mgaic

爱错


  • 首页

  • 标签

  • 分类

  • 归档

hexo 恢复记录

发表于 2025-04-15

1.安装 nvm (类似于python的 conda)

1
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

2. 安装 nodejs

1
2
$ nvm install 18
$ nvm use 18

3. clone 项目

由于之前deploy 过项目, 直接克隆就好

1
$ git clone git@github.com:xxxxx/hexo_blog.git

4. 编译

1
2
$ cd hexo_blog 
$ npm install

5. 下载 NexT.Mist v5.1.3 主题

1
$ git clone -b v5.1.3 https://github.com/iissnan/hexo-theme-next.git themes/next

6. 修改翻页标签乱码

1
# 参考  https://blog.csdn.net/qq_36852780/article/details/104897491

7.主题设置, 防止404 或者页面跳转错误问题

1
2
3
4
5
6
7
8
# 修改主题包下的 _config.yml
# Schemes
#scheme: Muse
scheme: Mist
#scheme: Pisces
#scheme: Gemini


1
2
3
4
5
6
7
# 修改主题包下的 _config.yml
menu:
home: /|| home
tags: /tags/|| tags
categories: /categories/|| th
archives: /archives/|| archive

8. 跑起来

1
$ hexo clean && hexo g && hexo s

9. 发布

需要配置git仓库, 参考 https://hexo.io/docs/one-command-deployment

然后执行

1
$ hexo clean && hexo deploy

frida内存扫描以及关键代码定位.

发表于 2024-09-11

frida 发布了新特性, 支持硬件断点, 能更好的对内存区域进行扫描, 并快速定位出哪段代码读写了这片内存区域
感兴趣的可以看下
贴上地址 https://frida.re/news/

阅读全文 »

某视频类app 花指令、ollvm bcf、fla 处理

发表于 2024-08-29 | 分类于 逆向
笔者的ida版本是ida7.7, 使用ida64 打开样本so, 看看 Jni_onload 函数

img_1.png

阅读全文 »

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

12>

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