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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
| function find_RegisterNatives(params) { let symbols = Module.enumerateSymbolsSync("libart.so"); let addrRegisterNatives = null; for (let i = 0; i < symbols.length; i++) { let 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]); let java_class = args[1]; let class_name = Java.vm.tryGetEnv().getClassName(java_class); //console.log(class_name);
let methods_ptr = ptr(args[2]);
let method_count = parseInt(args[3]); for (let i = 0; i < method_count; i++) { let name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3)); let sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize)); let fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2)); console.log(name_ptr,sig_ptr,fnPtr_ptr); console.log(hexdump(sig_ptr, {length: 100, header: true, raw: true})); let name = Memory.readCString(name_ptr); let sig = Memory.readCString(sig_ptr); let symbol = DebugSymbol.fromAddress(fnPtr_ptr) if (name === "getPvKey" && sig === "()Ljava/lang/String;") { const newSig = "(Ljava/lang/String;)Ljava/lang/String;"; const newSigBytes = Memory.alloc(newSig.length); // 为新签名分配内存 Memory.writeUtf8String(newSigBytes, newSig); // 写入新的签名到新内存 Memory.protect(sig_ptr, newSig.length, 'rw'); // 直接覆盖原来 sig_ptr 地址处的签名 Memory.writeByteArray(sig_ptr, new Array(newSig.length+1).fill(0).map((_, i) => newSig.charCodeAt(i)));
const newname = "genPvKey"; const newnameBytes = Memory.alloc(newname.length); // 为新签名分配内存 Memory.writeUtf8String(newnameBytes, newname); // 写入新的签名到新内存 Memory.protect(name_ptr, newname.length, 'rw'); // 直接覆盖原来 sig_ptr 地址处的签名 Memory.writeByteArray(name_ptr, new Array(newname.length+1).fill(0).map((_, i) => newname.charCodeAt(i))); console.log(hexdump(sig_ptr, {length: 100, header: true, raw: true})); console.log(`✅ Replaced signature of getPvKey with: ${newSig}`); // sig = Memory.readCString(newSigPtr); } console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, " fnOffset:", symbol, " callee:", DebugSymbol.fromAddress(this.returnAddress)); } for (let i = 0; i < method_count; i++) { let name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3)); let sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize)); let fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
let name = Memory.readCString(name_ptr); let sig = Memory.readCString(sig_ptr); let symbol = DebugSymbol.fromAddress(fnPtr_ptr) console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, " fnOffset:", symbol, " callee:", DebugSymbol.fromAddress(this.returnAddress)); } } }); } } function hook(){ Java.perform(function(){ let MainActivity = Java.use("com.example.mobile03.MainActivity"); MainActivity["showAd"].implementation = function () { console.log(`MainActivity.showAd is called`); // this["showAd"](); };
var File = Java.use("java.io.File"); File.$init.overload('java.io.File', 'java.lang.String').implementation = function (dir, name) { // console.log(name); if(name=="rabbit"){ name="swan.dex"; console.log(name); } // 继续执行原方法 return this.$init(dir, name); }; var AssetManager = Java.use("android.content.res.AssetManager"); AssetManager.open.overload('java.lang.String').implementation = function (filename) { // 获取调用栈,检查是否来自 cpdex() console.log("open",filename); if(filename=="rabbit"){ filename="swan"; } // 继续执行原方法 return this.open(filename); };
Java.choose("com.example.mobile03.MainActivity",{ onMatch:function(instance){ instance.cpdex(); },onComplete:function(){
} }); var currentApplication = Java.use('android.app.ActivityThread').currentApplication(); var context = currentApplication.getApplicationContext();
var DexClassLoader = Java.use('dalvik.system.DexClassLoader'); var File = Java.use('java.io.File'); var dexPath = context.getDir("dex", 0).getAbsolutePath() + "/swan.dex"; console.log(context.getDir("dex", 0).getAbsolutePath()); var optimizedDir = context.getCodeCacheDir().getAbsolutePath(); var currentApplication = Java.use('android.app.ActivityThread').currentApplication(); var packageCodePath = currentApplication.getPackageCodePath().toString(); var libPath = packageCodePath + "!/lib/arm64-v8a/"; try{ var classLoader = DexClassLoader.$new(dexPath, optimizedDir, libPath, context.getClassLoader());
} catch(e){ }
var targetClass = classLoader.loadClass("com.example.mobile03.swan"); var clazz = Java.cast(targetClass, Java.use("java.lang.Class"));
var method = clazz.getDeclaredMethod("b", Java.array("java.lang.Class", []));
var result = method.invoke(null, Java.array("java.lang.Object", []));
console.log("✅ com.example.mobile03.swan.a.b() returned: " + result);
var targetClass = classLoader.loadClass("com.example.mobile03.swan"); var clazz = Java.cast(targetClass, Java.use("java.lang.Class"));
var paramTypes = Java.array("java.lang.Class", [Java.use("java.lang.String").class]); var method = clazz.getDeclaredMethod("genPvKey", paramTypes); method.setAccessible(true);
var args = Java.array("java.lang.Object", [Java.use("java.lang.String").$new("test_input")]); var result = method.invoke(null, args);
console.log("✅ genPvKey('test_input') returned: " + result); }) }
function main(){ find_RegisterNatives(); hook(); }
setImmediate(main,500);
|