FridaHook大全

Mobile-Security-Framework-MobSF

记一次frida实战——对某视频APP的脱壳、hook破解、模拟抓包、协议分析一条龙服务

安卓 App 逆向课程之三 frida 注入 Okhttp 抓包上篇

安卓 App 逆向课程之四 frida 注入 Okhttp 抓包中篇

安卓 App 逆向课程之五 frida 注入 Okhttp 抓包下篇

XPOSED魔改一:获取特征

【SO壳】17种安卓native反调试收集

  1. 遍历连接手机所有端口发送D-bus消息,如果返回”REJECT”这个特征则认为存在frida-server
  2. 直接调用openatsyscall的检测在text节表中搜索frida-gadget*.so / frida-agent*.so字符串,避免了hook libc来anti-anti的方法。**frida-detection**
  3. 内存中存在frida rpc字符串,认为有frida-server,**AntiFrida**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
function hook_java(){
Java.perform(function(){
// 静态函数的hook和主动调用
Java.use("com.example.demoso1.MainActivity").stringFromJNI.implementation = function (){
var result = this.stringFromJNI();
console.log("result is => ",result);
return result;
}
//console.log("invoke stringFromJNI : => "+Java.use("com.example.demoso1.MainActivity").stringFromJNI() );
// 动态注册的函数
Java.use("com.example.demoso1.MainActivity").stringFromJNI2.implementation = function (){
var result = this.stringFromJNI2();
console.log("result is => ",result);
return result;
}
//console.log("invoke stringFromJNI2 : => "+Java.use("com.example.demoso1.MainActivity").stringFromJNI2() );

Java.use("com.example.demoso1.MainActivity").myfirstjniJNI("JSstring")
// 动态函数的hook
Java.use("com.example.demoso1.MainActivity").init.implementation = function(){
console.log("hook init successfully!")
return this.init();
}
/*
// 动态函数的主动调用
Java.choose("com.example.demoso1.MainActivity",{
onMatch:function(instance){
console.log("Found instance!");
instance.init();
},onComplete:function(){console.log("Search complete!")}
})
*/
})
}
// memory list modules
// memory list exports libnaive-lib.so
function hook_nativelib(){
var native_lib_addr = Module.findBaseAddress("libnative-lib.so");
console.log("native_lib_addr => ",native_lib_addr);

var myfirstjniJNI = Module.findExportByName("libnative-lib.so", "Java_com_example_demoso1_MainActivity_myfirstjniJNI");
console.log("myfirstjniJNI addr => ",myfirstjniJNI);

var myfirstjniJNI_invoke = new NativeFunction(myfirstjniJNI,"pointer",["pointer","pointer","pointer"])

Interceptor.attach(myfirstjniJNI,{
onEnter:function(args){
console.log("Interceptor.attach myfirstjniJNI args:",args[0],args[1],args[2]);
console.log("args2 jstring is ",Java.vm.getEnv().getStringUtfChars( args[2],null).readCString())

console.log("myfirstjniJNI_invoke result => ",myfirstjniJNI_invoke(args[0],args[1],args[2]))

var newArgs2 = Java.vm.getEnv().newStringUtf("new args2 from frida");
args[2] = newArgs2;

},onLeave:function(retval){
console.log("Interceptor.attach myfirstjniJNI retval => ",retval)
console.log("retval jstring is ",Java.vm.getEnv().getStringUtfChars( retval,null).readCString())
var newRetval = Java.vm.getEnv().newStringUtf("new Retval from frida"); // jstring
retval.replace(newRetval);
}
})
}
// hook和主动调用native函数
function hookandinvoke_add(){
var native_lib_addr = Module.findBaseAddress("libnative-lib.so");
console.log("native_lib_addr => ",native_lib_addr);

var r0add_addr = Module.findExportByName("libnative-lib.so", "_Z5r0addii");
console.log("r0add addr => ",r0add_addr);
// 附加
Interceptor.attach(r0add_addr,{
onEnter:function(args){
console.log("x=>",args[0]," y=>",args[1]);
// 打印调用栈
console.log('CCCryptorCreate called from:\n' +
Thread.backtrace(this.context, Backtracer.FUZZY)
.map(DebugSymbol.fromAddress).join('\n') + '\n');
},onLeave:function(retval){
console.log("retval is => ",retval);
}
})

var r0add = new NativeFunction(r0add_addr,"int",["int","int"]);
var r0add_result = r0add(50,1);
console.log("invoke result is => ",r0add_result);
}

