mgaic

爱错


  • 首页

  • 标签

  • 分类

  • 归档

ollvm bcf fla 学习记录并实战某博

发表于 2024-08-26 | 分类于 逆向

样例: libbxxdxprotect.so

前后对比图

绕过前 F5 长这个样子, 有一部分bcf(bugus control flow 虚假控制流) 的痕迹.

阅读全文 »

frida-stalker-trace 使用并实战某音

发表于 2024-08-12 | 分类于 逆向

我们自己写了一个app, 现在对这个app进行trace

先看看so名

1
cat /proc/$(pidof com.zj.my_md5 )/maps | grep checkout
阅读全文 »

docker容器下对运行中python进程调试踩坑记录(mgaic亲踩)

发表于 2024-08-01 | 分类于 逆向

背景

线上的项目是使用python3.6.15写的, 跑在docker下

问题

某个进程执行巨慢,通过日志定位到了 if else, 但是if下的代码有日志, else 处并没有打日志, 所以想看看else 处到底发生了什么.

阅读全文 »

某音去除花指令

发表于 2024-07-19 | 分类于 逆向
ida7.7 打开so文件 查看jni_onload

img_1.png

底部有个内联汇编, 跳转到X1, 但ida没识别出来.
__asm { BR X1 }

阅读全文 »

stackplz hook art 记录

发表于 2024-07-17 | 分类于 逆向

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
#include <jni.h>
#include <string>
#include <stdio.h>
#include <string.h>


void get_sign(const char *str);

extern "C" JNIEXPORT jstring JNICALL
Java_com_zj_my_1md5_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */, jstring url) {
std::string hello = env->GetStringUTFChars(url, 0);
hello = hello + "1";
get_sign(hello.c_str());

// return env->NewStringUTF(hello.c_str());
return env->NewStringUTF(hello.c_str());
}


void get_sign(const char *original) {
char buffer[50]; // 假设最大长度为 50
strncpy(buffer, original, sizeof(buffer));
strcat(buffer, " Additional ");
printf("Modified string: %s\n", buffer);

}

上面是我自己写的jni实现.

stackplz hook NewStringUTF 打印堆栈

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[str] --stack

结果如下, 可以看到调用堆栈已经打印出来了.

img_1.png

hook 一下GetStringUTFChars 看看入参?

先查看一下导出函数地址

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w GetStringUTFChars --dumpret

执行结果如下

1
2
3
4
5
6
findBTFAssets btf_file=a12-5.10-arm64_min.btf
[*] save maps to maps_6024.txt
FindRet for GetStringUTFChars failed, sym:_ZN3art12_GLOBAL__N_18CheckJNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh.llvm.14181278422957417913 offse
t:0x44b610
FindRet for GetStringUTFChars -> [0x4b7528] sym:_ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh offset:0x4b6e60
FindRet for GetStringUTFChars -> [0x51acb8] sym:_ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh offset:0x51a5f0

执行结果解析

0x4b7528 是函数最后一条指令的地址. _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh 是导出函数名, 0x4b6e60 是导出函数在so中的偏移

我们试试hook _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[int,str]

看看结果

1
2
3
4
5
6
idx:0 [/apex/com.android.art/lib64/libart.so] -> sym:_ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh off:0x0
ConfigMap{stackplz_pid=7690,thread_whitelist=0}
uid => whitelist:[10274];blacklist:[]
pid => whitelist:[6024];blacklist:[]
tid => whitelist:[];blacklist:[]
start 2 modules

发现并没有调用,说明很可能是调用的另一个函数, 试试另一个函数 _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[int,str]

结果如下

img_1.png

乱码 这是为什么呢? 原来 GetStringUTFChars 的入参是jstring, 出参是char * 所以我们要inline hook GetStringUTFChars 的最后一条指令的地址, 然后打印x0的值(arm64调用约定, 返回值一般放在x0寄存器)。

试试看, 代码如下

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w 0x51acb8[str:x0]

