Skip to content

Commit

Permalink
update hook_art
Browse files Browse the repository at this point in the history
  • Loading branch information
lasting-yang committed Jun 2, 2021
1 parent 8502ad0 commit 1578bbe
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 47 deletions.
209 changes: 164 additions & 45 deletions hook_art.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@

const STD_STRING_SIZE = 3 * Process.pointerSize;
class StdString {
constructor() {
this.handle = Memory.alloc(STD_STRING_SIZE);
}

dispose() {
const [data, isTiny] = this._getData();
if (!isTiny) {
Java.api.$delete(data);
}
}

disposeToString() {
const result = this.toString();
this.dispose();
return result;
}

toString() {
const [data] = this._getData();
return data.readUtf8String();
}

_getData() {
const str = this.handle;
const isTiny = (str.readU8() & 1) === 0;
const data = isTiny ? str.add(1) : str.add(2 * Process.pointerSize).readPointer();
return [data, isTiny];
}
}

function prettyMethod(method_id, withSignature) {
const result = new StdString();
Java.api['art::ArtMethod::PrettyMethod'](result, method_id, withSignature ? 1 : 0);
return result.disposeToString();
}

/*
GetFieldID is at 0xe39b87c5 _ZN3art3JNI10GetFieldIDEP7_JNIEnvP7_jclassPKcS6_
GetMethodID is at 0xe39a1a19 _ZN3art3JNI11GetMethodIDEP7_JNIEnvP7_jclassPKcS6_
Expand All @@ -7,7 +46,7 @@ GetStaticFieldID is at 0xe39c9635 _ZN3art3JNI16GetStaticFieldIDEP7_JNIEnvP7_jcl
GetStaticMethodID is at 0xe39be0ed _ZN3art3JNI17GetStaticMethodIDEP7_JNIEnvP7_jclassPKcS6_
GetStringUTFChars is at 0xe39d06e5 _ZN3art3JNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh
FindClass is at 0xe399ae5d _ZN3art3JNI9FindClassEP7_JNIEnvPKc
*/
*/

function hook_libart() {
var symbols = Module.enumerateSymbolsSync("libart.so");
Expand All @@ -19,11 +58,14 @@ function hook_libart() {
var addrGetFieldID = null;
var addrGetStaticFieldID = null;
var addrRegisterNatives = null;
var so_name = "libxxx"; //TODO 这里写需要查看的so

for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
if (symbol.name.indexOf("art") >= 0 &&
symbol.name.indexOf("JNI") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0
symbol.name.indexOf("CheckJNI") < 0 &&
symbol.name.indexOf("_ZN3art3JNIILb0") >= 0
) {
if (symbol.name.indexOf("GetStringUTFChars") >= 0) {
addrGetStringUTFChars = symbol.address;
Expand All @@ -49,17 +91,74 @@ function hook_libart() {
} else if (symbol.name.indexOf("RegisterNatives") >= 0) {
addrRegisterNatives = symbol.address;
console.log("RegisterNatives is at ", symbol.address, symbol.name);
} else if (symbol.name.indexOf("CallStatic") >= 0) {
console.log("CallStatic is at ", symbol.address, symbol.name);
Interceptor.attach(symbol.address, {
onEnter: function (args) {
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var java_class = args[1];
var mid = args[2];
var class_name = Java.vm.tryGetEnv().getClassName(java_class);
if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
var method_name = prettyMethod(mid, 1);
console.log("<>CallStatic:", DebugSymbol.fromAddress(this.returnAddress), class_name, method_name);
}
}
},
onLeave: function (retval) { }
});
} else if (symbol.name.indexOf("CallNonvirtual") >= 0) {
console.log("CallNonvirtual is at ", symbol.address, symbol.name);
Interceptor.attach(symbol.address, {
onEnter: function (args) {
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var jobject = args[1];
var jclass = args[2];
var jmethodID = args[3];
var obj_class_name = Java.vm.tryGetEnv().getObjectClassName(jobject);
var class_name = Java.vm.tryGetEnv().getClassName(jclass);
if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
var method_name = prettyMethod(jmethodID, 1);
console.log("<>CallNonvirtual:", DebugSymbol.fromAddress(this.returnAddress), class_name, obj_class_name, method_name);
}
}
},
onLeave: function (retval) { }
});
} else if (symbol.name.indexOf("Call") >= 0 && symbol.name.indexOf("Method") >= 0) {
console.log("Call<>Method is at ", symbol.address, symbol.name);
Interceptor.attach(symbol.address, {
onEnter: function (args) {
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var java_class = args[1];
var mid = args[2];
var class_name = Java.vm.tryGetEnv().getObjectClassName(java_class);
if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
var method_name = prettyMethod(mid, 1);
console.log("<>Call<>Method:", DebugSymbol.fromAddress(this.returnAddress), class_name, method_name);
}
}
},
onLeave: function (retval) { }
});
}
}
}

