forked from WithSecureLabs/android-keystore-audit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtracer-secretkeyfactory.js
128 lines (114 loc) · 3.86 KB
/
tracer-secretkeyfactory.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
PBEKeySpec tracer allows to see parameters (including password) from which PBKDF keys are generated
*/
Java.perform(function () {
//hookSecretKeyFactory_getInstance();
hookPBEKeySpec();
hookPBEKeySpec2();
hookPBEKeySpec3();
});
console.log("SecretKeyFactory hooks loaded!");
var cipherList = [];
var StringCls = null;
Java.perform(function () {
StringCls = Java.use('java.lang.String');
});
function hookSecretKeyFactory_getInstance()
{
var func = Java.use('javax.crypto.SecretKeyFactory')['getInstance'];
func.implementation = function(flag) {
console.log("[SecretKeyFactory.getInstance()]: flag: " + flag );
return this.getInstance(flag);
}
}
/*
.overload('[C')
.overload('[C', '[B', 'int')
.overload('[C', '[B', 'int', 'int')
*/
function hookPBEKeySpec()
{
var PBEKeySpec = Java.use('javax.crypto.spec.PBEKeySpec')['$init'].overload('[C');
PBEKeySpec.implementation = function(pass) {
console.log("[PBEKeySpec.PBEKeySpec()]: pass: " + charArrayToString(pass) );
return this.$init(pass);
}
}
function hookPBEKeySpec2()
{
var PBEKeySpec = Java.use('javax.crypto.spec.PBEKeySpec')['$init'].overload('[C', '[B', 'int');
PBEKeySpec.implementation = function(pass, salt, iter) {
console.log("[PBEKeySpec.PBEKeySpec2()]: pass: " + charArrayToString(pass) + " iter: "+iter);
dumpByteArray("salt",salt)
return this.$init(pass,salt,iter);
}
}
function hookPBEKeySpec3()
{
var PBEKeySpec = Java.use('javax.crypto.spec.PBEKeySpec')['$init'].overload('[C', '[B', 'int', 'int');
PBEKeySpec.implementation = function(pass, salt, iter, keyLength) {
console.log("[PBEKeySpec.PBEKeySpec3()]: pass: " + charArrayToString(pass) + " iter: "+iter + " keyLength: "+keyLength);
dumpByteArray("salt",salt)
return this.$init(pass,salt,iter,keyLength);
}
}
function charArrayToString(charArray)
{
if(charArray == null)
return '(null)';
else
return StringCls.$new(charArray);
}
function dumpByteArray(title,byteArr)
{
if(byteArr!=null)
{
try{
var buff = new ArrayBuffer(byteArr.length)
var dtv = new DataView(buff)
for(var i = 0; i < byteArr.length; i++){
dtv.setUint8(i,byteArr[i]); // Frida sucks sometimes and returns different byteArr.length between ArrayBuffer(byteArr.length) and for(..; i < byteArr.length;..). It occured even when Array.copyOf was done to work on copy.
}
console.log( title+":\n");
console.log(hexdumpJS(dtv.buffer,0,byteArr.length))
} catch(error){console.log("Exception has occured in hexdump")}
}
else
{
console.log("byteArr is null!");
}
}
function _fillUp (value, count, fillWith) {
var l = count - value.length;
var ret = "";
while (--l > -1)
ret += fillWith;
return ret + value;
}
function hexdumpJS (arrayBuffer, offset, length) {
var view = new DataView(arrayBuffer);
offset = offset || 0;
length = length || arrayBuffer.byteLength;
var out = _fillUp("Offset", 8, " ") + " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n";
var row = "";
for (var i = 0; i < length; i += 16) {
row += _fillUp(offset.toString(16).toUpperCase(), 8, "0") + " ";
var n = Math.min(16, length - offset);
var string = "";
for (var j = 0; j < 16; ++j) {
if (j < n) {
var value = view.getUint8(offset);
string += (value >= 32 && value < 128) ? String.fromCharCode(value) : ".";
row += _fillUp(value.toString(16).toUpperCase(), 2, "0") + " ";
offset++;
}
else {
row += " ";
string += " ";
}
}
row += " " + string + "\n";
}
out += row;
return out;
};