function hook_replace(){
var native_lib_addr = Module.findBaseAddress("libnative-lib.so");
console.log("native_lib_addr => ",native_lib_addr);

var myfirstjniJNI = Module.findExportByName("libnative-lib.so", "Java_com_example_demoso1_MainActivity_myfirstjniJNI");
console.log("myfirstjniJNI addr => ",myfirstjniJNI);

var myfirstjniJNI_invoke = new NativeFunction(myfirstjniJNI,"pointer",["pointer","pointer","pointer"])
// 替换
Interceptor.replace(myfirstjniJNI,new NativeCallback(function(args0,args1,args2){
console.log("Interceptor.replace myfirstjniJNI args:",args0,args1,args2);
//var result = myfirstjniJNI_invoke(args0,args1,args2)
return Java.vm.getEnv().newStringUtf("new Retval from frida");;
},"pointer",["pointer","pointer","pointer"]))
}
// 枚举所有符号
function EnumerateAllExports(){
var modules = Process.enumerateModules();
//console.log("Process.enumerateModules => ",JSON.stringify(modules))
for(var i=0;i<modules.length;i++){
var module = modules[i];
var module_name = modules[i].name;
var exports = module.enumerateExports();
console.log("module_name=>",module_name," module.enumerateExports = > ",JSON.stringify(exports))
}
}

ProcessModuleMemoryThread

1
2
3
4
5
6
7
8
9
function MODULE(){
var native_lib_addr = Process.findModuleByAddress(Module.findBaseAddress("linker64"));
console.log("native_lib_addr => ",JSON.stringify(native_lib_addr));
console.log("enumerateImports=>",JSON.stringify(native_lib_addr.enumerateSymbols()))
console.log("enumerateImports=>",JSON.stringify(native_lib_addr.enumerateExports()))
console.log("enumerateImports=>",JSON.stringify(native_lib_addr.enumerateImports()))

}
setImmediate(MODULE)

jni 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

function EnumerateAllExports(){
var modules = Process.enumerateModules();
//console.log("Process.enumerateModules => ",JSON.stringify(modules))
for(var i=0;i<modules.length;i++){
var module = modules[i];
var module_name = modules[i].name;
var exports = module.enumerateExports();
console.log("module_name=>",module_name," module.enumerateExports = > ",JSON.stringify(exports))
}
}

// memory list exports libart.so http://demangler.com/ 获取符号对应的函数
function hook_JNI(){

var GetStringUTFChars_addr = null;
var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
//console.log(JSON.stringify(symbols))
for(var i = 0;i<symbols.length;i++){
var symbol = symbols[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
if(symbol.indexOf("GetStringUTFChars")>=0){
console.log("finally found GetStringUTFChars name :",symbol);
GetStringUTFChars_addr =symbols[i].address ;
console.log("finally found GetStringUTFChars address :",GetStringUTFChars_addr);
}
}
}
Interceptor.attach(GetStringUTFChars_addr,{
onEnter:function(args){
console.log("art::JNI::GetStringUTFChars(_JNIEnv*, _jstring*, unsigned char*)=>",args[0],Java.vm.getEnv().getStringUtfChars( args[1],null).readCString(),args[2]);
// console.log('CCCryptorCreate called from:\n' +
// Thread.backtrace(this.context, Backtracer.ACCURATE) //Backtracer.FUZZY
// .map(DebugSymbol.fromAddress).join('\n') + '\n');
},onLeave:function(retval){
console.log("retval is => ",retval.readCString());
}
})
}

