篇幅有限 完整内容及源码关注公众号:ReverseCode,发送 冲 
移动TV npm install –save @types/frida-gum 配置vscode的frida自动代码提示
1 2 3 4 5 6 adb install movetv.apk git clone https://github.com/hluwa/FRIDA-DEXDump.git python main.py  打开app操作一会积分查看视频开始脱壳 cd com.cz.babySister grep -ril "LoginActivity" *  查看该类在那个dex中 frida -UF -l hookEvent.js  点击登录时,触发打印LoginActivity完整路径 
通过jadx-gui 查看com.cz.babySister.activity.LoginActivity的onClick方法
1 2 3 4 5 6 7 8 objection -g com.cz.babySister explore android hooking search classes user   查找和用户相关的类 android hooking search classes person android hooking watch class com.cz.babySister.javabean.UserInfo  查看该类在jadx中哪些地方调用了 plugin load /root/.objection/plugins/Wallbreaker plugin wallbreaker objectsearch com.cz.babySister.javabean.UserInfo  内存搜索UserInfo plugin wallbreaker objectdump --fullname 0x112swa   查看内存中UserInfo信息 android hooking list class_methods com.cz.babySister.javabean.UserInfo 
frida -U -f com.cz.babySister -l jifen.js --no-pause 有壳不能spawn,从登录开始hook
frida -UF -l jifen.js 服务器检测校验了无法查看视频,客户端修改无效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function hook_jifen(){     Java.perform(function(){         var javaString = Java.use("java.lang.String")         Java.use("com.cz.babySister.javabean.UserInfo").setJifen.implementation = function(str) {             var result = this.setJifen(javaString.$new("1000"))             console.log("setJifen is :" ,str)             console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));             return result;         }         Java.use("com.cz.babySister.javabean.UserInfo").setJifen.implementation = function() {             var result = this.getJifen()             console.log("getJifen is :",result)             console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));             return javaString.$new("1000")         }     }) } function main(){     hook_jifen() } setImmediate(main) 
通过console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));打印调用栈,找到最下面的com.cz.babySister.alipay.k.run,查看com.cz.babySister.alipay下的所有类,jadx搜索支付失败
1 2 3 4 5 6 7 8 9 10 11 12 function hook_jifen2(){     Java.perform(function(){         var javaString = Java.use("java.lang.String")         Java.use("com.cz.babySister.alipay.o").b.implementation=function(){             console.log("success")             return javaString.$new("9000")         }     }) } function main(){     hook_jifen2() } 
依旧失败,可能做了支付订单校验。
调用栈中害打印了com.cz.babySister.utils.ParseJson.parseRegisterName,查看com.cz.babySister.utils.ParseJson类,所有内容都是从该类中出现,jadx查看该类的调用处,出现queryJifen
进入a.a方法,a2就是json,所有查询从a.a中返回json,通过objection对该类进行hook,登录时查看调用的方法基本都是a.a
1 2 android hooking watch class com.cz.babySister.c.a --dump-args --dump-return   android hooking watch_method class com.cz.babySister.c.a.a --dump-args --dump-return 
每次看成人台时都会queryJifen判断积分是否不足,不过Return Value是服务器判断了积分是否充足,充足才返回可以看的地址,没有逻辑漏洞了。
搜索memi1的来源
1 2 android hooking watch class_method android.content.Context.getString --dump-args --dump-return android hooking watch class_method android.content.Context.getText --dump-args --dump-return 
context在app启动后立即生成且销毁,因为有壳的原因,无法hook,只有一次捕捉机会
1 2 3 4 android hooking watch class android.provider.Settings$Secure --dump-args --dump-return  每次context实时获取的 android hooking watch class_method android.provider.Settings$Secure.getString  --dump-args --dump-return --dump-backtrace plugin wallbreaker objectsearch android.app.ContextImpl$ApplicationContentResolver plugin wallbreaker objectdump --fullname 0x2502 
记一次frida实战——对某视频APP的脱壳、hook破解、模拟抓包、协议分析一条龙服务 
fulao2 adb install -r fulao2.apk
1 2 3 4 5 6 7 8 9 10 11 ./fs128arm64 frida -UF -l hookSocket.js -o /root/Desktop/img.txt  启动app后开始抓包,GET到的地址结合域名发现图片是被加密的 objection -g com.ilulutv.fulao2 explore -P ~/.objection/plugins android hooking search classes imageView plugin wallbreaker objectsearch android.widget.ImageView  查看内存中的对象 plugin wallbreaker objectdump --fullname 0x20212  打印内存对象属性内容 android hooking search classes Bitmap  把所有Bitmap相关的类拷贝到文件bitmap.txt中,前面加上android hooking watch class plugin wallbreaker objectdump --fullname 0x2045   查看内存Bitmap属性,即图片属性 objection -g com.ilulutv.fulao2 explore -c bitmap.txt  批量hook,如果app崩了查看最后一个hook的类,在文件中删除重新挂上objection android hooking watch class_method android.graphics.BitmapFactory.decodeStream --dump-args --dump-backtrace --dump-return  下拉加载图片,堆栈中加载了glide图片加载库 android hooking watch class_method android.graphics.BitmapFactory.decodeByteArray --dump-args --dump-backtrace --dump-return   堆栈中打印了业务代码com.ilulutv.fulao2.other.helper.glide.b.a 
jadx打开fulao2,搜索com.ilulutv.fulao2.other.helper.glide.b类的a方法
1 android hooking list class_methods android.graphics.BigmapFactory 查看decodeByteArray返回值 
其中byte[] c2 = com.ilulutv.fulao2.other.i.b.c(decode, Base64.decode(bytes2, 0), encodeToString);解密
hook网络流打印下载图片内容 
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 function hookRAW(){     Java.perform(function(){         console.log("hooking RAW...")         Java.use("com.ilulutv.fulao2.other.i.b").a.overload('java.nio.ByteBuffer').implementation = function(bytebuffer){             var result =  this.a(bytebuffer)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("result is => ",ByteString.of(result).hex())             return result         }     })      } function hook_SSLsocketandroid8(){     Java.perform(function(){         console.log("hook_SSLsocket")         // concrypt本质对libssl.so进行操作         Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream").write.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){             var result = this.write(bytearry,int1,int2);             console.log("HTTPS write result,bytearry,int1,int2=>",result,bytearry,int1,int2)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("bytearray contents=>", ByteString.of(bytearry).hex())             //console.log(jhexdump(bytearry,int1,int2));             // console.log(jhexdump(bytearry));             return result;         }                           Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream").read.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){             var result = this.read(bytearry,int1,int2);             console.log("HTTPS read result,bytearry,int1,int2=>",result,bytearry,int1,int2)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("bytearray contents=>", ByteString.of(bytearry).hex())             //console.log(jhexdump(bytearry,int1,int2));             // console.log(jhexdump(bytearry));             return result;         }              }) } function main(){     hookRAW()     hook_SSLsocketandroid8() } setImmediate(main) 
frida -UF -l fulao2.js -o hookRAW.txt 下拉内容查看log图片,对比抓包hook_SSLsocketandroid8结果和hookRAW结果的内容是否一致,说明com.ilulutv.fulao2.other.i.b.a((ByteBuffer) obj)确实是要加密的内容,明文在com.ilulutv.fulao2.other.i.b.b(decode, Base64.decode(bytes2, 0), encodeToString)
根据return com.bumptech.glide.load.q.d.e.a(BitmapFactory.decodeByteArray(b2, 0, b2.length), this.f11769a);,hook系统库查看解密后图片内容
1 2 3 4 5 6 7 8 9 10 11 function hookClean(){     Java.perform(function(){         // hook 系统库 不会被混淆 ,图片文件头jpeg都是ffd8ff         Java.use("android.graphics.BigmapFactory").decodeByteArray.overload('[B','int','int','android.graphics.BitmapFactory$Options').implementation = function (ba,int1,int2,op){             var result = this.decodeByteArray(ba,in1,int2,op)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("ba is=>",ByteString.of(ba).hex())             return result;         }     }) } 
byte下载图片,frida -UF -l fulao2.js -o hookRAW.txt 下拉加载图片 
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 function guid() {     function S4() {       return (((1+Math.random())*0x10000)|0).toString(16).substring(1);     }     return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());   } function hookClean(){     Java.perform(function(){         // hook 系统库 不会被混淆 ,图片文件头jpeg都是ffd8ff         Java.use("android.graphics.BigmapFactory").decodeByteArray.overload('[B','int','int','android.graphics.BitmapFactory$Options').implementation = function (ba,int1,int2,op){             var result = this.decodeByteArray(ba,in1,int2,op)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("ba is=>",ByteString.of(ba).hex())             var path = "/sdcard/Download/tmp/"+guid()+".jpg"             console.log("path=> ",path)             // android hooking search classes File             var file = Java.use("java.io.File").$new(path)             // android hooking search classes FileOutputStream             var fos = Java.use("java.io.FileOutputStream").$new(file);             fos.write(data);             fos.close();             fos.close();             return result;         }     }) } 
根据正常图片访问方式,利用安卓api,通过Bigmap对象压缩到文件输出流 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function hookClean(){     Java.perform(function(){         // hook 系统库 不会被混淆 ,图片文件头jpeg都是ffd8ff         Java.use("android.graphics.BigmapFactory").decodeByteArray.overload('[B','int','int','android.graphics.BitmapFactory$Options').implementation = function (ba,int1,int2,op){             var result = this.decodeByteArray(ba,in1,int2,op)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("ba is=>",ByteString.of(ba).hex())             var path = "/sdcard/Download/tmp/"+guid()+".jpg"             console.log("path=> ",path)             // android hooking search classes File             var file = Java.use("java.io.File").$new(path)             // android hooking search classes FileOutputStream             var fos = Java.use("java.io.FileOutputStream").$new(file);             // android hooking list class_methods android.graphics.Bitmap 查看compress实例方法             result.compress(Java.use("android.graphics.Bitmap$CompressFormat").JPEG.value,100,fos)             // fos.write(data);             fos.close();             fos.close();             return result;         }     }) } 
compress占用主线程资源,阻塞主线程导致程序崩溃,可以另起线程专门用来下载图片 
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 function hookImage() {     Java.perform(function () {         var Runnable = Java.use("java.lang.Runnable");         var saveImg = Java.registerClass({             name: "com.roysue.runnable",             implements: [Runnable],             fields: {                 bm: "android.graphics.Bitmap",             },             methods: {                 $init: [{                     returnType: "void",                     argumentTypes: ["android.graphics.Bitmap"],                     implementation: function (bitmap) {                         this.bm.value = bitmap;                     }                 }],                 run: function () {                     var path = "/sdcard/Download/tmp/" + guid() + ".jpg"                     console.log("path=> ", path)                     var file = Java.use("java.io.File").$new(path)                     var fos = Java.use("java.io.FileOutputStream").$new(file);                     this.bm.value.compress(Java.use("android.graphics.Bitmap$CompressFormat").JPEG.value, 100, fos)                     console.log("success!")                     fos.flush();                     fos.close();                 }             }         });         Java.use("android.graphics.BitmapFactory").decodeByteArray.overload('[B', 'int', 'int', 'android.graphics.BitmapFactory$Options').implementation = function (data, offset, length, opts) {             var result = this.decodeByteArray(data, offset, length, opts);             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             var runnable = saveImg.$new(result);             runnable.run()             return result;         }     }) } 
不建议多线程在手机端运行,可以将线程发送PC端执行 
fulao2.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 function hookImage() {     Java.perform(function () {         var Runnable = Java.use("java.lang.Runnable");         var saveImg = Java.registerClass({             name: "com.roysue.runnable",             implements: [Runnable],             fields: {                 bm: "android.graphics.Bitmap",             },             methods: {                 $init: [{                     returnType: "void",                     argumentTypes: ["android.graphics.Bitmap"],                     implementation: function (bitmap) {                         this.bm.value = bitmap;                     }                 }],                 run: function () {                     var path = "/sdcard/Download/tmp/" + guid() + ".jpg"                     console.log("path=> ", path)                     var file = Java.use("java.io.File").$new(path)                     var fos = Java.use("java.io.FileOutputStream").$new(file);                     this.bm.value.compress(Java.use("android.graphics.Bitmap$CompressFormat").JPEG.value, 100, fos)                     console.log("success!")                     fos.flush();                     fos.close();                 }             }         });         Java.use("android.graphics.BitmapFactory").decodeByteArray.overload('[B', 'int', 'int', 'android.graphics.BitmapFactory$Options').implementation = function (data, offset, length, opts) {             var result = this.decodeByteArray(data, offset, length, opts);             send(data)             return result;         }     }) } function main(){     hookImage() } setImmediate(main) 
fulao2.py
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 import frida import json import time import uuid import base64 import re    def my_message_handler(message, payload):     print(message)     print(payload)     if message["type"] == "send":         #image = re.findall("(-?\d+)", message["payload"])         image = message["payload"]         print(image) 		# 保存image         intArr = []         # 位数的转换         for m in image:             ival = int(m)             if ival < 0:                 ival += 256             intArr.append(ival)         bs = bytes(intArr)         fileName = str(uuid.uuid1()) + ".jpg"         f = open(fileName, 'wb')         f.write(bs)         f.close() device = frida.get_usb_device() target = device.get_frontmost_application() session = device.attach(target.pid) # 加载脚本 with open("fulao2.js") as f:     script = session.create_script(f.read()) script.on("message", my_message_handler)  # 调用错误处理 script.load() # 脚本会持续运行等待输入 input() 
接下来尝试从抓到的包中解密协议,获取解密后的图片在hookRAW中实现脱机 
fulao2.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function hookRAW(){     Java.perform(function(){         console.log("hooking RAW...")         Java.use("com.ilulutv.fulao2.other.i.b").a.overload('java.nio.ByteBuffer').implementation = function(bytebuffer){             var result =  this.a(bytebuffer)             var ByteString = Java.use("com.android.okhttp.okio.ByteString");             console.log("result is => ",ByteString.of(result).hex())             send(result)             return result         }     })      } function main(){     hookRAW() } setImmediate(main) 
fulao2.py中image = message["payload"]需要解密,进入decodeImageKey实现
进入CipherCore
发现从so库中加载的加密协议
1 2 memory list modules  找到libcipher-lib.so memory list exports libcipher-lib.so  搜索getString 分析拿到byte之后通过base64加密 
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 import frida import json import time import uuid import base64 import re from Crypto.Cipher import AES import base64 def IMGdecrypt(bytearray):     # hook String decodeImgKey = CipherClient.decodeImgKey();     imgkey = base64.decodebytes(         bytes("svOEKGb5WD0ezmHE4FXCVQ==", encoding='utf8'))          imgiv = base64.decodebytes(         bytes("4B7eYzHTevzHvgVZfWVNIg==", encoding='utf8'))          cipher = AES.new(imgkey, AES.MODE_CBC, imgiv)     # enStr += (len(enStr) % 4)*"="     # decryptByts = base64.urlsafe_b64decode(enStr)     msg = cipher.decrypt(bytearray)     def unpad(s): return s[0:-s[-1]]     return unpad(msg) def my_message_handler(message, payload):     print(message)     print(payload)     if message["type"] == "send":         #image = re.findall("(-?\d+)", message["payload"])         image = message["payload"]         print(image)         intArr = []         # 位数的转换         for m in image:             ival = int(m)             if ival < 0:                 ival += 256             intArr.append(ival)         bs = bytes(intArr)         # 拿到数据后Base64解密         bs = IMGdecrypt(bs)         fileName = str(uuid.uuid1()) + ".jpg"         f = open(fileName, 'wb')         f.write(bs)         f.close() device = frida.get_usb_device() target = device.get_frontmost_application() session = device.attach(target.pid) # 加载脚本 with open("fulao2.js") as f:     script = session.create_script(f.read()) script.on("message", my_message_handler)  # 调用错误处理 script.load() # 脚本会持续运行等待输入 input() 
VIP破解 
切换高清视频,提示vip限定功能,无法切换vip,尝试hook按钮点击事件,frida -UF -l hookEvent.js,点击切换清晰度
jadx搜索com.ilulutv.fulao2.film.l.t
1 2 plugin wallbreaker objectsearch com.ilulutv.fulao2.film.l$t plugin wallbreaker objectdump --fullname 0x2a76 
1 2 plugin wallbreaker objectdump --fullname 0x28f2   查看在看视频实例 android heap search instances com.ilulutv.fulao2.film.l 
尝试将this.f11151d.q0改为true,完成VIP功能中的清晰度切换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function hookVIP(){     Java.perform(function(){         Java.choose("com.ilulutv.fulao2.film.l",{             onMatch:function(ins){                 console.log("found ins:=>",ins)                 ins.q0.value=true;             },onComplete:function(){                 console.log("search complete")             }         })     }) } function main(){     hookVIP() } setInterval(main,500) 
抓取所有收发包
frida -U -f com.ilulutv.fulao2 -l hookSocket.js -o traffic.txt 所有通信都是加密了,不是在https层加密,而是在业务层,那就尝试hook所有的cipher
objection -g com.ilulutv.fulao2 explore -c cipher.txt
1 2 3 android hooking watch class com.cz.babySister.c.a   android hooking watch class_method javax.crypto.Cipher.init  --dump-args --dump-return --dump-backtrace android hooking list class_methods com.ilulutv.fulao2.other.i.b  将所有的方法复制到ciph.txt中,前面添加上android hooking watch class_method,后面添加--dump-args --dump-return --dump-backtrace 
objection -g com.ilulutv.fulao2 explore -c cipher.txt 关闭app重新hook,打印出所有的通信内容包括加解密所有内容
查看com.ilulutv.fulao2.other.i.b.a ,改包将其中的vip改为true,expire修改过期时间
当所有业务返回都被加解密了,可以尝试hook系统库,不可被混淆加密
第一题.apk jadx-gui 第一题.apk
1 2 3 objection -g com.kanxue.pediy1 explore android hooking search classes com.kanxue.pediy1 android hooking watch classe com.kanxue.pediy1.VVVV 
frida -UF -l question.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 var CONTEXT = null; // 获取类名 function getObjClassName(obj) {     if (!jclazz) {         var jclazz = Java.use("java.lang.Class");     }     if (!jobj) {         var jobj = Java.use("java.lang.Object");     }     return jclazz.getName.call(jobj.getClass.call(obj)); } function hookReturn() {     Java.perform(function () {         Java.use("com.kanxue.pediy1.VVVVV").VVVV.implementation = function (context, str) {             var result = this.VVVV(context, str)             console.log("context,str,result => ", context, str, result);             console.log("context className is => ", getObjClassName(context));             CONTEXT = context;             return true;         }     }) } function invoke() {     Java.perform(function () {         //console.log("CONTEXT IS => ",CONTEXT)         var MainActivity = null;         Java.choose("com.kanxue.pediy1.MainActivity", {             onMatch: function (instance) {                 MainActivity = instance;             },             onComplete: function () { }         })         var CONTEXT2 = Java.use("com.kanxue.pediy1.MainActivity$1").$new(MainActivity);         var javaString = Java.use("java.lang.String").$new("12345");         for (var x = 0; x < (99999 + 1); x++) {         	// 静态函数VVVV 使用use直接调用             var result = Java.use("com.kanxue.pediy1.VVVVV").VVVV(CONTEXT2, String(x));             console.log("now x is => ", String(x))             if (result) {                 console.log("found result is => ", String(x))                 break;             }         }     }) } function main() {     hookReturn()     invoke() } setImmediate(main) 
主动调用的参数构造两种方案:
1 2 cd ~/.pyenv tree -NCfhl | grep agent.js   加上构造函数hook,如com.kanxue.pediy1.MainActivity$1 
第二题.apk jadx-gui 第二题.apk
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 function invoke2() {     Java.perform(function () {         // console.log("CONTEXT IS => ",CONTEXT)         var MainActivity = null;         Java.choose("com.kanxue.pediy1.MainActivity",{             onMatch:function(instance){                 MainActivity = instance;             },             onComplete:function(){}         })         // var CONTEXT2 = Java.use("com.kanxue.pediy1.MainActivity$1").$new(MainActivity);         var loader1 = null;         var loader2 = null;         Java.enumerateClassLoaders({             onMatch: function (loader) {                 try {                     if (loader.findClass("com.kanxue.pediy1.VVVVV")) {                         console.log("Successfully found loader")                         console.log(loader); 						// 切换classLoader                         loader2 = loader;                         Java.classFactory.loader = loader2;                     }else if(loader.findClass("com.kanxue.pediy1.MainActivity")){                         console.log("Successfully found loader")                         console.log(loader);                         loader1 = loader;                     }else{                     }                 }                 catch (error) {                     console.log("find error:" + error)                 }             },             onComplete: function () {                 console.log("end1")             }         })           var javaString = Java.use("java.lang.String").$new("12345");         for (var x = 0; x < (99999 + 1); x++) {             var result1 = MainActivity.stringFromJNI(String(100000 - x));             var result2 = Java.use("com.kanxue.pediy1.VVVVV").VVVV(String(result1));                       console.log("now x is => ", String(x))             if (result2) {                 console.log("found result2 is => ", String(100000 - x))                 break;             }         }     }) } 
frida -UF -l traceNativelibssl.js 拿到函数_ZTVNST3__19strstreamE ,修改if(exports[j].name.indexOf("ZTVNSt3")>=0){,if(exports[j].name.indexOf("ZTVNSt3")>=0){,
举杯邀Frida,对影成三题 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 // hook native函数,使其不要执行,Interceptor.replace function hookSTRSTR() {     var kill_addr = Module.findExportByName("libc.so", "strcmp");     Interceptor.attach(strstr, {         onEnter: function (args) {             console.log("Entering =>")             console.log("args[0] => ", args[0].readCString())             console.log("args[1] => ", args[1].readCString())         },         onLeave: function (retval) {         }     } )} function replaceKill(){     var kill_addr = Module.findExportByName("libc.so", "kill");     // var kill = new NativeFunction(kill_addr,"int",['int','int']);     Interceptor.replace(kill_addr,new NativeCallback(function(arg0,arg1){         console.log("arg0=> ",arg0)         console.log("arg1=> ",arg1)     },"int",['int','int'])) }