if (addrGetStringUTFChars != null) {
Interceptor.attach(addrGetStringUTFChars, {
onEnter: function (args) {},
onEnter: function (args) {
},
onLeave: function (retval) {
if (retval != null) {
var bytes = Memory.readCString(retval);
console.log("[GetStringUTFChars] result:" + bytes);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var bytes = Memory.readCString(retval);
console.log("[GetStringUTFChars] result:" + bytes, DebugSymbol.fromAddress(this.returnAddress));
}
}
}
});
Expand All @@ -68,97 +167,117 @@ function hook_libart() {
Interceptor.attach(addrNewStringUTF, {
onEnter: function (args) {
if (args[1] != null) {
var string = Memory.readCString(args[1]);
console.log("[NewStringUTF] bytes:" + string);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var string = Memory.readCString(args[1]);
console.log("[NewStringUTF] bytes:" + string, DebugSymbol.fromAddress(this.returnAddress));
}

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}

if (addrFindClass != null) {
Interceptor.attach(addrFindClass, {
onEnter: function (args) {
if (args[1] != null) {
var name = Memory.readCString(args[1]);
console.log("[FindClass] name:" + name);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var name = Memory.readCString(args[1]);
console.log("[FindClass] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
}
}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}
if (addrGetMethodID != null) {
Interceptor.attach(addrGetMethodID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetMethodID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetMethodID] name:" + name);
var clazz = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(clazz);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetMethodID] class_name:" + class_name + " name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
} else {
console.log("[GetMethodID] class_name:" + class_name + " name:" + name, DebugSymbol.fromAddress(this.returnAddress));
}
}

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}
if (addrGetStaticMethodID != null) {
Interceptor.attach(addrGetStaticMethodID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetStaticMethodID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetStaticMethodID] name:" + name);
var clazz = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(clazz);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetStaticMethodID] class_name:" + class_name + " name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
} else {
console.log("[GetStaticMethodID] class_name:" + class_name + " name:" + name, DebugSymbol.fromAddress(this.returnAddress));
}
}

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}
if (addrGetFieldID != null) {
Interceptor.attach(addrGetFieldID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetFieldID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetFieldID] name:" + name);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetFieldID] name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
} else {
console.log("[GetFieldID] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
}
}

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}
if (addrGetStaticFieldID != null) {
Interceptor.attach(addrGetStaticFieldID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetStaticFieldID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetStaticFieldID] name:" + name);
var module = Process.findModuleByAddress(this.returnAddress);
if (module != null && module.name.indexOf(so_name) == 0) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetStaticFieldID] name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
} else {
console.log("[GetStaticFieldID] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
}
}

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}

if (addrRegisterNatives != null) {
Interceptor.attach(addrRegisterNatives, {
onEnter: function (args) {
console.log("[RegisterNatives] method_count:", args[3]);
console.log("[RegisterNatives] method_count:", args[3], DebugSymbol.fromAddress(this.returnAddress));
var env = args[0];
var java_class = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(java_class);
Expand All @@ -178,7 +297,7 @@ function hook_libart() {

}
},
onLeave: function (retval) {}
onLeave: function (retval) { }
});
}
}
Expand Down
6 changes: 4 additions & 2 deletions hook_artmethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function prettyMethod(method_id, withSignature) {
return result.disposeToString();
}

function hook_dlopen(module_name , fun ) {
function hook_dlopen(module_name, fun) {
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");

if (android_dlopen_ext) {
Expand Down Expand Up @@ -108,7 +108,9 @@ function hook_native() {
onEnter: function (args) {
var method_name = prettyMethod(args[0], 0);
if (!(method_name.indexOf("java.") == 0 || method_name.indexOf("android.") == 0)) {
console.log("ArtMethod Invoke:", method_name);
console.log("ArtMethod Invoke:" + method_name + ' called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n') + '\n');
}
}
});
Expand Down

0 comments on commit 1578bbe

Please sign in to comment.