密码学学习记录 5 / 15
- 密码学学习记录|hash md5 算法
- 密码学学习记录|hash md5 算法练习样本一
- 密码学学习记录|hash md5 算法练习样本二
- 密码学学习记录|hash sha1 算法
- 密码学学习记录|hash sha1 算法练习样本一
- 密码学学习记录|hash sha256 算法
- 密码学学习记录|hash sha256 算法练习样本一
- 密码学学习记录|hash sha512 算法
- 密码学学习记录|hash hmac 算法
- 密码学学习记录|des 加解密算法
- 密码学学习记录|des - 3des 算法
- 密码学学习记录|aes 加解密算法
- 密码学学习记录|aes dfa 练习样本一
- 密码学学习记录|aes dfa 练习样本二
- 密码学学习记录|aes dfa 练习样本三
样本来自 Litt1eQ 大佬的公众号 Coder小Q
推荐阅读上一章的 sha1 算法分析
分析之前先使用 unidbg 跑一下,方便动态调试分析
这个样本跟前面的 md5 逻辑比较相似,打开即可分析
so 分析
这是入口函数,核心逻辑在 sub_950
这里有几个常量,点过去看一下
这里有五个,猜测是 H0-H4
五个常量
在往下就是,数据分组跟四轮循环了
sub_91C
这个函数的逻辑,就是四个 F
函数了
unidbg
使用 unidbg
获取一些常常量值
-
1、
H0-H4
五个常量 -
2、四个计算常数
-
3、循环移位数
0x1 五个常量 hook
emulator.getBackend().hook_add_new(new CodeHook() {
@Override
public void hook(Backend backend, long address, int size, Object user) {
if (address == (module.base + 0xA00)) {
Arm32RegisterContext ctx = emulator.getContext();
System.out.println("0xA00 五个常量: 0x" + Long.toHexString(ctx.getR1Long()));
}
}
@Override
public void onAttach(UnHook unHook) {
}
@Override
public void detach() {
}
}, module.base + 0xA00, module.base + 0xA00, null);
0x2 四个计算常数 hook
emulator.getBackend().hook_add_new(new CodeHook() {
@Override
public void hook(Backend backend, long address, int size, Object user) {
if (address == (module.base + 0xA44)) {
Arm32RegisterContext ctx = emulator.getContext();
System.out.println("0xA44 K params = 0x" + Long.toHexString(ctx.getR1Long()));
}
}
@Override
public void onAttach(UnHook unHook) {
}
@Override
public void detach() {
}
}, module.base + 0xA44, module.base + 0xA44, null);
计算常数有些不同,标准的只有四个,四轮每轮使用一个,这里的却是有 80
个,也就是每步都是不同的
0x3 循环移位数
这个不需要 hook
静态分析就能看出来(不过需要注意,标准的是循环左移,这里是循环右移)
数组分组时,循环右移数是 31
80
步计算时,循环右移使用的分别是 27, 2
python
使用之前的代码改改就可以
- 1、
H0-H4
五个常量
self.H = [0x1B6E192E, 0x3FC176B7, 0x5F973152, 0x6DCC57BB, 0x7AEA38C1]
- 2、计算常数
self.K = [
0xDF173709, 0xCCB9E3D2, 0x73CAF584, 0xA5FAF9A5, 0xF36AAC58, 0xA2C7B75E, 0x76888D8F, 0x3E9E8A08,
0xDB22622E, 0x4CF63C0F, 0x7E714178, 0x2326FDCF, 0x26CE914A, 0x3CB69463, 0x870A24BC, 0x2441A25,
0x96913352, 0x22889709, 0x222EC95F, 0x2DC2CAFD, 0x461173C7, 0x480BC543, 0xE31BCB1C, 0x67C3C909,
0x7112F5F3, 0xA937B122, 0x5021BCE9, 0x9F9DA0C5, 0x794BEBE8, 0xC01EDC7C, 0xD73CC8F5, 0x4F707435,
0x9D537008, 0x1E01CC36, 0x2920CC22, 0x4A986749, 0x7F965009, 0x4884B90, 0x9EA9963E, 0x162C4DEB,
0x1FE109E8, 0x333B89FC, 0x2C43BC20, 0x459B474C, 0xE730A765, 0xDA34245, 0x6E606232, 0xAC7E29D4,
0x2EDED96B, 0x9C7C6EB3, 0x7C153F9F, 0x54B308E1, 0xD365ECEB, 0x51EE2ABD, 0, 0, 0, 0, 0, 0, 0,
0x1B6E192E, 0x3FC176B7, 0x5F973152, 0x6DCC57BB, 0x7AEA38C1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
- 3、循环右移
@staticmethod
def left_circular_shift(k, bits):
bits = bits % (2 ** 32)
k = k % (2 ** 32)
return (k << (32 - bits) | (k >> bits)) % (2 ** 32)
- 4、transform
def transform(self, input_str):
iterations = (len(input_str) * 8) // 512
for i in range(0, iterations):
input_str1 = input_str[i * 64: (i + 1) * 64]
A = self.H[0]
B = self.H[1]
C = self.H[2]
D = self.H[3]
E = self.H[4]
W = [0] * 80
for w1 in range(16):
W[w1] = (input_str1[w1 * 4]) << 24
W[w1] |= (input_str1[w1 * 4 + 1]) << 16
W[w1] |= (input_str1[w1 * 4 + 2]) << 8
W[w1] |= (input_str1[w1 * 4 + 3]) << 0
for w2 in range(16, 80):
W[w2] = self.left_circular_shift(W[w2 - 3] ^ W[w2 - 8] ^ W[w2 - 14] ^ W[w2 - 16], 31)
for f in range(80):
if f < 20:
f_res = ((B & C) | ((~B) & D)) % (2 ** 32)
elif f < 40:
f_res = (B ^ C ^ D) % (2 ** 32)
elif f < 60:
f_res = ((B & C) | (B & D) | (C & D)) % (2 ** 32)
elif f < 80:
f_res = (B ^ C ^ D) % (2 ** 32)
else:
f_res = 0
TEMP = self.left_circular_shift(A, 27) + f_res + E + W[f] + self.K[f]
TEMP = TEMP % (2 ** 32)
E = D
D = C
C = self.left_circular_shift(B, 2)
B = A
A = TEMP
self.H[0] = (self.H[0] + A) % (2 ** 32)
self.H[1] = (self.H[1] + B) % (2 ** 32)
self.H[2] = (self.H[2] + C) % (2 ** 32)
self.H[3] = (self.H[3] + D) % (2 ** 32)
self.H[4] = (self.H[4] + E) % (2 ** 32)
return ''.join([hex(i).replace('0x', '').rjust(8, '0') for i in self.H]).upper()
最后
执行代码,结果跟 unidbg
的结果相同(这里有个很离谱的问题,unidbg 的结果跟 app 的不同,有哪位巨佬知晓原因还望指教)
everhu
2021-12-28这个apk支持64位的指令,如果你的手机也支持64位的指令,它会调用v8a的so,两个so的sha1结果不一样
会爬山的小脑虎
2021-12-28@everhu 原来如此,多谢巨佬指点迷津
everhu
2021-12-29@会爬山的小脑虎 别这么说,我也是看着你的文章学习的,刚好这个问题我之前碰到过