function replace_JNI(){
var NewStringUTF_addr = null;
var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
//console.log(JSON.stringify(symbols))
for(var i = 0;i<symbols.length;i++){
var symbol = symbols[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
if(symbol.indexOf("NewStringUTF")>=0){
console.log("finally found NewStringUTF_name :",symbol); // 函数名
NewStringUTF_addr =symbols[i].address ;
console.log("finally found NewStringUTF_addr :",NewStringUTF_addr); // 函数地址
}
}
}
var NewStringUTF = new NativeFunction(NewStringUTF_addr,"pointer",["pointer","pointer"])
Interceptor.replace(NewStringUTF_addr,
new NativeCallback(function(parg1,parg2){
console.log("parg1,parg2=>",parg1,parg2.readCString());
// console.log('CCCryptorCreate called from:\n' +
// Thread.backtrace(this.context, Backtracer.ACCURATE)
// .map(DebugSymbol.fromAddress).join('\n') + '\n');
var newPARG2 = Memory.allocUtf8String("newPARG2")
var result = NewStringUTF(parg1,newPARG2);
return result;
},"pointer",
["pointer","pointer"]))
}

function hook_RegisterNatives(){
var RegisterNatives_addr = null;
var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
//console.log(JSON.stringify(symbols))
for(var i = 0;i<symbols.length;i++){
var symbol = symbols[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
if(symbol.indexOf("RegisterNatives")>=0){
console.log("finally found RegisterNatives_name :",symbol);
RegisterNatives_addr =symbols[i].address ;
console.log("finally found RegisterNatives_addr :",RegisterNatives_addr);
}
}
}

if(RegisterNatives_addr!=null){
Interceptor.attach(RegisterNatives_addr,{
onEnter:function(args){
console.log("[RegisterNatives]method counts :",args[3]);
var env = args[0];
var jclass = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(jclass);
var methods_ptr = ptr(args[2]);
var method_count = parseInt(args[3]);
for (var i = 0; i < method_count; i++) {
var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
var name = Memory.readCString(name_ptr);
var sig = Memory.readCString(sig_ptr);
var find_module = Process.findModuleByAddress(fnPtr_ptr);
console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
}
},onLeave:function(retval){
}
})

}else{
console.log("didn`t found RegisterNatives address")
}

}

setImmediate(hook_RegisterNatives);

libc 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
function beginAnti(){
Java.perform(function(){
Java.choose("com.example.demoso1.MainActivity",{
onMatch:function(instance){
console.log("Found instance!");
instance.init(); // 触发反调试
},onComplete:function(){console.log("Search complete!")}
})
})
}

function hook_pthread(){

var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
// var symbols = Process.findModuleByName("libc.so").enumerateSymbols()
var time_addr = Module.findExportByName("libc.so", "time"); // 随意指定一个函数
console.log("pthread_create_addr=>",pthread_create_addr)

Interceptor.attach(pthread_create_addr,{
onEnter:function(args){
console.log("args=>",args[0],args[1],args[2],args[4])
var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
if(libnativebaseaddress!=null){
console.log("libnativebaseaddress=>",libnativebaseaddress);
//var detect_frida_loop_addr = args[2]-libnativebaseaddress;
//console.log("detect_frida_loop offset is =>",detect_frida_loop_addr) 偏移64900
if(args[2]-libnativebaseaddress == 64900){
console.log("found anti frida loop!,excute time_addr=>",time_addr);
args[2]=time_addr;
}
}
},onLeave:function(retval){
console.log("retval is =>",retval)
}
})
}

function replace_pthread(){
var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
console.log("pthread_create_addr=>",pthread_create_addr)
var pthread_create = new NativeFunction(pthread_create_addr,"int",["pointer","pointer","pointer","pointer"])
Interceptor.replace(pthread_create_addr,
new NativeCallback(function(parg1,parg2,parg3,parg4){
console.log(parg1,parg2,parg3,parg4)
var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
if(libnativebaseaddress!=null){
console.log("libnativebaseaddress=>",libnativebaseaddress);
if(parg3-libnativebaseaddress == 64900){
return null;
}
}
return pthread_create(parg1,parg2,parg3,parg4)
},"int",["pointer","pointer","pointer","pointer"]))
}

function writeSomething(path,contents){
var fopen_addr = Module.findExportByName("libc.so", "fopen");
var fputs_addr = Module.findExportByName("libc.so", "fputs");
var fclose_addr = Module.findExportByName("libc.so", "fclose");

//console.log("fopen=>",fopen_addr," fputs=>",fputs_addr," fclose=>",fclose_addr);

var fopen = new NativeFunction(fopen_addr,"pointer",["pointer","pointer"])
var fputs = new NativeFunction(fputs_addr,"int",["pointer","pointer"])
var fclose = new NativeFunction(fclose_addr,"int",["pointer"])

console.log(path,contents)

var fileName = Memory.allocUtf8String(path);
var mode = Memory.allocUtf8String("a+");

var fp = fopen(fileName,mode);

var contentHello = Memory.allocUtf8String(contents);
var ret = fputs(contentHello,fp)

fclose(fp);
}