执行结果

img_1.png

可以看到 hook成功

同理可以Hook NewStringUTF, NewStringUTF 的入参是 char *, 所以只需要hook 偏移或者导出函数地址就可以了, 不需要hook 函数的最后一条指令的地址

1
./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE12NewStringUTFEP7_JNIEnvPKc[int,str] --regs

亲测可行, 并且不同的so, 可以调用的导出函数并不一样. 例如某音和我自己写的so, 虽然都是调用的 NewStringUTF, 但是对应的导出函数名是不一样的,建议两个都试一下

hook 某音 GetStringUTFChars

1
./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w 0x4b7528[str:x0]

效果如下

img_1.png

打印的无关信息过多, 试着过滤掉一部分. 只要/data开头的数据. -f 表示filter w:/data 表示 white 白名单. str.f0表示对第一个char* 应用f0过滤策略, 即 w:/data

1
./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w 0x4b7528[str.f0:x0] -f w:/data

看看结果

img_1.png

hook GetStaticMethodID

1
2
./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w GetStaticMethodID --dumpret
./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w 0x49e250[str:x2,str:x3]

结果如下 豁然开朗

img_1.png

硬件断点 hook 0x1e66c 打印调用堆栈

1
./stackplz -p `pidof com.zj.my_md5` --brk 0x715adae66c:x  --stack

0x715adae66c 是绝对地址. 通过so基址加偏移得到的.

结果如下

img_1.png

某音six分析记录(mgaic原创)

发表于 2024-07-16 | 分类于 逆向

hook hashMap put 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function hookMap(){
var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function (a, b) {
//a=="username"和a.equals("username")一般都可以
//如果不行换一下即可
// console.log("a", a);
// if (a == "x-tt-token") {
if (a == "X-Medusa") {
// if (a.indexOf("medusa") != -1) {
console.log("hashMap.put: ", a, b);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}
return this.put(a, b);
}
}

结果如下

img_1.png

hook fCw试试, 看看在调用该函数的时候, 六神是否已经生成

hook 代码如下

1
2
3
4
5
6
7
8
9
10
function hook_intercept(){
let C112070fCw = Java.use("X.fCw");
C112070fCw["intercept"].implementation = function (chain) {
console.log(`C112070fCw.intercept is called: chain=${chain.request().url()}`);
console.log(`C112070fCw.intercept is called: chain headers =${chain.request().headers()}`);
let result = this["intercept"](chain);
// console.log(`C112070fCw.intercept result=${result}`);
return result;
};
}

hook 结果如下

img_1.png

可以看到此处六神已经拿到了, 继续往上游函数摸索.

hook fct函数试试, hookfct函数发现headers 中没有 six

jadx打开看看

img_1.png

看看response fct函数以后, headers有没有增加six 字段

hook脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function hook_intercept(){
let C112070fCw = Java.use("X.fCt");
var origin_chain = null;
C112070fCw["intercept"].implementation = function (chain) {
origin_chain = chain;
console.log(`C112070fCw.intercept is called: chain=${chain.request().url()}`);
console.log(`C112070fCw.intercept is called: chain headers =${chain.request().headers()}`);
let result = this["intercept"](chain);
// console.log(`C112070fCw.intercept result=${result}`);
console.log("after call function ", result.request().headers());
return result;
};

}

结果如下

img_1.png

可以看到 经过 fCt 以后,six就出来了. 重点看看 fCt, tryAddSecurityFactor 很可疑, hook 看看, 要注意Map强转HashMap, 否则打印出来的就是 Obejct

1
2
3
4
5
6
7
8
9
let NetworkParams = Java.use("com.bytedance.frameworks.baselib.network.http.NetworkParams");
var HashMap = Java.use('java.util.HashMap');
NetworkParams["tryAddSecurityFactor"].implementation = function (str, map) {
console.log(`NetworkParams.tryAddSecurityFactor is called: str=${str}, map=${map}`);
let result = this["tryAddSecurityFactor"](str, map);
console.log(`NetworkParams.tryAddSecurityFactor result=${result}`);
console.log(`NetworkParams.tryAddSecurityFactor result=${Java.cast(result, HashMap).toString()}`);
return result;
};

