mgaic

爱错


  • 首页

  • 标签

  • 分类

  • 归档

sha256 学习笔记

发表于 2025-04-29 | 分类于 逆向

step1 常量初始化

1
2
3
4
5
6
7
8
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

这八个初始向量怎么来的?
答曰: 前八个质数取根号后的值 取小数部分, 然后乘以2的32次方, 对结果取整 就是初始向量.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import math

# 第一个8个素数
primes = [2, 3, 5, 7, 11, 13, 17, 19]

H = []

for p in primes:
sqrt_p = math.sqrt(p)
sqrt_p = p ** (1/2)
frac_part = sqrt_p - int(sqrt_p) # 提取小数部分
value = int(frac_part * (2**32)) # 小数部分 * 2^32,再取整
H.append(value)

# 打印结果
for h in H:
print(hex(h))

step2 常量64位 K表

如果生成的?
答曰: 前64个质数,取立方根, 跟8位常量的生成算法一样, 只是取的是立方根, 下面给出代码

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
import math

# 先生成前64个素数
def get_first_n_primes(n):
primes = []
candidate = 2
while len(primes) < n:
is_prime = True
for p in primes:
if p * p > candidate:
break
if candidate % p == 0:
is_prime = False
break
if is_prime:
primes.append(candidate)
candidate += 1
return primes

# 计算K表
def generate_sha256_k():
primes = get_first_n_primes(64)
K = []
for p in primes:
cbrt = p ** (1/3)
frac_part = cbrt - int(cbrt)
value = int(frac_part * (2**32))
K.append(value)
return K

# 打印结果
K = generate_sha256_k()
for i, k in enumerate(K):
print(f"K[{i}] = 0x{k:08x}")

综上,这些常量也只是根据质数生成的, 换一批质数, 获取随机常量就可以达到魔改的目的

step 3 填充

假设有数据 ‘abc’, 用16进制表示 是

1
2
61626300 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

0x61 是 ‘a’的 ascii 码
0x62 是 ‘b’的 ascii 码
0x63 是 ‘c’的 ascii 码

将数据尾部添加一个 bit’1’, 然后再添加若干个 bit’0’, 凑够 448 位
448 + 64 = 512, 为什么要凑 448 因为还有 64位置是用来记录数据的长度的。 448位记录是的数据 64位记录的是长度

这样数据在内存中就变成了如下分布

1
2
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018

0x80 是 10000000的hex表示.
0x18 对应十进制是 24, 正好就是 abc 所占的bit

计算, 生成 w0-w63

w0-w15 就是原来的数据.

w16-w63 根据如下算法生成

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
def _sigma0(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 7) ^
_rotate_right(num, 18) ^
(num >> 3))
return num

def _sigma1(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 17) ^
_rotate_right(num, 19) ^
(num >> 10))
return num

def _capsigma0(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 2) ^
_rotate_right(num, 13) ^
_rotate_right(num, 22))
return num

def _capsigma1(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 6) ^
_rotate_right(num, 11) ^
_rotate_right(num, 25))
return num

def _ch(x: int, y: int, z: int):
"""As defined in the specification."""
return (x & y) ^ (~x & z)

def _maj(x: int, y: int, z: int):
"""As defined in the specification."""
return (x & y) ^ (x & z) ^ (y & z)

def _rotate_right(num: int, shift: int, size: int = 32):
"""Rotate an integer right."""
return (num >> shift) | (num << size - shift)


W = []
for t in range(0, 64):
if t <= 15:
# adds the t'th 32 bit word of the block,
# starting from leftmost word
# 4 bytes at a time
W.append(bytes(message_block[t*4:(t*4)+4]))
else:
term1 = _sigma1(int.from_bytes(W[t-2], 'big'))
term2 = int.from_bytes(W[t-7], 'big')
term3 = _sigma0(int.from_bytes(W[t-15], 'big'))
term4 = int.from_bytes(W[t-16], 'big')

# append a 4-byte byte object
schedule = ((term1 + term2 + term3 + term4) % 2**32).to_bytes(4, 'big')
W.append(schedule)

assert len(W) == 64

接下给出sha256 完整代码

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""This Python module is an implementation of the SHA-256 algorithm.
From https://github.com/keanemind/Python-SHA-256"""

K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]