function EnumerateAllExports(){
/*

var packageName = null
Java.perform(function(){
packageName = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext().getPackageName();
console.log("package name is :",packageName)
})
if(!packageName){
console.log("can`t get package name ,quitting .")
return null;
}
*/

var modules = Process.enumerateModules();
//console.log("Process.enumerateModules => ",JSON.stringify(modules))
for(var i=0;i<modules.length;i++){
var module = modules[i];
var module_name = modules[i].name;
//var exports = module.enumerateExports();
var exports = module.enumerateSymbols();
console.log("module_name=>",module_name," module.enumerateExports = > ",JSON.stringify(exports))
for(var m =0; m<exports.length;m++){
console.log("m=>",m)
//writeSomething("/sdcard/"+packageName+"/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
writeSomething("/sdcard/settings/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
}

}
}


setImmediate(EnumerateAllExports)

linker hook

在Android so文件的.init、.init_array上和JNI_OnLoad处下断点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//应用以32位在64位终端环境下运行
//adb install --abi armeabi-v7a <path to apk>

function hook_pthread() {

var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
var time_addr = Module.findExportByName("libc.so", "time");
console.log("pthread_create_addr=>", pthread_create_addr)

Interceptor.attach(pthread_create_addr, {
onEnter: function (args) {
console.log("args=>", args[0], args[1], args[2], args[4])
var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
if (libnativebaseaddress != null) {
console.log("libnativebaseaddress=>", libnativebaseaddress);
//var detect_frida_loop_addr = args[2]-libnativebaseaddress;
//console.log("detect_frida_loop offset is =>",detect_frida_loop_addr)
if (args[2] - libnativebaseaddress == 0x95c9) {
console.log("found anti frida loop!,excute time_addr=>", time_addr);
args[2] = time_addr;
}
}
}, onLeave: function (retval) {
console.log("retval is =>", retval)
}
})
}
function EnumerateAllExports() {

var linker = Process.getModuleByName("linker")
//console.log("exports=>",JSON.stringify(linker.enumerateSymbols()))
var call_function_addr = null;
var exports = linker.enumerateSymbols();
//console.log("module_name=>",module_name," module.enumerateExports = > ",JSON.stringify(exports))
for (var m = 0; m < exports.length; m++) {
//console.log("m=>",m)
//writeSomething("/sdcard/"+packageName+"/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
//writeSomething("/sdcard/settings/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
if (exports[m].name == "__dl__ZL13call_functionPKcPFviPPcS2_ES0_") { // 用demangler查看函数
call_function_addr = exports[m].address;
console.log("found call_function_addr => ", call_function_addr)
hook_call_function(call_function_addr)
}
}
/*
__dl__ZL13call_functionPKcPFvvES0_
__dl_call_function(char const*, void (*)(), char const*)


__dl__ZL13call_functionPKcPFviPPcS2_ES0_
__dl_call_function(char const*, void (*)(int, char**, char**), char const*)
*/

}

function hook_call_function(_call_function_addr){
console.log("hook call function begin!hooking address :=>",_call_function_addr)
Interceptor.attach(_call_function_addr,{
onEnter:function(args){
if(args[2].readCString().indexOf("base.odex")<0){ // 过滤
console.log("function_name : agrs[0]=>",args[0].readCString())
console.log("so path : agrs[2]=>",args[2].readCString())
console.log("function offset : args[1]=>","0x"+(args[1]-Module.findBaseAddress("libnative-lib.so")).toString(16))

}
},onLeave:function(retval){

}
})
}

setImmediate(EnumerateAllExports)

boringssl证书

方案1: frida替换校验证书时回调函数的返回值,修改为枚举变量ssl_verify_ok的值0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// so加载之后立马hook
function todoOndlopen(libraryName, fn) {
return new Promise((resolve, reject) => {
var exportName = Java.androidVersion >= 8.1 ? 'android_dlopen_ext' : 'dlopen';
var dlopen_ptr = Module.findExportByName(null, exportName);
if (dlopen_ptr) {
Interceptor.attach(dlopen_ptr, {
onEnter: function (args) {
var libPath = args[0].readCString();
if (libPath.indexOf(libraryName) != -1) {
console.log(`libraryPath: ${libPath}`);
this.hook = true
}
},
onLeave: function (retVal) {
if (this.hook) {
console.log('hooking')
resolve(fn());
}
}
})
} else {
reject(exportName + ' not found')
}
})
}

// enum ssl_verify_result_t BORINGSSL_ENUM_INT {
// ssl_verify_ok, 0
// ssl_verify_invalid, 1
// ssl_verify_retry, 2
// };
// 修改为枚举变量ssl_verify_ok的值0
function replaceCallback(pcustom_verify_callback){
Interceptor.attach(pcustom_verify_callback, {
onLeave(retval){
if (retval != 0){
console.log("custom_verify_callback retval: ", retval)
console.log('custom_verify_callback retval replace with 0x0');
retval.replace(ptr('0x0'))
}
}
})
}

//void SSL_CTX_set_custom_verify(
// SSL_CTX *ctx, int mode,
// enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) {
// ctx->verify_mode = mode;
// ctx->custom_verify_callback = callback;
// }
// 替换校验证书时回调函数的返回值
function anti_ssl_verify(){
const libraryName = 'libsscronet.so';
return todoOndlopen(libraryName, ()=>{
const pSSL_CTX_set_custom_verify = Module.findExportByName('libttboringssl.so', 'SSL_CTX_set_custom_verify');
var SSL_CTX_set_custom_verify = new NativeFunction(pSSL_CTX_set_custom_verify, 'pointer', ['pointer', 'int', 'pointer']);
Interceptor.replace(pSSL_CTX_set_custom_verify, new NativeCallback((ctx, verify_mode, pcustom_verify_callback)=>{
console.log(`SSL_CTX_set_custom_verify be called, ctx: ${ctx}, verify_mode: ${verify_mode}, pcustom_verify_callback=${pcustom_verify_callback}`);
replaceCallback(pcustom_verify_callback)
return SSL_CTX_set_custom_verify(ctx, verify_mode, pcustom_verify_callback);
}, 'pointer',['pointer', 'int', 'pointer']))

})
}

function main(){
anti_ssl_verify();
}

setImmediate(main)

方案2:记录所有回调函数的地址,获取函数所在模块和偏移,然后在ida中patch返回值,然后推送到存放app动态库的目录下面

1
2
3
4
5
6
7
8
9
10
function getModuleByAddr(addr) {
var result = null;
Process.enumerateModules().forEach(function (module) {
if (module.base <= addr && addr <= (module.base.add(module.size))) {
result = JSON.stringify(module);
return false; // 跳出循环
}
});
return result;
}

IDA打开libsscronet.so(抖音)

image-20221018225632072

image-20221018230542414

N修改sub_1CCB20为VerifyCallback,在VerifyCallBack函数中最终return sub_1CCD58(v3)就是函数返回的位置。

image-20221018231837186

找到j_ret的引用处,设置Options-General的opcode字节长度为4,ARM to HEX将opcode的MOVS R0, #0转成16进制0020

image-20221018232304540

image-20221018232406166

打开Hex View-1,F2修改01 20为00 20,F2应用。

image-20221018232700912

同理,进入sub_1CCD58中所有return 1;return 2;的地方的opcode都修改为0020,Edit-Patch Program-apply patches to input file保存好后放到/data/app/com.ss.android.ugc.aweme-mjb-5ipSrniOlGTyMxBrQg==/lib/arm

1
2
3
chgrp system libsscronet.so
chown system libsscronet.so
chmod 777 libsscronet.so

ollvm

hellojni_2.0.0.apk 函数sign1函数,打开libhello-jni.so的导出函数没有搜到,但是出现了多个.datadiv_decode函数,这就是ollvm默认字符串混淆前缀。

image-20221022150354601

以上byte开头编译过程是把字符串加密的逻辑,双击进入byte_37118,在010Editor中新建十六进制文件

image-20221022151122532

文章作者: J
文章链接: http://onejane.github.io/2022/06/05/FridaHook大全/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 万物皆可逆向
支付宝打赏
微信打赏