var symbols = Module.enumerateSymbolsSync("libart.so");
var addrNewStringUTF = null;
for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
if (symbol.name.indexOf("NewStringUTF") >= 0 && symbol.name.indexOf("CheckJNI") < 0) {
addrNewStringUTF = symbol.address;
console.log("NewStringUTF is at ", symbol.address, symbol.name);
}
}
if (addrNewStringUTF != null) {
Interceptor.attach(addrNewStringUTF, {
onEnter: function (args) {
var c_string = args[1];
var dataString = c_string.readCString();
if (dataString.indexOf("XYAAAAAQAAAAEAAAB") != -1) {
console.log(dataString);
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
}
});
}
// frida -UF -l 1.so_utfstring.js -o token.txt
2、hook 所有的interceptor
public class XhsHttpInterceptor implements Interceptor {
//在so中创建请求头的值,并添加到request对象中,在继续执行下一个拦截器
public native Response intercept(Interceptor.Chain chain, long j2) throws IOException;
}
拦截器中做的事情:
public native Response intercept(Interceptor.Chain chain, long j2)
var symbols = Module.enumerateSymbolsSync("libart.so");
var addrRegisterNatives = null;
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("RegisterNatives") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0) {
addrRegisterNatives = symbol.address;
// console.log("RegisterNatives is at ", symbol.address, symbol.name);
}
}
// console.log("addrRegisterNatives=", addrRegisterNatives);
if (addrRegisterNatives != null) {
Interceptor.attach(addrRegisterNatives, {
onEnter: function (args) {
var env = args[0];
var java_class = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(java_class);
// 只有类名为com.xxx.nativelibrary.LibBili,才打印输出
console.log(class_name);
var taget_class = "com.xxx.shield.http.XhsHttpInterceptor";
if (class_name === taget_class) {
// console.log("\n[RegisterNatives] method_count:", args[3]);
var methods_ptr = ptr(args[2]);
var method_count = parseInt(args[3]);
for (var i = 0; i < method_count; i++) {
// Java中函数名字的
var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
// 参数和返回值类型
var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
// C中的函数指针
var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
var name = Memory.readCString(name_ptr); // 读取java中函数名
var sig = Memory.readCString(sig_ptr); // 参数和返回值类型
var find_module = Process.findModuleByAddress(fnPtr_ptr); // 根据C中函数指针获取模块
var offset = ptr(fnPtr_ptr).sub(find_module.base) // fnPtr_ptr - 模块基地址
// console.log("[RegisterNatives] java_class:", class_name);
console.log("name:", name, "sig:", sig, "module_name:", find_module.name, "offset:", offset);
//console.log("name:", name, "module_name:", find_module.name, "offset:", offset);
}
}
}
});
function find_RegisterNatives(params) {
var symbols = Module.enumerateSymbolsSync("libart.so");
var addrRegisterNatives = null;
for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
//_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
if (symbol.name.indexOf("art") >= 0 &&
symbol.name.indexOf("JNI") >= 0 &&
symbol.name.indexOf("RegisterNatives") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0) {
addrRegisterNatives = symbol.address;
console.log("RegisterNatives is at ", symbol.address, symbol.name);
hook_RegisterNatives(addrRegisterNatives)
}
}
}
function hook_RegisterNatives(addrRegisterNatives) {
if (addrRegisterNatives != null) {
Interceptor.attach(addrRegisterNatives, {
onEnter: function (args) {
console.log("[RegisterNatives] method_count:", args[3]);
var java_class = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(java_class);
//console.log(class_name);
var methods_ptr = ptr(args[2]);
var method_count = parseInt(args[3]);
for (var i = 0; i < method_count; i++) {
var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
var name = Memory.readCString(name_ptr);
var sig = Memory.readCString(sig_ptr);
var symbol = DebugSymbol.fromAddress(fnPtr_ptr)
//console.log("[RegisterNatives] java_class:", class_name)
var target_ClassName = "com.xxx.shield.http.XhsHttpInterceptor";
if(class_name === target_ClassName){
console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, " fnOffset:", symbol, " callee:", DebugSymbol.fromAddress(this.returnAddress));
//console.log("name:", name, "sig:", sig, "module_name:", find_module.name, "offset:", offset);
}
}
}
});
}
java.lang.UnsupportedOperationException: java/nio/charset/Charset->defaultCharset()Ljava/nio/charset/Charset;
at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticObjectMethodV(AbstractJni.java:503)
public long initialize (){
Number number = module.callFunction(emulator,
0x937B1,
vm.getJNIEnv(),
vm.addLocalObject(vm.resolveClass("com/xingin/shield/http/XhsHttpInterceptor")), //jclass
vm.addLocalObject(new StringObject(vm,"main"))
);
return number.longValue();
}
hook时机: 在加载so文件后进行hook
function do_hook() {
setTimeout(function () {
Java.perform(function () {
var XhsHttpInterceptor = Java.use('com.xxx.shield.http.XhsHttpInterceptor');
XhsHttpInterceptor.initialize.implementation = function (str) {
console.log("str=", str);
return this.initialize(str);
};
})
}, 40);
}
function load_so_and_hook() {
var dlopen = Module.findExportByName(null, "dlopen");
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(dlopen, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
// console.log("[dlopen:]", path);
this.path = path;
}, onLeave: function (retval) {
if (this.path.indexOf("libshield.so") !== -1) {
console.log("[dlopen:]", this.path);
do_hook();
}
}
});
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
this.path = path;
}, onLeave: function (retval) {
if (this.path.indexOf("libshield.so") !== -1) {
console.log("\nandroid_dlopen_ext加载:", this.path);
do_hook();
}
}
});