├── .idea ├── Frida_Android_Hook.iml ├── misc.xml └── modules.xml ├── README.md ├── book └── Frida Zhong Wen Wen Dang - Wei Zhi.epub ├── frida_ssl_pinning_bypass.pdf ├── hook.js ├── hook_android_log.js ├── hook_java_class_loader.js ├── hook_java_find_class.js ├── hook_java_find_class_N.js ├── hook_java_loadLibrary.js ├── hook_jni.js ├── hook_libmono.js ├── hook_mini.js ├── hook_native.js ├── hook_native_code.py ├── native.js └── shell ├── frida-server-11.0.12-android-arm └── frida-server.bat /.idea/Frida_Android_Hook.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Frida_Android_Hook 2 | 3 | --book
4 | ------Frida中文翻译文档
5 | --shell
6 | ------Frida push脚本
7 | ------Frida arm32
8 | hook.js hook native实例
9 | hook_native_code py脚本
10 | -------------------------------------------------------------------------------- /book/Frida Zhong Wen Wen Dang - Wei Zhi.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sepyeight/Frida_Android_Hook/5352917fea092cbe56c22d34249f1778c0cab42d/book/Frida Zhong Wen Wen Dang - Wei Zhi.epub -------------------------------------------------------------------------------- /frida_ssl_pinning_bypass.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sepyeight/Frida_Android_Hook/5352917fea092cbe56c22d34249f1778c0cab42d/frida_ssl_pinning_bypass.pdf -------------------------------------------------------------------------------- /hook.js: -------------------------------------------------------------------------------- 1 | /** 2 | * hook write 3 | * search dex magic word 4 | * dump dex 5 | */ 6 | function hook_write(){ 7 | var read_buf_len = 7; 8 | var file_name_partial = "/sdcard/hook_write_dex_"; 9 | var dex_file_magic = "dex\n035"; 10 | Interceptor.attach(Module.findExportByName("libc.so" , "write"), { 11 | //write(FILE *fd, buf, len(buf)) 12 | onEnter: function(args) { 13 | send("write("+args[0]+", "+Memory.readCString(args[1], read_buf_len)+", "+args[2]+")"); 14 | if(Memory.readCString(args[1], read_buf_len) == dex_file_magic){ 15 | var filename = get_dex_file_name(file_name_partial); 16 | var outFile = new File(filename, "w"); 17 | var buf = Memory.readByteArray(args[1], parseInt(args[2])); 18 | outFile.write(buf); 19 | outFile.flush(); 20 | outFile.close(); 21 | send("write finished!!!"); 22 | }}, 23 | onLeave:function(retval){ 24 | } 25 | }); 26 | } 27 | 28 | /** 29 | * hook memcmp 30 | * search dex magic word 31 | * dump dex 32 | */ 33 | function hook_memcmp() { 34 | var read_buf_len = 7; 35 | var file_name_partial = "/sdcard/hook_memcmp_dex_"; 36 | var dex_file_magic = "dex\n035"; 37 | Interceptor.attach(Module.findExportByName("libc.so" , "memcmp"), { 38 | onEnter: function(args) { 39 | send("show args1 is: "+Memory.readCString(args[0], parseInt(args[2]))+" and args2 is: "+Memory.readCString(args[1], parseInt(args[2]))+" and length is: "+args[2]); 40 | if(Memory.readCString(args[0],read_buf_len) == dex_file_magic){ 41 | var filename = get_dex_file_name(file_name_partial); 42 | var outFile = new File(filename, "w"); 43 | var buf = Memory.readByteArray(args[0], parseInt(args[2])); 44 | outFile.write(buf); 45 | outFile.flush(); 46 | outFile.close(); 47 | send("memcmp hooked "); 48 | } 49 | if(Memory.readCString(args[1],read_buf_len) == dex_file_magic){ 50 | var filename = get_dex_file_name(file_name_partial); 51 | var outFile = new File(filename, "w"); 52 | var buf = Memory.readByteArray(args[1], parseInt(args[2])); 53 | outFile.write(buf); 54 | outFile.flush(); 55 | outFile.close(); 56 | send("memcmp hooked "); 57 | } 58 | }, 59 | onLeave:function(retval){ 60 | } 61 | }); 62 | } 63 | 64 | /** 65 | * 360 66 | */ 67 | function hook_memcpy() { 68 | var read_buf_len = 7; 69 | var file_name_partial = "/sdcard/hook_memcpy_dex_"; 70 | var dex_file_magic = "dex\n035"; 71 | //void *memcpy(void *dest, const void *src, size_t n); 72 | Interceptor.attach(Module.findExportByName("libc.so" , "memcpy"), { 73 | onEnter: function (args) { 74 | this.dest = args[0]; 75 | this.src = args[1]; 76 | this.size = args[2].toInt32(); 77 | }, 78 | onLeave: function (retval) { 79 | if(Memory.readCString(this.dest, read_buf_len) == dex_file_magic){ 80 | send("hook memcpy("+Memory.readCString(this.dest, read_buf_len)+", "+Memory.readCString(this.src, read_buf_len)+", "+this.size+")"); 81 | var filename = get_dex_file_name(file_name_partial); 82 | var buf = Memory.readByteArray(this.dest, this.size); 83 | var outFile = new File(filename, "wb+"); 84 | outFile.write(buf); 85 | outFile.flush(); 86 | outFile.close(); 87 | send("hook memcpy finished!!!"); 88 | } 89 | } 90 | }); 91 | } 92 | 93 | function hook_open() { 94 | Interceptor.attach(Module.findExportByName("libc.so" , "open"), { 95 | onEnter: function (args) { 96 | send("hook open("+Memory.readCString(args[0])+", "+args[1].toInt32()+")"); 97 | }, 98 | onLeave: function (retval) { 99 | 100 | } 101 | }); 102 | } 103 | 104 | function hook_fopen() { 105 | Interceptor.attach(Module.findExportByName("libc.so" , "fopen"), { 106 | onEnter: function (args) { 107 | send("hook fopen("+Memory.readCString(args[0])+", "+Memory.readCString(args[1])+")"); 108 | }, 109 | onLeave: function (retval) { 110 | 111 | } 112 | }); 113 | } 114 | 115 | function hook_mmap() { 116 | Interceptor.attach(Module.findExportByName("libc.so" , "mmap"), { 117 | onEnter: function (args) { 118 | send("hook mmap("+args[0]+", "+args[1]+", "+args[2]+", "+args[3]+", "+args[4]+", "+args[5]+")"); 119 | }, 120 | onLeave: function (retval) { 121 | send("mmap result is: "+Memory.readCString(retval, 5)); 122 | } 123 | }); 124 | } 125 | 126 | function hook_munmap() { 127 | Interceptor.attach(Module.findExportByName("libc.so" , "mmap"), { 128 | onEnter: function (args) { 129 | send("hook munmap("+args[0]+", "+args[1]+")"); 130 | }, 131 | onLeave: function (retval) { 132 | } 133 | }); 134 | } 135 | 136 | function hook_snprintf() { 137 | Interceptor.attach(Module.findExportByName("libc.so" , "snprintf"), { 138 | onEnter: function (args) { 139 | this.str = args[0]; 140 | 141 | }, 142 | onLeave: function (retval) { 143 | send("hook snprintf str is: "+Memory.readCString(this.str)); 144 | } 145 | }); 146 | } 147 | 148 | 149 | function hook_openMemory() { 150 | var read_buf_len = 7; 151 | var file_name_partial = "/data/data/com.me.hookme/hook_openMemory_dex_"; 152 | var dex_file_magic = "dex\n035"; 153 | // const DexFile* DexFile::OpenMemory(const byte* base, size_t size, const std::string& location, uint32_t location_checksum, MemMap* mem_map, std::string* error_msg) 154 | Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapES2_PS9_"), { 155 | onEnter: function(args) { 156 | if(Memory.readCString(args[0], read_buf_len) == dex_file_magic){ 157 | var filename = get_dex_file_name(file_name_partial); 158 | var outFile = new File(filename, "w"); 159 | var buf = Memory.readByteArray(args[0], args[1].toInt32()); 160 | outFile.write(buf); 161 | outFile.flush(); 162 | outFile.close(); 163 | send("hook openMemory finished!!!"); 164 | } 165 | }, 166 | onLeave: function(retval){ 167 | } 168 | }); 169 | } 170 | 171 | function hook_defineClass() { 172 | //_ZN3art11ClassLinker11DefineClassEPKcNS_6HandleINS_6mirror11ClassLoaderEEERKNS_7DexFileERKNS7_8ClassDefE 173 | //mirror::Class* ClassLinker::DefineClass(const char* descriptor, Handle class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) 174 | //DefineClass(descriptor.c_str(), class_loader, *dex_file,*dex_class_def); 175 | Interceptor.attach(Module.findExportByName("libart.so" , "_ZN3art11ClassLinker11DefineClassEPKcNS_6HandleINS_6mirror11ClassLoaderEEERKNS_7DexFileERKNS7_8ClassDefE"), { 176 | onEnter: function (args) { 177 | send("args[2] is: "+Memory.readCString(args[2], 7)); 178 | }, 179 | onLeave: function (retval) { 180 | } 181 | }); 182 | } 183 | 184 | function hook_dlopen() { 185 | Interceptor.attach(Module.findExportByName("libc.so" , "dlopen"), { 186 | onEnter: function (args) { 187 | send("hook dlopen("+Memory.readCString(args[0]) +", "+ args[1]+")"); 188 | }, 189 | onLeave: function (retval) { 190 | send("hook dlopen result: "+retval); 191 | } 192 | }); 193 | } 194 | 195 | function hook_dlsym() { 196 | Interceptor.attach(Module.findExportByName("libc.so" , "dlsym"), { 197 | onEnter: function (args) { 198 | send("hook dlsym("+args[0] +", "+ Memory.readCString(args[1])+")"); 199 | }, 200 | onLeave: function (retval){ 201 | send("hook dlsym result: "+retval); 202 | } 203 | }); 204 | } 205 | 206 | function hook_registerNativeMethods() { 207 | 208 | Interceptor.attach(Module.findExportByName("libart.so" , "_ZN3art21RegisterNativeMethodsEP7_JNIEnvPKcPK15JNINativeMethodi"), { 209 | onEnter: function (args){ 210 | 211 | }, 212 | onLeave: function (retval){ 213 | 214 | } 215 | }); 216 | } 217 | 218 | function get_dex_file_name(file_name_partial) { 219 | var date = new Date(); 220 | var time = date.getTime(); 221 | var file_name = file_name_partial + time + ".dex"; 222 | return file_name; 223 | } 224 | 225 | 226 | setTimeout(hook_openMemory(),0); -------------------------------------------------------------------------------- /hook_android_log.js: -------------------------------------------------------------------------------- 1 | function hookLog() { 2 | if (Java.available) { 3 | Java.perform(function () { 4 | var Log = Java.use("android.util.Log"); 5 | if (Log != undefined) { 6 | Log.e.overload("java.lang.String", "java.lang.String").implementation = function (tag, msg) { 7 | console.log(Log + ".e tag is " + tag + " msg is " + msg); 8 | return this.e("Frida", msg); 9 | } 10 | } else { 11 | console.log("class " + Log + "not found!"); 12 | } 13 | }) 14 | } 15 | 16 | var logPrintPoint = undefined; 17 | var exports = Module.enumerateExportsSync("liblog.so"); 18 | for (var i = 0; i < exports.length; i++) { 19 | if (exports[i].name == "__android_log_print") { 20 | logPrintPoint = exports[i].address; 21 | break; 22 | } 23 | } 24 | 25 | Interceptor.attach(logPrintPoint, { 26 | onEnter: function (args) { 27 | // console.log("catch..."); 28 | var buf = Memory.allocUtf8String("Frida"); 29 | var tag = ptr("6"); 30 | this.buf = buf; 31 | args[0] = tag; 32 | args[1] = this.buf; 33 | // console.log("replace finish!!!"); 34 | } 35 | }); 36 | } 37 | 38 | 39 | setTimeout(hookLog, 0); -------------------------------------------------------------------------------- /hook_java_class_loader.js: -------------------------------------------------------------------------------- 1 | //try to load class 2 | function hook_class_loader_load_class(java_class_name) { 3 | var target_class = null; 4 | var base_loader = Java.use("dalvik.system.BaseDexClassLoader"); 5 | var lang_class = Java.use("java.lang.Class"); 6 | if (base_loader != null) { 7 | console.log("[V] base_loader is loaded!"); 8 | base_loader.$init.overload("java.lang.String", "java.io.File", "java.lang.String", "java.lang.ClassLoader").implementation = function (str1, file, str2, loader) { 9 | var ret = this.$init(str1, file, str2, loader); 10 | var clazz_obj = Java.cast(this.getClass(), lang_class); 11 | console.log("[V] class loader name is " + clazz_obj.getName()); 12 | return ret; 13 | }; 14 | base_loader.loadClass.overload("java.lang.String", "boolean").implementation = function (name) { 15 | var clazz_obj = Java.cast(this.getClass(), lang_class); 16 | console.log("[V] class loader " + clazz_obj.getName() + " load class name " + name); 17 | var result = this.loadClass(name, false); 18 | return result; 19 | }; 20 | base_loader.findClass.implementation = function (name) { 21 | var result = this.findClass(name); 22 | var clazz_obj = Java.cast(this.getClass(), lang_class); 23 | console.log("[V] class loader " + clazz_obj.getName() + " find class name " + name); 24 | 25 | if (target_class == null) { 26 | try { 27 | console.log("[V] try to load class " + java_class_name); 28 | target_class = this.loadClass(java_class_name); 29 | console.log("[V] class loader " + clazz_obj.getName() + " load class name " + java_class_name + " successful!"); 30 | } catch (error) { 31 | console.log("[E] load class " + java_class_name + " failed"); 32 | } 33 | } 34 | return result; 35 | } 36 | } 37 | 38 | return target_class; 39 | } 40 | 41 | function begin() { 42 | if (Java.available) { 43 | Java.perform(function () { 44 | console.log("[V] begin...."); 45 | var java_class_name = "com.zebra.carcloud.openapi.simplesdk.b"; 46 | hook_class_loader_load_class(java_class_name); 47 | console.log("[V] finish...."); 48 | }); 49 | } 50 | } 51 | 52 | setTimeout(begin(), 0); -------------------------------------------------------------------------------- /hook_java_find_class.js: -------------------------------------------------------------------------------- 1 | function js_find_real_loader(java_class_name, android_class_loader_name, android_class_loader_list) { 2 | console.log("[V] try to load "+ android_class_loader_name); 3 | if (Java.available) { 4 | Java.perform(function () { 5 | Java.choose(android_class_loader_name, { 6 | onMatch: function (instance) { 7 | console.log("[V] " + instance); 8 | android_class_loader_list.push(instance); 9 | }, 10 | onComplete: function () { 11 | console.log("[V] load class loader finished!"); 12 | var real_loader = null; 13 | for (var i in android_class_loader_list) { 14 | try { 15 | var java_clazz = android_class_loader_list[i].findClass(java_class_name); 16 | console.log("[V] find class " + java_class_name + " in " + android_class_loader_name + "[" + i + "]"); 17 | real_loader = android_class_loader_list[i]; 18 | } catch (error) { 19 | console.log("[E] can't find class " + java_class_name + " in " + android_class_loader_name + "[" + i + "]"); 20 | } 21 | } 22 | console.log("[V] find class loader finished!"); 23 | return real_loader; 24 | } 25 | }) 26 | }); 27 | } 28 | } 29 | 30 | function find_class() { 31 | var java_class_name = "com.zebra.carcloud.openapi.simplesdk.f"; 32 | var android_class_loader_name_list = ["dalvik.system.DexClassLoader", "dalvik.system.PathClassLoader"]; 33 | var real_loader = null; 34 | for (var i = android_class_loader_name_list.length - 1; i >= 0; i--) { 35 | var android_class_loader_list = []; 36 | real_loader = js_find_real_loader(java_class_name, android_class_loader_name_list[i], android_class_loader_list); 37 | } 38 | if (real_loader != null) { 39 | Java.classFactory.loader = real_loader; 40 | Java.use(java_class_name); 41 | }else{ 42 | console.log("[E] class loader is null, load class failed!"); 43 | } 44 | } 45 | 46 | setTimeout(find_class, 0); -------------------------------------------------------------------------------- /hook_java_find_class_N.js: -------------------------------------------------------------------------------- 1 | /** 2 | * up to android7.0 3 | * enumerateClassLoader and try to load class by name. 4 | */ 5 | function java_get_loader(class_name) { 6 | var loader_list = Java.enumerateClassLoadersSync(); 7 | if(loader_list == null){ 8 | console.log("[E] loader list is null"); 9 | return null; 10 | } 11 | console.log("[V] loader list length is "+ loader_list.length); 12 | for (var i=0; i" + module.name + " module address->" + module.base); 34 | show_mono_info(module); 35 | 36 | var addr = module.base.add(0x196C4C); 37 | print_addr_info(addr); 38 | console.log("mono_image_open_from_data_with_name address is " + addr); 39 | 40 | Interceptor.attach(addr, { 41 | onEnter: function (args) { 42 | console.log("onEnter..."); 43 | this.name = Memory.readCString(args[5]); 44 | this.data = args[0]; 45 | this.size = args[1].toInt32(); 46 | console.log("mono_image_open_from_data_with_name info: name->" + this.name + ", size->" + this.size); 47 | }, 48 | onLeave: function (revtal) { 49 | console.log("onLeave..."); 50 | var data = Memory.readByteArray(revtal, this.size); 51 | send(JSON.stringify({ 52 | file_name: this.name.replace(/\//g, "."), 53 | file_size: this.size, 54 | }, null, 2), data); 55 | } 56 | }); 57 | } 58 | 59 | function print_addr_info(address) { 60 | console.log(hexdump(address, { 61 | offset: 0, 62 | lengyh: 16, 63 | header: true, 64 | ansi: true 65 | })); 66 | } 67 | 68 | setTimeout(hook); -------------------------------------------------------------------------------- /hook_mini.js: -------------------------------------------------------------------------------- 1 | function hook() { 2 | var symbols = Module.enumerateSymbolsSync("libart.so"); 3 | 4 | var addrFindClass = undefined; 5 | var addrGetMethodID = undefined; 6 | var addrGetStaticMethodID = undefined; 7 | var addrGetStringUTFChars = undefined; 8 | var addrNewStringUTF = undefined; 9 | var addrGetObjectClass = undefined; 10 | var addrGetObjectField = undefined; 11 | var addrGetArrayLength = undefined; 12 | var addrGetByteArrayElements = undefined; 13 | var addrGetSuperclass = undefined; 14 | var addrGetStaticIntField = undefined; 15 | var addrGetStaticFieldID = undefined; 16 | var addrReleaseStringUTFChars = undefined; 17 | var addrDeleteLocalRef = undefined; 18 | 19 | symbols.forEach(function (sym) { 20 | if (sym.name == "_ZN3art3JNI9FindClassEP7_JNIEnvPKc") { 21 | addrFindClass = sym.address; 22 | console.log("[V]FindClass address " + addrFindClass); 23 | } else if (sym.name == "_ZN3art3JNI11GetMethodIDEP7_JNIEnvP7_jclassPKcS6_") { 24 | addrGetMethodID = sym.address; 25 | } else if (sym.name == "_ZN3art3JNI17GetStaticMethodIDEP7_JNIEnvP7_jclassPKcS6_") { 26 | addrGetStaticMethodID = sym.address; 27 | } else if (sym.name == "_ZN3art3JNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh") { 28 | addrGetStringUTFChars = sym.address; 29 | } else if (sym.name == "_ZN3art3JNI12NewStringUTFEP7_JNIEnvPKc") { 30 | addrNewStringUTF = sym.address; 31 | } else if (sym.name == "_ZN3art3JNI14GetObjectClassEP7_JNIEnvP8_jobject") { 32 | addrGetObjectClass = sym.address; 33 | } else if (sym.name == "_ZN3art3JNI14GetObjectFieldEP7_JNIEnvP8_jobjectP9_jfieldID") { 34 | addrGetObjectField = sym.address; 35 | } else if (sym.name == "_ZN3art3JNI14GetArrayLengthEP7_JNIEnvP7_jarray") { 36 | addrGetArrayLength = sym.address; 37 | } else if (sym.name == "_ZN3art3JNI20GetByteArrayElementsEP7_JNIEnvP11_jbyteArrayPh") { 38 | addrGetByteArrayElements = sym.address; 39 | } else if (sym.name == "_ZN3art3JNI13GetSuperclassEP7_JNIEnvP7_jclass") { 40 | addrGetSuperclass = sym.address; 41 | } else if (sym.name == "_ZN3art3JNI17GetStaticIntFieldEP7_JNIEnvP7_jclassP9_jfieldID") { 42 | addrGetStaticIntField = sym.address; 43 | } else if (sym.name == "_ZN3art3JNI16GetStaticFieldIDEP7_JNIEnvP7_jclassPKcS6_") { 44 | addrGetStaticFieldID = sym.address; 45 | } else if (sym.name == "_ZN3art3JNI21ReleaseStringUTFCharsEP7_JNIEnvP8_jstringPKc") { 46 | addrReleaseStringUTFChars = sym.address; 47 | } else if (sym.name == "_ZN3art3JNI14DeleteLocalRefEP7_JNIEnvP8_jobject") { 48 | addrDeleteLocalRef = sym.address; 49 | } 50 | }); 51 | 52 | if (addrFindClass != undefined) { 53 | Interceptor.attach(addrFindClass, { 54 | onEnter: function (args) { 55 | console.log("[V]FindClass->" + Memory.readCString(args[1])); 56 | }, 57 | onLeave: function (retval) { 58 | } 59 | }); 60 | } 61 | 62 | if (addrGetMethodID != undefined) { 63 | Interceptor.attach(addrGetMethodID, { 64 | onEnter: function (args) { 65 | var env = Java.vm.getEnv(); 66 | // var cls = env.findClass("java/lang/Class"); 67 | // var mid = env.getMethodId(cls, "getName", "()Ljava/lang/String;"); 68 | console.log("[V]GetMethodID->" + env.getClassName(args[1])); 69 | console.log("\t[I]GetMethodID::method->" + Memory.readCString(args[2])); 70 | console.log("\t[I]GetMethodID::sig->" + Memory.readCString(args[3])); 71 | }, 72 | onLeave: function (retval) { 73 | } 74 | }); 75 | } 76 | 77 | if (addrGetStaticMethodID != undefined) { 78 | Interceptor.attach(addrGetStaticMethodID, { 79 | onEnter: function (args) { 80 | var env = Java.vm.getEnv(); 81 | console.log("[V]GetStaticMethodID->" + env.getClassName(args[1])); 82 | console.log("\t[I]GetStaticMethodID::method->" + Memory.readCString(args[2])); 83 | console.log("\t[I]GetStaticMethodID::sig->" + Memory.readCString(args[3])); 84 | }, 85 | onLeave: function (retval) { 86 | } 87 | }); 88 | } 89 | 90 | if (addrGetStringUTFChars != undefined) { 91 | Interceptor.attach(addrGetStringUTFChars, { 92 | onEnter: function (args) { 93 | var env = Java.vm.getEnv(); 94 | console.log("[V]GetStringUTFChars->" + env.stringFromJni(args[1])); 95 | }, 96 | onLeave: function (retval) { 97 | } 98 | }); 99 | } 100 | 101 | if (addrNewStringUTF != undefined) { 102 | Interceptor.attach(addrNewStringUTF, { 103 | onEnter: function (args) { 104 | if(Memory.readUtf8String(args[1]) != ""){ 105 | console.log("[V]NewStringUTF->" + Memory.readUtf8String(args[1])); 106 | } 107 | }, 108 | onLeave: function (retval) { 109 | } 110 | }); 111 | } 112 | 113 | if (addrGetObjectClass != undefined) { 114 | Interceptor.attach(addrGetObjectClass, { 115 | onEnter: function (args) { 116 | var env = Java.vm.getEnv(); 117 | console.log("[V]GetObjectClass->" + env.getObjectClassName(args[1])); 118 | }, 119 | onLeave: function (retval) { 120 | } 121 | }); 122 | } 123 | 124 | 125 | if (addrGetObjectField != undefined) { 126 | Interceptor.attach(addrGetObjectField, { 127 | onEnter: function (args) { 128 | var env = Java.vm.getEnv(); 129 | var cls = env.getObjectClass(args[1]); 130 | console.log("[V]GetObjectField->" + env.getClassName(cls)); 131 | }, 132 | onLeave: function (retval) { 133 | var env = Java.vm.getEnv(); 134 | console.log("\t[I]GetObjectField::fid->" + env.getObjectClassName(retval)); 135 | } 136 | }); 137 | } 138 | 139 | 140 | if(addrGetArrayLength != undefined){ 141 | Interceptor.attach(addrGetArrayLength, { 142 | onEnter: function (args) {}, 143 | onLeave: function (retval) { 144 | var env = Java.vm.getEnv(); 145 | console.log("[V]GetArrayLength::size->" + retval.toInt32()); 146 | } 147 | }); 148 | } 149 | 150 | // if(addrGetByteArrayElements != undefined){ 151 | // Interceptor.attach(addrGetByteArrayElements, { 152 | // onEnter: function (args) { 153 | // }, 154 | // onLeave: function (retval) { 155 | // } 156 | // }); 157 | // } 158 | 159 | 160 | if (addrGetSuperclass != undefined) { 161 | Interceptor.attach(addrGetSuperclass, { 162 | onEnter: function (args) { 163 | var env = Java.vm.getEnv(); 164 | console.log("[V]GetSuperclass->" + env.getClassName(args[1])); 165 | }, 166 | onLeave: function (retval) { 167 | var env = Java.vm.getEnv(); 168 | console.log("\t[I]GetSuperclass::SuperClass->" + env.getClassName(retval)); 169 | } 170 | }); 171 | } 172 | 173 | 174 | if (addrGetStaticIntField != undefined) { 175 | Interceptor.attach(addrGetStaticIntField, { 176 | onEnter: function (args) { 177 | var env = Java.vm.getEnv(); 178 | console.log("[V]GetStaticIntField->" + env.getClassName(args[1])); 179 | }, 180 | onLeave: function (retval) { 181 | console.log("\t[I]GetStaticIntField::value->" + retval.toInt32()); 182 | } 183 | }); 184 | } 185 | 186 | 187 | if (addrGetStaticFieldID != undefined) { 188 | Interceptor.attach(addrGetStaticFieldID, { 189 | onEnter: function (args) { 190 | var env = Java.vm.getEnv(); 191 | console.log("[V]GetStaticFieldID->" + env.getClassName(args[1])); 192 | console.log("\t[V]GetStaticFieldID::name->" + Memory.readCString(args[2])); 193 | console.log("\t[V]GetStaticFieldID::sig->" + Memory.readCString(args[3])); 194 | }, 195 | onLeave: function (retval) { 196 | } 197 | }); 198 | } 199 | 200 | 201 | // if (addrReleaseStringUTFChars != undefined) { 202 | // Interceptor.attach(addrReleaseStringUTFChars, { 203 | // onEnter: function (args) { 204 | // }, 205 | // onLeave: function (retval) { 206 | // } 207 | // }); 208 | // } 209 | 210 | if (addrDeleteLocalRef != undefined) { 211 | Interceptor.attach(addrDeleteLocalRef, { 212 | onEnter: function (args) { 213 | var env = Java.vm.getEnv(); 214 | console.log("[V]DeleteLocalRef::Object->" + env.getObjectClassName(args[1])); 215 | }, 216 | onLeave: function (retval) { 217 | } 218 | }); 219 | } 220 | 221 | } 222 | 223 | setImmediate(hook); -------------------------------------------------------------------------------- /hook_native.js: -------------------------------------------------------------------------------- 1 | function hook_native() { 2 | var opendir_addr = Module.findExportByName(null, 'opendir'); 3 | Interceptor.attach(opendir_addr, { 4 | onEnter: function (args) { 5 | console.log('Native opendir(' + Memory.readCString(args[0]) + ')'); 6 | }, 7 | onLeave: function (retval) { 8 | var path = Memory.readCString(this.path); 9 | console.log('Native opendir(' + path + '), ret->' + retval); 10 | } 11 | }); 12 | 13 | //struct dirent { 14 | // ino_t d_ino; /* Inode number */ 15 | // off_t d_off; /* Not an offset; see below */ 16 | // unsigned short d_reclen; /* Length of this record */ 17 | // unsigned char d_type; /* Type of file; not supported 18 | // by all filesystem types */ 19 | // char d_name[256]; /* Null-terminated filename */ 20 | // }; 21 | // struct dirent *readdir(DIR *dirp); 22 | var readdir_addr = Module.findExportByName(null, 'readdir'); 23 | Interceptor.attach(readdir_addr, { 24 | onEnter: function (args) { 25 | this.dirp = args[0]; 26 | }, 27 | onLeave: function (retval) { 28 | var dirp = this.dirp; 29 | //dump_memory(dirp); 30 | // Memory.protect(ptr(retval.add(19)), 30, 'rw-'); 31 | if (dirp != null) { 32 | console.log('Native readdir(' + dirp + '), ret->' + Memory.readCString(ptr(retval.add(19)))); 33 | } 34 | } 35 | }); 36 | 37 | // int strcasecmp(const char *s1, const char *s2); 38 | var strcasecmp_addr = Module.findExportByName(null, 'strcasecmp'); 39 | Interceptor.attach(strcasecmp_addr, { 40 | onEnter: function (args) { 41 | this.s1 = Memory.readCString(args[0]); 42 | this.s2 = Memory.readCString(args[1]); 43 | }, 44 | onLeave: function (retval) { 45 | var s1 = this.s1; 46 | var s2 = this.s2; 47 | console.log('Native strcasecmp(' + s1 + ', ' + s2 + '), ret->' + retval.toInt32()); 48 | } 49 | }); 50 | 51 | // int strncasecmp(const char *s1, const char *s2, size_t n); 52 | var strncasecmp_addr = Module.findExportByName(null, 'strncasecmp'); 53 | Interceptor.attach(strncasecmp_addr, { 54 | onEnter: function (args) { 55 | this.s1 = Memory.readCString(args[0]); 56 | this.s2 = Memory.readCString(args[1]); 57 | this.n = args[2]; 58 | }, 59 | onLeave: function (retval) { 60 | var s1 = this.s1; 61 | var s2 = this.s2; 62 | var n = this.n; 63 | console.log('Native strncasecmp(' + s1 + ', ' + s2 + ', ' + n.toInt32() + '), ret->' + retval); 64 | } 65 | }); 66 | 67 | // unsigned int sleep(unsigned int seconds); 68 | var sleep_addr = Module.findExportByName(null, 'sleep'); 69 | Interceptor.attach(sleep_addr, { 70 | onEnter: function (args) { 71 | this.seconds = args[0].toInt32(); 72 | }, 73 | onLeave: function (retval) { 74 | var seconds = this.seconds; 75 | console.log('Native sleep(' + seconds + '), ret->' + retval.toInt32()); 76 | } 77 | }); 78 | 79 | // int kill(pid_t pid, int sig); 80 | var kill_addr = Module.findExportByName(null, 'kill'); 81 | Interceptor.attach(kill_addr, { 82 | onEnter: function (args) { 83 | this.pid = args[0].toInt32(); 84 | this.sig = args[1].toInt32(); 85 | }, 86 | onLeave: function (retval) { 87 | var pid = this.pid; 88 | var sig = this.sig; 89 | console.log('Native kill(' + pid + ', ' + sig + '), ret->' + retval.toInt32()); 90 | } 91 | }); 92 | 93 | // int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); 94 | var readdir_r_addr = Module.findExportByName(null, 'readdir_r'); 95 | Interceptor.attach(readdir_r_addr, { 96 | onEnter: function (args) { 97 | this.dirp = args[0]; 98 | this.entry = args[1]; 99 | this.result = args[2]; 100 | }, 101 | onLeave: function (retval) { 102 | //dump_memory(this.entry); 103 | var dirp = this.dirp; 104 | var entry = this.entry; 105 | var result = this.result; 106 | console.log('Native readdir_r(' + dirp + ', ' + Memory.readCString(entry.add(19)) + ', ' + result + '), ret->' + retval); 107 | } 108 | }); 109 | 110 | // char *strstr(const char *haystack, const char *needle) 111 | var strstr_addr = Module.findExportByName(null, 'strstr'); 112 | Interceptor.attach(strstr_addr, { 113 | onEnter: function (args) { 114 | this.haystack = Memory.readCString(args[0]); 115 | this.needle = Memory.readCString(args[1]); 116 | }, 117 | onLeave: function (retval) { 118 | var haystack = this.haystack; 119 | var needle = this.needle; 120 | var ret = Memory.readCString(retval); 121 | console.log('Native strstr(' + haystack + ', ' + needle + '), ret->' + ret); 122 | } 123 | }); 124 | 125 | // char *strcasestr(const char *haystack, const char *needle); 126 | var strcasestr_addr = Module.findExportByName(null, 'strcasestr'); 127 | Interceptor.attach(strcasestr_addr, { 128 | onEnter: function (args) { 129 | this.haystack = Memory.readCString(args[0]); 130 | this.needle = Memory.readCString(args[1]); 131 | }, 132 | onLeave: function (retval) { 133 | var haystack = this.haystack; 134 | var needle = this.needle; 135 | var ret = Memory.readCString(retval); 136 | console.log('Native strcasestr(' + haystack + ', ' + needle + '), ret->' + ret); 137 | } 138 | }); 139 | 140 | // int vsprintf (char * s, const char * format, va_list arg ); 141 | var vsprintf_addr = Module.findExportByName(null, 'vsprintf'); 142 | Interceptor.attach(vsprintf_addr, { 143 | onEnter: function (args) { 144 | this.s = Memory.readCString(args[0]); 145 | this.format = Memory.readCString(args[1]); 146 | this.arg = args[2]; 147 | }, 148 | onLeave: function (retval) { 149 | var s = this.s; 150 | var format = this.format; 151 | var arg = this.arg; 152 | console.log('Native vsprintf(' + s + ', ' + format + ', ' + arg + '), ret->' + retval); 153 | } 154 | }); 155 | 156 | 157 | // int open(const char *pathname, int flags); 158 | var open_addr = Module.findExportByName(null, 'open'); 159 | Interceptor.attach(open_addr, { 160 | onEnter: function (args) { 161 | // console.log('Native open(' + Memory.readCString(args[0]) + ', ' + args[1] + ')'); 162 | this.pathname = args[0]; 163 | this.flags = args[1]; 164 | }, 165 | onLeave: function (retval) { 166 | var pathname = Memory.readCString(this.pathname); 167 | var flags = this.flags; 168 | console.log('Native open(' + pathname + ', ' + flags + '), ret->' + retval); 169 | } 170 | }); 171 | 172 | // int openat64(int fd, const char * path, int oflag, ...); 173 | var openat64_addr = Module.findExportByName(null, 'openat64'); 174 | Interceptor.attach(openat64_addr, { 175 | onEnter: function (args) { 176 | this.fd = args[0]; 177 | this.path = Memory.readCString(ptr(args[1])); 178 | this.oflag = args[2]; 179 | }, 180 | onLeave: function (retval) { 181 | var fd = this.fd; 182 | var path = this.path; 183 | var oflag = this.oflag; 184 | console.log('Native openat64(' + fd + ', ' + path + ', ' + oflag + '), ret->' + retval); 185 | } 186 | }); 187 | 188 | // int openat(int dirfd, const char *pathname, int flags); 189 | var openat_addr = Module.findExportByName(null, 'openat'); 190 | Interceptor.attach(openat_addr, { 191 | onEnter: function (args) { 192 | this.dirfd = args[0]; 193 | this.pathname = Memory.readCString(args[1]); 194 | this.flags = args[2]; 195 | }, 196 | onLeave: function (retval) { 197 | var dirfd = this.dirfd; 198 | var pathname = this.pathname; 199 | var flags = this.flags; 200 | console.log('Native openat(' + dirfd + ', ' + pathname + ', ' + flags + '), ret->' + retval); 201 | } 202 | }); 203 | 204 | // off_t lseek(int fd, off_t offset, int whence); 205 | var lseek_addr = Module.findExportByName(null, 'lseek'); 206 | Interceptor.attach(lseek_addr, { 207 | onEnter: function (args) { 208 | this.fd = args[0]; 209 | this.offset = args[1]; 210 | this.whence = args[2]; 211 | }, 212 | onLeave: function (retval) { 213 | var fd = this.fd; 214 | var offset = this.offset; 215 | var whence = this.whence; 216 | console.log('Native lseek(' + fd + ', ' + offset + ', ' + whence + '), ret->' + retval); 217 | } 218 | }); 219 | 220 | // off64_t lseek64(int fd, off64_t offset, int whence); 221 | var lseek64_addr = Module.findExportByName(null, 'lseek64'); 222 | Interceptor.attach(lseek64_addr, { 223 | onEnter: function (args) { 224 | this.fd = args[0]; 225 | this.offset = args[1]; 226 | this.whence = args[2]; 227 | }, 228 | onLeave: function (retval) { 229 | var fd = this.fd; 230 | var offset = this.offset; 231 | var whence = this.whence; 232 | console.log('Native lseek64(' + fd + ', ' + offset + ', ' + whence + '), ret->' + retval); 233 | } 234 | }); 235 | 236 | // int ftruncate(int fildes, off_t length); 237 | var ftruncate_addr = Module.findExportByName(null, 'ftruncate'); 238 | Interceptor.attach(ftruncate_addr, { 239 | onEnter: function (args) { 240 | this.fildes = args[0]; 241 | this.length = args[1]; 242 | }, 243 | onLeave: function (retval) { 244 | var fildes = this.fildes; 245 | var length = this.length; 246 | console.log('Native ftruncate(' + fildes + ', ' + length + '), ret->' + retval); 247 | } 248 | }); 249 | 250 | 251 | // int creat(const char *path, mode_t mode); 252 | var create_addr = Module.findExportByName(null, 'create'); 253 | if (create_addr) { 254 | Interceptor.attach(create_addr, { 255 | onEnter: function (args) { 256 | this.path = Memory.readCString(args[0]); 257 | this.mode = args[1]; 258 | }, 259 | onLeave: function (retval) { 260 | var path = this.path; 261 | var mode = this.mode; 262 | console.log('Native create(' + path + ', ' + mode + '), ret->' + retval); 263 | } 264 | }); 265 | } 266 | 267 | // char *strrchr(const char *str, int c) 268 | var strrchr_addr = Module.findExportByName(null, 'strrchr'); 269 | Interceptor.attach(strrchr_addr, { 270 | onEnter: function (args) { 271 | this.str = Memory.readCString(args[0]); 272 | this.c = args[1]; 273 | }, 274 | onLeave: function (retval) { 275 | var str = this.str; 276 | var c = this.c; 277 | var ret = Memory.readCString(retval); 278 | console.log('Native strrchr(' + str + ', ' + c + ', ' + ret + '), ret->' + retval); 279 | } 280 | }); 281 | 282 | // int mkdirat(int dirfd, const char *pathname, mode_t mode); 283 | var mkdirat_addr = Module.findExportByName(null, 'mkdirat'); 284 | Interceptor.attach(mkdirat_addr, { 285 | onEnter: function (args) { 286 | this.dirfd = args[0]; 287 | this.pathname = args[1]; 288 | this.mode = args[2]; 289 | }, 290 | onLeave: function (retval) { 291 | var dirfd = this.dirfd; 292 | var pathname = this.pathname; 293 | var mode = this.mode; 294 | console.log('Native mkdirat(' + dirfd + ', ' + pathname + ', ' + mode + '), ret->' + retval); 295 | } 296 | }); 297 | 298 | var fdopendir_addr = Module.findExportByName(null, 'fdopendir'); 299 | Interceptor.attach(fdopendir_addr, { 300 | onEnter: function (args) { 301 | this.arg = args[0]; 302 | }, 303 | onLeave: function (retval) { 304 | var arg = this.arg; 305 | console.log('Native fdopendir_addr(' + arg + '), ret->' + retval); 306 | } 307 | }); 308 | 309 | var access_addr = Module.findExportByName(null, 'access'); 310 | Interceptor.attach(access_addr, { 311 | onEnter: function (args) { 312 | if (Memory.readCString(args[0]).endsWith("su")) { 313 | Memory.writeUtf8String(args[0], Memory.readCString(args[0]) + "c"); 314 | } 315 | this.path = args[0]; 316 | this.flag = args[1]; 317 | }, 318 | onLeave: function (retval) { 319 | var path = Memory.readCString(this.path); 320 | var flag = this.flag; 321 | console.log('Native access(' + path + ', ' + flag + '), ret->' + retval); 322 | } 323 | }); 324 | 325 | var fopen_addr = Module.findExportByName(null, 'fopen'); 326 | Interceptor.attach(fopen_addr, { 327 | onEnter: function (args) { 328 | this.path = Memory.readCString(ptr(args[0])); 329 | this.flag = args[1]; 330 | }, 331 | onLeave: function (retval) { 332 | var path = this.path; 333 | var flag = this.flag; 334 | console.log('Native fopen(' + path + ', ' + flag + '), ret->' + retval); 335 | } 336 | }); 337 | 338 | 339 | // int strcmp(const char *s1, const char *s2); 340 | var strcmp_addr = Module.findExportByName(null, 'strcmp'); 341 | Interceptor.attach(strcmp_addr, { 342 | onEnter: function (args) { 343 | this.str0 = Memory.readCString(args[0]); 344 | this.str1 = Memory.readCString(args[1]); 345 | if (this.str0 == 'TracerPid') { 346 | Memory.writeUtf8String(args[0], "TracerPd"); 347 | } 348 | 349 | }, 350 | onLeave: function (retval) { 351 | var str0 = this.str0; 352 | var str1 = this.str1; 353 | console.log('Native strcmp(' + str0 + ', ' + str1 + '), ret->' + retval); 354 | } 355 | }); 356 | 357 | // const char * strchr ( const char * str, int character ); 358 | var strchr_addr = Module.findExportByName(null, 'strchr'); 359 | Interceptor.attach(strchr_addr, { 360 | onEnter: function (args) { 361 | this.str = Memory.readCString(args[0]); 362 | this.character = args[1].toInt32(); 363 | }, 364 | onLeave: function (retval) { 365 | var str = this.str; 366 | var character = this.character; 367 | console.log('Native strchr(' + str + ', ' + character + '), ret->' + retval); 368 | } 369 | }); 370 | 371 | // long int strtol(const char *nptr, char **endptr, int base); 372 | var strtol_addr = Module.findExportByName(null, 'strtol'); 373 | Interceptor.attach(strtol_addr, { 374 | onEnter: function (args) { 375 | this.nptr = Memory.readCString(args[0]); 376 | this.endptr = args[1]; 377 | this.base = args[2].toInt32(); 378 | }, 379 | onLeave: function (retval) { 380 | var nptr = this.nptr; 381 | var endptr = this.endptr; 382 | var base = this.base; 383 | console.log('Native strtol(' + nptr + ', ' + endptr + ', ' + base + '), ret->' + retval.toInt32()); 384 | } 385 | }); 386 | 387 | // long long int strtoll(const char *nptr, char **endptr, int base); 388 | var strtoll_addr = Module.findExportByName(null, 'strtoll'); 389 | Interceptor.attach(strtoll_addr, { 390 | onEnter: function (args) { 391 | this.nptr = Memory.readCString(args[0]); 392 | this.endptr = args[1]; 393 | this.base = args[2].toInt32(); 394 | }, 395 | onLeave: function (retval) { 396 | var nptr = this.nptr; 397 | var endptr = this.endptr; 398 | var base = this.base; 399 | console.log('Native strtoll(' + nptr + ', ' + endptr + ', ' + base + '), ret->' + retval.toInt32()); 400 | } 401 | }); 402 | 403 | // int islower(int c); 404 | var islower_addr = Module.findExportByName(null, 'islower'); 405 | Interceptor.attach(islower_addr, { 406 | onEnter: function (args) { 407 | this.c = args[0].toInt32(); 408 | }, 409 | onLeave: function (retval) { 410 | var c = this.c; 411 | console.log('Nativa islower(' + c + '), ret->' + retval.toInt32()); 412 | } 413 | }); 414 | 415 | // char* getenv(const char* name) 416 | var getenv_addr = Module.findExportByName(null, 'getenv'); 417 | Interceptor.attach(getenv_addr, { 418 | onEnter: function (args) { 419 | this.name = Memory.readCString(args[0]); 420 | }, 421 | onLeave: function (retval) { 422 | var name = this.name; 423 | console.log('Native getenv(' + name + '), ret->' + retval); 424 | } 425 | }); 426 | 427 | // int strncmp ( const char * str1, const char * str2, size_t num ); 428 | var strncmp_addr = Module.findExportByName(null, 'strncmp'); 429 | // Interceptor.attach(strncmp_addr, { 430 | // onEnter: function (args) { 431 | // this.str0 = args[0]; 432 | // this.str1 = args[1]; 433 | // this.num = args[2]; 434 | // }, 435 | // onLeave: function (retval) { 436 | // var num = this.num; 437 | // var str0 = Memory.readCString(this.str0, num); 438 | // var str1 = Memory.readCString(this.str1, num); 439 | // console.log('Native strncmp(' + str0 + ', ' + str1 + ', ' + num + '), ret->' + retval); 440 | // } 441 | // }); 442 | 443 | // int stat(const char *file_name, struct stat *buf); 444 | var stat_addr = Module.findExportByName(null, 'stat'); 445 | Interceptor.attach(stat_addr, { 446 | onEnter: function (args) { 447 | this.file_name = Memory.readCString(ptr(args[0])); 448 | this.buf = args[1]; 449 | }, 450 | onLeave: function (retval) { 451 | var file_name = this.file_name; 452 | var buf = this.buf; 453 | console.log('Native stat(' + file_name + ', ' + buf + '), ret->' + retval); 454 | } 455 | }); 456 | 457 | // int lstat(const char *path, struct stat *buf); 458 | var lstat_addr = Module.findExportByName(null, 'lstat'); 459 | Interceptor.attach(lstat_addr, { 460 | onEnter: function (args) { 461 | this.file_name = Memory.readCString(ptr(args[0])); 462 | this.buf = args[1]; 463 | }, 464 | onLeave: function (retval) { 465 | var file_name = this.file_name; 466 | var buf = this.buf; 467 | console.log('Native lstat(' + file_name + ', ' + buf + '), ret->' + retval); 468 | } 469 | }); 470 | 471 | 472 | // int fstat(int fd, struct stat *buf); 473 | var fstat_addr = Module.findExportByName(null, 'fstat'); 474 | Interceptor.attach(fstat_addr, { 475 | onEnter: function (args) { 476 | this.fd = args[0]; 477 | this.buf = args[1]; 478 | }, 479 | onLeave: function (retval) { 480 | var fd = this.fd; 481 | var buf = this.buf; 482 | console.log('Native lstat(' + fd + ', ' + buf + '), ret->' + retval); 483 | } 484 | }); 485 | 486 | // const void * memchr ( const void * ptr, int value, size_t num ); 487 | var memchr_addr = Module.findExportByName(null, 'memchr'); 488 | Interceptor.attach(memchr_addr, { 489 | onEnter: function (args) { 490 | this.ptr = args[0]; 491 | this.value = args[1]; 492 | this.num = args[2]; 493 | }, 494 | onLeave: function (retval) { 495 | var ptr = Memory.readCString(this.ptr); 496 | var value = Memory.readCString(this.value); 497 | var num = this.num; 498 | console.log('Native memchr(' + ptr + ', ' + value + ', ' + num + '),ret->' + retval); 499 | } 500 | }); 501 | 502 | // int memcmp(const void *s1, const void *s2, size_t n); 503 | var memcmp_addr = Module.findExportByName(null, 'memcmp'); 504 | Interceptor.attach(memcmp_addr, { 505 | onEnter: function (args) { 506 | this.s1 = args[0]; 507 | this.s2 = args[1]; 508 | this.n = args[2].toInt32(); 509 | }, 510 | onLeave: function (retval) { 511 | var s1 = this.s1; 512 | var s2 = this.s2; 513 | var n = this.n; 514 | console.log('Native memcmp(' + s1 + ', ' + s2 + ', ' + n + '), ret->' + retval); 515 | } 516 | 517 | }); 518 | 519 | // void *memcpy(void *dest, const void *src, size_t n); 520 | var memcpy_addr = Module.findExportByName(null, 'memcpy'); 521 | Interceptor.attach(memcpy_addr, { 522 | onEnter: function (args) { 523 | this.dest = args[0]; 524 | this.src = args[1]; 525 | this.n = args[2].toInt32(); 526 | }, 527 | onLeave: function (retval) { 528 | var dest = this.dest; 529 | var src = this.src; 530 | var n = this.n; 531 | console.log('Native memcpy(' + dest + ', ' + src + ', ' + n + ', ret->' + retval); 532 | } 533 | }); 534 | 535 | var strlen_addr = Module.findExportByName(null, 'strlen'); 536 | Interceptor.attach(strlen_addr, { 537 | onEnter: function (args) { 538 | this.str = Memory.readCString(ptr(args[0])); 539 | }, 540 | onLeave: function (retval) { 541 | var str = this.str; 542 | console.log('Native strlen(' + str + '), ret->' + str); 543 | } 544 | }); 545 | 546 | // FILE * popen(const char *command , const char *type ); 547 | var popen_addr = Module.findExportByName(null, 'popen'); 548 | Interceptor.attach(popen_addr, { 549 | onEnter: function (args) { 550 | this.command = Memory.readCString(ptr(args[0])); 551 | this.type = Memory.readCString(ptr(args[1])); 552 | }, 553 | onLeave: function (retval) { 554 | var command = this.command; 555 | var type = this.type; 556 | console.log('Native popen(' + command + ', ' + type + '), ret->' + retval); 557 | } 558 | }); 559 | 560 | // int atoi (const char * str); 561 | var atoi_addr = Module.findExportByName(null, 'atoi'); 562 | Interceptor.attach(atoi_addr, { 563 | onEnter: function (args) { 564 | this.str = Memory.readCString(args[0]); 565 | }, 566 | onLeave: function (retval) { 567 | var str = this.str; 568 | console.log('Native atoi(' + str + '), ret->' + retval); 569 | } 570 | }); 571 | 572 | // int regcomp(regex_t *restrict preg, const char *restrict pattern, int cflags); 573 | var regcomp_addr = Module.findExportByName(null, 'regcomp'); 574 | Interceptor.attach(regcomp_addr, { 575 | onEnter: function (args) { 576 | this.preg = args[0]; 577 | this.pattern = Memory.readCString(args[1]); 578 | this.cflags = args[2]; 579 | }, 580 | onLeave: function (retval) { 581 | var preg = this.preg; 582 | var pattern = this.pattern; 583 | var cflags = this.cflags; 584 | console.log('Native regcomp(' + preg + ', ' + pattern + ', ' + cflags + '), ret->' + retval); 585 | } 586 | }); 587 | 588 | // size_t regerror(int errcode, const regex_t *restrict preg, char *restrict errbuf, size_t errbuf_size); 589 | // void regfree(regex_t *preg); 590 | // int regexec(const regex_t *restrict preg, const char *restrict string, size_t nmatch, regmatch_t pmatch[restrict], int eflags); 591 | var regexec_addr = Module.findExportByName(null, 'regexec'); 592 | Interceptor.attach(regexec_addr, { 593 | onEnter: function (args) { 594 | this.preg = args[0]; 595 | this.string = Memory.readCString(args[1]); 596 | this.nmatch = args[2]; 597 | this.pmatch = args[3]; 598 | this.eflags = args[4]; 599 | }, 600 | onLeave: function (retval) { 601 | var preg = this.preg; 602 | var string = this.string; 603 | var nmatch = this.nmatch; 604 | var pmatch = this.pmatch; 605 | var eflags = this.eflags; 606 | console.log('Native regexec(' + preg + ', ' + string + ', ' + nmatch + ', ' + pmatch + ', ' + eflags + '), retval->' + retval); 607 | } 608 | }); 609 | 610 | // void * memset ( void * ptr, int value, size_t num ); 611 | var memset_addr = Module.findExportByName(null, 'memset'); 612 | Interceptor.attach(memset_addr, { 613 | onEnter: function (args) { 614 | this.ptr = args[0]; 615 | this.value = args[1]; 616 | this.num = args[2]; 617 | }, 618 | onLeave: function (retval) { 619 | var ptr = this.ptr; 620 | var value = this.value; 621 | var num = this.num; 622 | console.log('Native memset(' + ptr + ', ' + value + ',' + num + '), ret->' + retval); 623 | } 624 | }); 625 | 626 | 627 | // char *fgets(char *str, int n, FILE *stream) 628 | var fgets_addr = Module.findExportByName(null, 'fgets'); 629 | Interceptor.attach(fgets_addr, { 630 | onEnter: function (args) { 631 | this.str = Memory.readCString(ptr(args[0])); 632 | this.n = args[1]; 633 | this.stream = args[2]; 634 | 635 | }, 636 | onLeave: function (retval) { 637 | console.log('Native fgets(' + this.str + ', ' + this.n + ', ' + this.stream + '), ret->' + retval); 638 | } 639 | }); 640 | 641 | // int sprintf( char *buffer, const char *format [, argument] ... ); 642 | var sprintf_addr = Module.findExportByName(null, 'sprintf'); 643 | Interceptor.attach(sprintf_addr, { 644 | onEnter: function (args) { 645 | this.buffer = ptr(args[0]); 646 | this.format = ptr(args[1]); 647 | 648 | }, 649 | onLeave: function (retval) { 650 | var buffer = Memory.readCString(this.buffer); 651 | var format = Memory.readCString(this.format); 652 | console.log('Native sprintf(' + buffer + ', ' + format + '), ret->' + retval); 653 | } 654 | }); 655 | 656 | // int snprintf ( char * s, size_t n, const char * format, ... ); 657 | var snprintf_add = Module.findExportByName(null, 'snprintf'); 658 | Interceptor.attach(snprintf_add, { 659 | onEnter: function (args) { 660 | this.buffer = ptr(args[0]); 661 | this.size = args[1]; 662 | this.format = ptr(args[2]); 663 | 664 | }, 665 | onLeave: function (retval) { 666 | var buffer = Memory.readCString(this.buffer); 667 | var size = this.size; 668 | var format = Memory.readCString(this.format); 669 | if (size > 5) { 670 | console.log('Native snprintf(' + buffer + ', ' + size + ',' + format + '), ret->' + retval); 671 | } 672 | } 673 | }); 674 | 675 | // int fputs ( const char * str, FILE * stream ); 676 | var fputs_addr = Module.findExportByName(null, 'fputs'); 677 | Interceptor.attach(fputs_addr, { 678 | onEnter: function (args) { 679 | this.str = Memory.readCString(ptr(args[0])); 680 | this.stream = args[1]; 681 | 682 | }, 683 | onLeave: function (retval) { 684 | var str = this.str; 685 | var stream = this.stream; 686 | console.log('Native fputs(' + str + ', ' + stream + '), ret->' + retval); 687 | } 688 | }); 689 | 690 | // int fprintf(FILE *stream, const char *format, ...) 691 | var fprintf_addr = Module.findExportByName(null, 'fprintf'); 692 | Interceptor.attach(fprintf_addr, { 693 | onEnter: function (args) { 694 | this.stream = args[0]; 695 | this.format = Memory.readCString(ptr(args[1])); 696 | 697 | }, 698 | onLeave: function (retval) { 699 | var str = this.format; 700 | var stream = this.stream; 701 | console.log('Native fprintf(' + stream + ', ' + str + '), ret->' + retval); 702 | 703 | } 704 | }); 705 | 706 | // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 707 | var fread_addr = Module.findExportByName(null, 'fread'); 708 | Interceptor.attach(fread_addr, { 709 | onEnter: function (args) { 710 | this.ptr = ptr(args[0]); 711 | this.size = args[1]; 712 | this.nmemb = args[2]; 713 | this.stream = args[3]; 714 | 715 | }, 716 | onLeave: function (retval) { 717 | var ptr = Memory.readCString(this.ptr); 718 | var size = this.size; 719 | var nmemb = this.nmemb; 720 | var stream = this.stream; 721 | console.log('Native fread(' + ptr + ', ' + size + ', ' + nmemb + ', ' + stream + '), ret->' + retval); 722 | 723 | } 724 | }); 725 | 726 | // ssize_t read(int fd, void * buf, size_t count); 727 | var read_addr = Module.findExportByName(null, 'read'); 728 | Interceptor.attach(read_addr, { 729 | onEnter: function (args) { 730 | this.fd = args[0]; 731 | this.buf = ptr(args[1]); 732 | this.count = args[2]; 733 | }, 734 | onLeave: function (retval) { 735 | var fd = this.fd; 736 | var buf = Memory.readCString(this.buf); 737 | var count = this.count; 738 | console.log('Native read(' + fd + ', ' + buf + ', ' + count + '), ret->' + retval); 739 | } 740 | }); 741 | 742 | // int fstatat(int dirfd, const char *path, struct stat * buf ", int " flags ); 743 | var fstatat_addr = Module.findExportByName(null, 'fstatat'); 744 | Interceptor.attach(fstatat_addr, { 745 | onEnter: function (args) { 746 | this.dirfd = args[0]; 747 | this.path = Memory.readCStirng(args[1]); 748 | this.buf = args[2]; 749 | this.flags = args[3]; 750 | }, 751 | onLeave: function (retval) { 752 | var dirfd = this.dirfd; 753 | var path = this.path; 754 | var buf = this.buf; 755 | var flags = this.flags; 756 | console.log('Native fstatat(' + dirfd + ', ' + path + ', ' + buf + ', ' + flags + '), ret->' + retval); 757 | } 758 | }); 759 | 760 | // size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream ); 761 | var fwrite_addr = Module.findExportByName(null, 'fwrite'); 762 | Interceptor.attach(fwrite_addr, { 763 | onEnter: function (args) { 764 | this.buffer = Memory.readCString(ptr(args[0])); 765 | this.size = args[1]; 766 | this.count = args[2]; 767 | this.stream = args[3]; 768 | 769 | }, 770 | onLeave: function (retval) { 771 | var str = this.buffer; 772 | var size = this.size; 773 | var count = this.count; 774 | var stream = this.stream; 775 | console.log('Native fwrite(' + str + ', ' + size + ', ' + count + ',' + stream + '), ret->' + retval); 776 | 777 | } 778 | }); 779 | 780 | // ssize_t write (int fd, const void * buf, size_t count); 781 | var write_addr = Module.findExportByName(null, 'write'); 782 | Interceptor.attach(write_addr, { 783 | onEnter: function (args) { 784 | this.fd = args[0]; 785 | this.buf = Memory.readCString(ptr(args[1])); 786 | this.count = args[2]; 787 | 788 | }, 789 | onLeave: function (retval) { 790 | var fd = this.fd; 791 | var buf = this.buf; 792 | var count = this.count; 793 | console.log('Native write(' + fd + ', ' + buf + ', ' + count + '), ret->' + retval); 794 | 795 | } 796 | }); 797 | 798 | // char *strcpy(char *dest, const char *src); 799 | var strcpy_addr = Module.findExportByName(null, 'strcpy'); 800 | Interceptor.attach(strcpy_addr, { 801 | onEnter: function (args) { 802 | this.dest = args[0]; 803 | this.src = Memory.readCString(args[1]); 804 | }, 805 | onLeave: function (retval) { 806 | var dest = Memory.readCString(this.dest); 807 | var src = this.src; 808 | console.log('Native strcpy(' + dest + ', ' + src + '), ret->' + retval); 809 | 810 | } 811 | }); 812 | 813 | // char *strcat(char *dest, const char *src) 814 | var strcat_addr = Module.findExportByName(null, 'strcat'); 815 | Interceptor.attach(strcat_addr, { 816 | onEnter: function (args) { 817 | this.dest = Memory.readCStirng(args[0]); 818 | this.src = Memory.readCStirng(args[1]); 819 | }, 820 | onLeave: function (retval) { 821 | var dest = this.dest; 822 | var src = this.src; 823 | console.log('Native strcat(' + dest + ', ' + src + '), ret->' + retval); 824 | } 825 | }); 826 | 827 | // char * strncat ( char * destination, const char * source, size_t num ); 828 | var strncat_addr = Module.findExportByName(null, 'strncat'); 829 | Interceptor.attach(strncat_addr, { 830 | onEnter: function (args) { 831 | this.dest = Memory.readCStirng(args[0]); 832 | this.src = Memory.readCStirng(args[1]); 833 | this.num = args[2]; 834 | }, 835 | onLeave: function (retval) { 836 | var dest = this.dest; 837 | var src = this.src; 838 | var num = this.num; 839 | console.log('Native strncat(' + dest + ', ' + src + ', ' + num + '), ret->' + retval); 840 | } 841 | }); 842 | 843 | // char *strncpy(char *dest, const char *src, size_t n); 844 | var strncpy_addr = Module.findExportByName(null, 'strncpy'); 845 | Interceptor.attach(strncpy_addr, { 846 | onEnter: function (args) { 847 | this.dest = args[0]; 848 | this.src = Memory.readCString(args[1]); 849 | this.n = args[2]; 850 | }, 851 | onLeave: function (retval) { 852 | var dest = Memory.readCString(this.dest); 853 | var src = this.src; 854 | var n = this.n; 855 | console.log('Native strncpy(' + dest + ', ' + src + ", " + n + '), ret->' + retval); 856 | 857 | } 858 | }); 859 | 860 | // int rename ( const char * oldname, const char * newname ); 861 | var rename_addr = Module.findExportByName(null, 'rename'); 862 | Interceptor.attach(rename_addr, { 863 | onEnter: function (args) { 864 | this.oldname = Memory.readCString(args[0]); 865 | this.newname = Memory.readCString(args[1]); 866 | }, 867 | onLeave: function (retval) { 868 | var oldname = this.oldname; 869 | var newname = this.newname; 870 | console.log('Native rename(' + oldname + ', ' + newname + '), ret->' + retval); 871 | } 872 | }); 873 | 874 | // __system_property_get(const char *key, char *value) 875 | var system_property_get_addr = Module.findExportByName(null, '__system_property_get'); 876 | Interceptor.attach(system_property_get_addr, { 877 | onEnter: function (args) { 878 | this.key = args[0]; 879 | this.value = args[1]; 880 | }, 881 | onLeave: function (retval) { 882 | var key = Memory.readCString(this.key); 883 | var value = Memory.readCString(this.src); 884 | console.log('Native __system_property_get(' + key + ', ' + value + '), ret->' + retval); 885 | 886 | } 887 | }); 888 | 889 | // int system (const char* command); 890 | var system_addr = Module.findExportByName(null, 'system'); 891 | Interceptor.attach(system_addr, { 892 | onEnter: function (args) { 893 | this.command = Memory.readCString(args[0]); 894 | }, 895 | onLeave: function (retval) { 896 | var command = this.command; 897 | console.log('Native system(' + command + '), ret->' + retval); 898 | } 899 | }); 900 | 901 | // void *dlopen(const char *filename, int flag); 902 | var dloepn_addr = Module.findExportByName(null, 'dlopen'); 903 | Interceptor.attach(dloepn_addr, { 904 | onEnter: function (args) { 905 | this.filename = Memory.readCString(args[0]); 906 | this.flag = args[1]; 907 | }, 908 | onLeave: function (retval) { 909 | var filename = this.filename; 910 | var flag = this.flag; 911 | console.log('Native dlopen(' + filename + ', ' + flag + '), ret->' + retval); 912 | } 913 | }); 914 | 915 | // char *dlerror(void); 916 | var dlerror_addr = Module.findExportByName(null, 'dlerror'); 917 | Interceptor.attach(dlerror_addr, { 918 | onEnter: function (args) { 919 | }, 920 | onLeave: function (retval) { 921 | console.log('Native dlerror(), ret->' + Memory.readCString(retval)); 922 | } 923 | }); 924 | 925 | // void *dlsym(void *handle, const char *symbol); 926 | var dlsym_addr = Module.findExportByName(null, 'dlsym'); 927 | Interceptor.attach(dlsym_addr, { 928 | onEnter: function (args) { 929 | this.handle = args[0]; 930 | this.symbol = Memory.readCString(args[1]); 931 | }, 932 | onLeave: function (retval) { 933 | var handle = this.handle; 934 | var symbol = this.symbol; 935 | console.log('Native dlsym(' + handle + ', ' + symbol + '), ret->' + retval); 936 | } 937 | }); 938 | 939 | // int dlclose(void *handle); 940 | var dlclose_addr = Module.findExportByName(null, 'dlclose'); 941 | Interceptor.attach(dlclose_addr, { 942 | onEnter: function (args) { 943 | this.handle = args[0]; 944 | }, 945 | onLeave: function (retval) { 946 | var handle = this.handle; 947 | console.log('Native dlclose(' + handle + '), ret->' + retval); 948 | } 949 | }); 950 | 951 | // void* malloc (size_t size); 952 | var malloc_addr = Module.findExportByName(null, 'malloc'); 953 | Interceptor.attach(malloc_addr, { 954 | onEnter: function (args) { 955 | this.size = args[0]; 956 | }, 957 | onLeave: function (retval) { 958 | var size = this.size; 959 | console.log('Native malloc(' + size + '), ret->' + retval); 960 | } 961 | }); 962 | 963 | // long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); 964 | var ptrace_addr = Module.findExportByName(null, 'ptrace'); 965 | Interceptor.attach(ptrace_addr, { 966 | onEnter: function (args) { 967 | this.request = args[0]; 968 | this.pid = args[1]; 969 | this.addr = args[2]; 970 | this.data = args[3]; 971 | }, 972 | onLeave: function (retval) { 973 | var request = this.request; 974 | var pid = this.pid; 975 | var addr = this.addr; 976 | var data = this.data; 977 | console.log('Native ptrace(' + request + ', ' + pid + ', ' + addr + ', ' + data + '), ret->' + retval); 978 | } 979 | }); 980 | 981 | // pid_t fork(void); 982 | var fork_addr = Module.findExportByName(null, 'fork'); 983 | Interceptor.attach(fork_addr, { 984 | onEnter: function (args) { 985 | 986 | }, 987 | onLeave: function (retval) { 988 | console.log('Native fork(), ret->' + retval); 989 | } 990 | }); 991 | 992 | // pid_t getppid(void); 993 | var getppid_addr = Module.findExportByName(null, 'getppid'); 994 | Interceptor.attach(getppid_addr, { 995 | onEnter: function (args) { 996 | 997 | }, 998 | onLeave: function (retval) { 999 | console.log('Native getppid(), ret->' + retval); 1000 | } 1001 | }); 1002 | 1003 | // int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 1004 | var pthread_create_addr = Module.findExportByName(null, 'pthread_create'); 1005 | Interceptor.attach(pthread_create_addr, { 1006 | onEnter: function (args) { 1007 | console.log('Native pthread_create() is called!'); 1008 | }, 1009 | onLeave: function (retval) { 1010 | 1011 | } 1012 | }); 1013 | 1014 | // int kill(pid_t pid, int sig); 1015 | var kill_addr = Module.findExportByName(null, 'kill'); 1016 | Interceptor.attach(kill_addr, { 1017 | onEnter: function (args) { 1018 | console.log('Native kill(' + args[0].toInt32() + ', ' + args[1].toInt32() + ') is called!'); 1019 | }, 1020 | onLeave: function (retval) { 1021 | 1022 | } 1023 | }); 1024 | 1025 | // void exit(int status); 1026 | var exit_addr = Module.findExportByName(null, 'exit'); 1027 | Interceptor.attach(exit_addr, { 1028 | onEnter: function (args) { 1029 | console.log('Native exit(' + args[0].toInt32() + ') is called!'); 1030 | // return; 1031 | }, 1032 | onLeave: function (retval) { 1033 | 1034 | } 1035 | }); 1036 | 1037 | // void abort(void); 1038 | var abort_addr = Module.findExportByName(null, 'abort'); 1039 | Interceptor.attach(abort_addr, { 1040 | onEnter: function (args) { 1041 | console.log('Native abort() is called!'); 1042 | // return; 1043 | }, 1044 | onLeave: function (retval) { 1045 | 1046 | } 1047 | }); 1048 | 1049 | // int raise(int sig); 1050 | var raise_addr = Module.findExportByName(null, 'raise'); 1051 | Interceptor.attach(raise_addr, { 1052 | onEnter: function (args) { 1053 | console.log('Native raise(' + args[0].toInt32() + ') is called!'); 1054 | // return 0; 1055 | }, 1056 | onLeave: function (retval) { 1057 | 1058 | } 1059 | }); 1060 | 1061 | }; 1062 | 1063 | setTimeout(hook_native, 0); 1064 | -------------------------------------------------------------------------------- /hook_native_code.py: -------------------------------------------------------------------------------- 1 | import frida 2 | import sys 3 | 4 | package_name = 'com.alex.lookwifipassword' 5 | 6 | rdev = frida.get_remote_device() 7 | # 脚本控制app启动 8 | pid = rdev.spawn(package_name) 9 | session = rdev.attach(pid) 10 | rdev.resume(pid) 11 | 12 | def on_message(message, data): 13 | if message['type'] == 'error': 14 | print(message['stack']) 15 | else: 16 | print(message) 17 | 18 | 19 | with open('hook.js', 'r') as f: 20 | jscode = f.read() 21 | 22 | script = session.create_script(jscode) 23 | script.on('message', on_message) 24 | script.load() 25 | sys.stdin.read() 26 | session.detach() 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /native.js: -------------------------------------------------------------------------------- 1 | /** 2 | * int SSL_get_fd(const SSL *ssl); 3 | */ 4 | var SSL_get_fd_addr = Module.findExportByName(null, "SSL_get_fd"); 5 | var SSL_get_fd = new NativeFunction(SSL_get_fd_addr, "int", ["pointer"]); 6 | 7 | /** 8 | * get remote ip 9 | * int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 10 | * 11 | */ 12 | var getpeername_addr = Module.findExportByName(null, "getpeername"); 13 | var getpeername = new NativeFunction(getpeername_addr, "int", ["int", "pointer", "pointer"]); 14 | 15 | /** 16 | * get local host ip 17 | * int getsockname(int sockfd, struct sockaddr * localaddr, socken_t * addrlen); 18 | */ 19 | var getsockname_addr = Module.findExportByName(null, "getsockname"); 20 | var getsockname = new NativeFunction(getsockname_addr, "int", ["int", "pointer", "pointer"]); 21 | 22 | /** 23 | * convert ip to string 24 | * const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 25 | */ 26 | var inet_ntop_addr = Module.findExportByName(null, "inet_ntop"); 27 | var inet_ntop = new NativeFunction(inet_ntop_addr, "pointer", ["int", "pointer", "pointer", "int"]); 28 | 29 | /** 30 | * returns a pointer to the SSL_SESSION 31 | * SSL_SESSION *SSL_get_session(const SSL *ssl); 32 | */ 33 | var SSL_get_session_addr = Module.findExportByName(null, "SSL_get_session"); 34 | var SSL_get_session = new NativeFunction(SSL_get_session_addr, "pointer", ["pointer"]); 35 | 36 | /** 37 | * returns a pointer to the internal session id value for the session s 38 | * const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) 39 | */ 40 | var SSL_SESSION_get_id_addr = Module.findExportByName(null, "SSL_SESSION_get_id"); 41 | var SSL_SESSION_get_id = new NativeFunction(SSL_SESSION_get_id_addr, "pointer", ["pointer", "pointer"]) 42 | 43 | function hook_native() { 44 | 45 | /** 46 | * target: int SSL_write(SSL *ssl, const void *buf, int num); 47 | * ssl: getpeername->SSL_get_fd->ssl 48 | * buf: msg which not encrypt 49 | * num: buf len 50 | */ 51 | Interceptor.attach(Module.findExportByName(null, "SSL_write"), { 52 | onEnter: function (args) { 53 | this.ssl_st = args[0]; 54 | this.buf = args[1]; 55 | this.num = args[2].toInt32(); 56 | var message = getPortsAndAddresses(SSL_get_fd(this.ssl_st), false); 57 | message["ssl_session_id"] = getSSLSessionID(this.ssl_st); 58 | message["function"] = "SSL_write"; 59 | send(message, Memory.readByteArray(this.buf, this.num)); 60 | }, 61 | onLeave: function (retval) { 62 | } 63 | }); 64 | 65 | /** 66 | * int SSL_read(SSL *ssl, void *buf, int num); 67 | * The read operation was successful. The return value is the number of bytes actually read from the TLS/SSL connection. 68 | */ 69 | Interceptor.attach(Module.findExportByName(null, "SSL_read"), { 70 | onEnter: function (args) { 71 | this.ssl_st = args[0]; 72 | this.buf = args[1]; 73 | this.num = args[2].toInt32(); 74 | var message = getPortsAndAddresses(SSL_get_fd(this.ssl_st), true); 75 | message["ssl_session_id"] = getSSLSessionID(this.ssl_st); 76 | message["function"] = "SSL_read"; 77 | this.message = message; 78 | }, 79 | onLeave: function (retval) { 80 | retval |= 0; 81 | if(retval <= 0){ 82 | return; 83 | } 84 | send(this.message, Memory.readByteArray(this.buf, retval)); 85 | } 86 | }); 87 | } 88 | 89 | /** 90 | * get port android ip 91 | * @param sockfd 92 | * @param isRead isRead: true(SSL_read), isRead: false(SSL_write) 93 | */ 94 | function getPortsAndAddresses(sockfd, isRead) { 95 | /** 96 | * addr_len = sizeof(addr); // this is what's missing 97 | * getpeername(sock_fd, &addr, &addr_len); 98 | * @type {number} 99 | * https://stackoverflow.com/questions/14157187/how-to-get-peer-address-from-openssl-bio-object 100 | * struct sockaddr addr 101 | * sizeof( struct sockaddr ) = 0x10 102 | */ 103 | var strAddrSize = 28; 104 | var addrLenSize = 0x4; 105 | var addr = Memory.alloc(strAddrSize); 106 | var addrlen = Memory.alloc(addrLenSize); 107 | 108 | Memory.writeU32(addrlen, strAddrSize); 109 | 110 | var IPv6 = 10; 111 | var IPv4 = 2; 112 | 113 | /** 114 | * struct sockaddr { 115 | * unsigned short sa_family; 116 | * char sa_data[14]; 117 | * }; 118 | */ 119 | 120 | // struct sockaddr_in6 { 121 | // sa_family_t sin6_family; /* AF_INET6 */ 122 | // in_port_t sin6_port; /* port number */ 123 | // uint32_t sin6_flowinfo; /* IPv6 flow information */ 124 | // struct in6_addr sin6_addr; /* IPv6 address */ 125 | // uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */ 126 | // }; 127 | // 128 | // struct in6_addr { 129 | // unsigned char s6_addr[16]; /* IPv6 address */ 130 | // }; 131 | 132 | // struct sockaddr_in { 133 | // sa_family_t sin_family; /* address family: AF_INET */ 134 | // in_port_t sin_port; /* port in network byte order */ 135 | // struct in_addr sin_addr; /* internet address */ 136 | // }; 137 | // 138 | // /* Internet address. */ 139 | // struct in_addr { 140 | // uint32_t s_addr; /* address in network byte order */ 141 | // }; 142 | 143 | var message = {}; 144 | var src_dst = ["src", "dst"]; 145 | 146 | for (var i = 0; i < src_dst.length; i++) { 147 | if ((src_dst[i] == "src") ^ isRead) { 148 | getsockname(sockfd, addr, addrlen); 149 | } else { 150 | getpeername(sockfd, addr, addrlen); 151 | } 152 | 153 | var addrStr = Memory.alloc(80); 154 | if (Memory.readU16(addr) == IPv6) { 155 | inet_ntop(IPv6, addr.add(8), addrStr, 80); 156 | var port = Memory.readU16(addr.add(2)); 157 | var ipv6 = Memory.readCString(addrStr); 158 | // console.log("ip->" + ipv6 + ", port->" + port); 159 | message["ipVer"] = "IPv6"; 160 | message[src_dst[i] + "_port"] = port; 161 | message[src_dst[i] + "_addr"] = ipv6; 162 | } else if (Memory.readU16(addr) == IPv4) { 163 | inet_ntop(IPv4, addr.add(), addrStr, 80); 164 | var port = Memory.readU16(addr.add(4)); 165 | var ipv4 = Memory.readCString(addrStr); 166 | // console.log("ip->" + ipv4 + ", port->" + port); 167 | message["ipVer"] = "IPv4"; 168 | message[src_dst[i] + "_port"] = port; 169 | message[src_dst[i] + "_addr"] = ipv4; 170 | } 171 | } 172 | 173 | return message; 174 | 175 | } 176 | 177 | function getSSLSessionID(ssl) { 178 | var session = SSL_get_session(ssl); 179 | if (session == 0) { 180 | return 0; 181 | } 182 | var len = Memory.alloc(4); 183 | var p = SSL_SESSION_get_id(session, len); 184 | var len = Memory.readU32(len); 185 | 186 | var session_id = ""; 187 | for (var i = 0; i < len; i++) { 188 | // Read a byte, convert it to a hex string (0xAB ==> "AB"), and append 189 | // it to session_id. 190 | session_id += 191 | ("0" + Memory.readU8(p.add(i)).toString(16).toUpperCase()).substr(-2); 192 | } 193 | 194 | return session_id; 195 | } 196 | 197 | 198 | function hook() { 199 | hook_native(); 200 | } 201 | 202 | 203 | function dump_memory(addr, size) { 204 | var buf = Memory.readByteArray(ptr(addr), size); 205 | console.log(hexdump(buf, { 206 | offset: 0, 207 | length: size, 208 | header: true, 209 | ansi: true 210 | })); 211 | } 212 | 213 | setTimeout(hook, 0); -------------------------------------------------------------------------------- /shell/frida-server-11.0.12-android-arm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sepyeight/Frida_Android_Hook/5352917fea092cbe56c22d34249f1778c0cab42d/shell/frida-server-11.0.12-android-arm -------------------------------------------------------------------------------- /shell/frida-server.bat: -------------------------------------------------------------------------------- 1 | adb forward tcp:27042 tcp:27042 2 | adb forward tcp:27043 tcp:27043 3 | adb push frida-server-11.0.12-android-arm /data/local/tmp/frida-server 4 | adb shell "su -c 'chmod 0777 /data/local/tmp/frida-server'" 5 | adb shell "su -c '/data/local/tmp/frida-server'" 6 | --------------------------------------------------------------------------------