hook 结果如下, 可以看到 six已经生成了

img_1.png

jadx继续看看 发现调用了 onCallToAddSecurityFactor, 进去看看实现, 发现是个接口

img_1.png

查看交叉引用看看

img_1.png

进入以后 发现调用了 l.a, hook 试试看

1
2
3
4
5
6
7
8
9
10
11
12
Java.perform(function (){
let l = Java.use("ms.bd.c.l");
let result = null;
l["a"].implementation = function (i, i2, j, str, obj) {
result = this["a"](i, i2, j, str, obj);
if(i == 50331649){
console.log("result ", Java.use('org.json.JSONArray').$new(result))
}

return result;
};
});

结果如下

img_1.png

java层到此结束。实现在native层。 实际测试, frida rpc 几十次后就不返回数据了. 风控很强。

ecapture 基于ebpf抓包(亲测可行)

发表于 2024-07-15 | 分类于 逆向

使用ecapture 抓包某物app, 亲测可行

ecapture 版本 0.8.3, 手机 红米note 12t pro, 内核版本 5.10. android版本 android 13

1
2
3
adb push ecapture /data/loca.tmp
chmod +x ecapture
./ecapture tls

效果图

可以看到请求 响应都在里面了

img_1.png

使用 stackplz 辅助分析 anti-frida(亲测可行)

发表于 2024-07-12

使用 stackplz 过anti-frida

一般检测frida 比较常用的一个函数是 strstr. 这个函数类似于 isSubString. 判断子串

我们使用 stackplz hook strstr 看看是谁在调用strstr

1
./stackplz -n tv.danmaku.bili -l /apex/com.android.runtime/lib64/bionic/libc.so -w strstr --stack

执行结果如下

img_1.png

看看strstr的参数, 到底是不是针对一些环境的检测

1
/stackplz -n tv.danmaku.bili -l /apex/com.android.runtime/lib64/bionic/libc.so -w strstr[str:x0,str:x1]  -o tmp.log

结果如下

img_1.png

google 一搜

img_1.png

大概率就是 libmxxxoxxdsec.so 在检测frida

从hook strstr的调用堆栈里我们可以看到是从 thread_start 开始的。 所以我们hook thread_create 看看, 创建线程比较早,所以先关掉app, 执行命令后再打开app

1
./stackplz -n tv.danmaku.bili -l /apex/com.android.runtime/lib64/bionic/libc.so -w pthread_create --stack -o tmp.log

可以看到结果, 有13处

img_1.png

ida打开 看看 0x1d304

img_1.png

F5 看看

img_1.png

这里很像是在创建线程。 我们试试patch, 强行让它不创建。 把 BLR X19 指令改为 nop. 在此之前还有一个问题, patch后会不会崩溃?
arm64 函数调用约定 返回值给x0, 我们看看后续有没有用到x0. 如果没用到我们可以这么改, 用到了程序可能就会崩溃

看汇编

img_1.png

发现并没有用到返回值。 所以我们打开 https://armconverter.com/

看看nop 对应的机器码

img_1.png

用 010editor 把 BL X19 对应的机器码全部改为 1F2003D5

我一共patch了三处. 然后把patch后的 so文件 push 到 /data/app/~~1m1hzMqd9svUirtnyTGHvA==/tv.xxxxx.xxxx-rMRttoSdjUufKzwDHC3FtQ==/lib/arm64/

然后frida 打开还是崩溃. 发现app 又用了其他另外一个地方的 sec.so文件. 把 so文件复制到两个目录下以后。发现frida 可以成功附加. 最好改一下so文件的权限为 755. 跟原先一致

<12

18 日志
2 分类
RSS
© 2025 chilly
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.3