def generate_hash(message: bytearray) -> bytearray:
"""Return a SHA-256 hash from the message passed.
The argument should be a bytes, bytearray, or
string object."""

if isinstance(message, str):
message = bytearray(message, 'ascii')
elif isinstance(message, bytes):
message = bytearray(message)
elif not isinstance(message, bytearray):
raise TypeError

# Padding
length = len(message) * 8 # len(message) is number of BYTES!!!
message.append(0x80)
while (len(message) * 8 + 64) % 512 != 0:
message.append(0x00)

message += length.to_bytes(8, 'big') # pad to 8 bytes or 64 bits

assert (len(message) * 8) % 512 == 0, "Padding did not complete properly!"

# Parsing
blocks = [] # contains 512-bit chunks of message
for i in range(0, len(message), 64): # 64 bytes is 512 bits
blocks.append(message[i:i+64])

# Setting Initial Hash Value
h0 = 0x6a09e667
h1 = 0xbb67ae85
h2 = 0x3c6ef372
h3 = 0xa54ff53a
h5 = 0x9b05688c
h4 = 0x510e527f
h6 = 0x1f83d9ab
h7 = 0x5be0cd19

# SHA-256 Hash Computation
for message_block in blocks:
# Prepare message schedule
message_schedule = []
for t in range(0, 64):
if t <= 15:
# adds the t'th 32 bit word of the block,
# starting from leftmost word
# 4 bytes at a time
message_schedule.append(bytes(message_block[t*4:(t*4)+4]))
else:
term1 = _sigma1(int.from_bytes(message_schedule[t-2], 'big'))
term2 = int.from_bytes(message_schedule[t-7], 'big')
term3 = _sigma0(int.from_bytes(message_schedule[t-15], 'big'))
term4 = int.from_bytes(message_schedule[t-16], 'big')

# append a 4-byte byte object
schedule = ((term1 + term2 + term3 + term4) % 2**32).to_bytes(4, 'big')
message_schedule.append(schedule)

assert len(message_schedule) == 64

# Initialize working variables
a = h0
b = h1
c = h2
d = h3
e = h4
f = h5
g = h6
h = h7

# Iterate for t=0 to 63
for t in range(64):
t1 = ((h + _capsigma1(e) + _ch(e, f, g) + K[t] +
int.from_bytes(message_schedule[t], 'big')) % 2**32)

t2 = (_capsigma0(a) + _maj(a, b, c)) % 2**32

h = g
g = f
f = e
e = (d + t1) % 2**32
d = c
c = b
b = a
a = (t1 + t2) % 2**32

# Compute intermediate hash value
h0 = (h0 + a) % 2**32
h1 = (h1 + b) % 2**32
h2 = (h2 + c) % 2**32
h3 = (h3 + d) % 2**32
h4 = (h4 + e) % 2**32
h5 = (h5 + f) % 2**32
h6 = (h6 + g) % 2**32
h7 = (h7 + h) % 2**32

return ((h0).to_bytes(4, 'big') + (h1).to_bytes(4, 'big') +
(h2).to_bytes(4, 'big') + (h3).to_bytes(4, 'big') +
(h4).to_bytes(4, 'big') + (h5).to_bytes(4, 'big') +
(h6).to_bytes(4, 'big') + (h7).to_bytes(4, 'big'))

def _sigma0(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 7) ^
_rotate_right(num, 18) ^
(num >> 3))
return num

def _sigma1(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 17) ^
_rotate_right(num, 19) ^
(num >> 10))
return num

def _capsigma0(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 2) ^
_rotate_right(num, 13) ^
_rotate_right(num, 22))
return num

def _capsigma1(num: int):
"""As defined in the specification."""
num = (_rotate_right(num, 6) ^
_rotate_right(num, 11) ^
_rotate_right(num, 25))
return num

def _ch(x: int, y: int, z: int):
"""As defined in the specification."""
return (x & y) ^ (~x & z)

def _maj(x: int, y: int, z: int):
"""As defined in the specification."""
return (x & y) ^ (x & z) ^ (y & z)

def _rotate_right(num: int, shift: int, size: int = 32):
"""Rotate an integer right."""
return (num >> shift) | (num << size - shift)

if __name__ == "__main__":
print(generate_hash("Hello").hex())

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 几十次后就不返回数据了. 风控很强。

<123>

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