首页
社区
课程
招聘
[原创]KCTF2022春季赛 第九题 同归于尽
发表于: 2022-6-2 16:39 13014

[原创]KCTF2022春季赛 第九题 同归于尽

2022-6-2 16:39
13014

花时间尝试了下这道题,最后败的倒地不起,但失败是好事,人总能在一次次失败中吸取教训,因此有了这篇wp,记录下这道题的踩坑过程。希望这篇wp可以让那些和我一样正在尝试逆向的萌新打开一些思路,共同进步

第一步,是令程序禁止地址随机化,这样程序每次从0x400000开始加载,而不是每次开机都会随机选择一个地址。虽然通过对IDA进行Segment的Rebase,也可以使其地址与OD/x32dbg一致(说起来,大佬们都是用x32dbg去做题,看来以后做题时也得切换调试器了),但是用0x400000显然更好,并且也能与家里电脑分析时保持一致。具体手法如下图(图片来源在文末):

首先会判断输入的字符串首字符是否为'A',以及长度是否为32位。

如果死在前两处校验,则会打印错误;否则会打印失败

经过单步验证,输入字符串"1234"(符合首字符不为'A'的情况),会依次调用sub_415B2Csub_499715sub_49B4ED这3个函数,其中执行完sub_49B4ED后,可以在eax指向的地址中找到中文字符"错误",执行完sub_49B4ED后,会在命令行中打印出"错误"

回到IDA中分析伪代码,通过观察可以发现,sub_415B2C初始化了一个数组,然后sub_499715通过对数组中特定位置字符进行异或运算,解出"错误"对应的ascii码,然后再通过sub_49B4ED打印出字符

图中两处橙色方框,都是先初始化数组,再进行异或解密,然后打印字符;但是两处初始化数组的函数不同,解密函数也不同,用于打印字符的函数是相同的。根据这个特征,我们可以去找sub_49B4ED这个函数的交叉引用,这样也许就可以找到打印"失败"所在的位置了

可以看到,在函数sub_46D092中也有三处调用sub_49B4ED的地方。进入其所在汇编附近(这里无法看伪代码,因为函数过长,超过1w行,IDA无法解析,修改解析函数大小后,又遇到了stack frame is too big的问题,查阅资料后扔无法解决,因此只能看汇编),可以看到,在每次调用sub_49B4ED之前,都有2个call,猜测这两个call是分别用来数组初始化与解密得到中文字符用的。

纯看汇编肯定不行,上万行呢!好在IDA支持CFG的形式,这里需要按照上图所示,在选项中对Graph视图进行配置,调整最大结点数,然后就能够以"基本块+边"的方式对汇编进行查看,体验会稍好些

先找到loc_47541A这个基本块,这个基本块里会打印出"失败",我标记为"失败1"是因为,一共有2个失败,说明可能有2次判断,而这里打印"失败"的地址最靠前,说明会受到第一次判断的影响,因此被标记为"失败1",也就先分析它

这里还有一点需要说明,就是图中左右两侧的边都是直上直下连接的,也就是说左侧是从上到下几乎完全线性的基本块,不会有边从左侧的基本块连接到右侧的基本块,右侧也几乎同样如此,所以此时基本可以忽略左侧的基本块,直接看右侧上方的调用链即可

在往上查看右侧调用链时,可以发现打印"成功"的基本块,并且是在右侧。我们知道左侧的基本块会走到"失败",现在我们要找到,导致走向失败或者成功的这个分支点在哪

再往上看,就可以找到图中所示的这片代码块了,在这里,我们看到了"失败2"所在的代码块。这里重点关注两个蓝色方框

其次是下面的蓝色方框(位于loc_478405),这里是一个循环,和上方的代码块loc_4783E3是关联的,IDA没有完全分析出,进入OD下断(当然先把前面的分支跳转patch掉,使之可以走到此处的代码块)可以发现,这一块是对输入的字符串进行判断,筛选出小写,即只允许输入 [0-9A-Za-z] 范围内的字符

继续往上分析,找到导致跳转的源头,结合OD进行分析,可以得到,这里对栈中的值进行了比较,若两处的值完全相同,则会进入理想的分支中。否则会跳转到"失败1"对应的分支

通过交叉引用,可以发现,其中进行比较的一个值是写死的,可以直接找到(所以另一个值就是将输入的字符串进行变换得到的了),这里可以先将其记录下

这里可以看到,随机输入的字符串,得到的新字符串(暂且称作其为加密字符串),和需要进行比较的结果差距还是很大的。接下来要做的,就是找出字符串是如何经过变换得到加密字符串的

这里为什么要找[ebp+0x1B0]?上层调用函数栈不是会下降吗?ebp变了,为啥寻址没变?其实我也不知道为啥要这样做,我只是找规律,我通过交叉引用找到调用sub_46D092的上层函数时,发现在该函数[ebp+0x1B0]的位置,也已经存储了加密后的字符串(这意味着还需要往上层找),尽管sub_46D092中的ebp和上层函数中的ebp值不一样,但是加密字符串都是存在[ebp+0x1B0]处,所以按照规律就这么找了,这里对这个地址下硬件访问断点也可以

然后我们在sub_4631E9中找到了,arg_1A8对应的刚好是0x1B0。这是sub_46D092上层函数的上层函数

接下来,通过交叉引用,可以找到一个函数sub_49AF99,它将[ebp+0x1B0]这个地址作为参数传了进去

单步调试一下,也可以发现,执行sub_49AF99前,会传入一个空缓冲区,执行后就填充了加密后的字符串,这下可以断定,这里的sub_49AF99就是对字符串进行加密的地方。接下来就可以针对sub_49AF99这个函数进行分析

我们知道,加密字符串有一个比较的值是写死的,所以我们带入加密后的字符串,分别进行解密,可以得到如下的结果,

将图中橙色方框按照顺序,以小端方式写入那个已经经过变换后的字符串堆块(在执行sub_49D07F之前,strcpy之后)中,然后F9执行

可以发现,这么做,进行手动修改加密前的字符串,是可以执行成功的,也说解密的程序是没有问题的,但是这里还存在两个问题

找字符串变换逻辑和找字符串加密逻辑一样,从这里可以看到,字符串作为参数传入sub_49AF99时位于[ebp+Source]也就是[ebp+0x2CA],然后据此通过交叉引用向上找,看看上层函数是否有修改[ebp+0x2CA]的地方

不断的往上找,可以发现在函数sub_44BC99中使用到了[ebp+0x2CA]这个栈空间,在该函数的基本块loc_44EBEC中,将输入的字符串与一个写死的全局变量进行了异或运算,可以看到这个全局变量就是"55555555555555555555555555555555"

总感觉就只差一步,但最终还是无能为力,直至题目结束,看了6位大佬的wp,咨询了出题的师傅,才豁然开朗

首先是对字符串进行加密的算法是SM4加密,由于自身的算法意识浅薄,看不出来(第三题的AES也没看出来),这也导致了始终发现不了最后的坑,但是不知道为什么Findcrypt只识别出了MD5和Base64

不过还是有一些特征的,在对进行密钥进行扩展的函数里,可以找到4个常量,搜索一下这4个常量就可以发现这是一个SM4的加密算法。这一点在mb_mgodlfyn的文章中有提到

这道题涉及到多种反调试手法,这一点在深山修行之人在他的文章进行总结,其中一种,就是修改SM4的密钥key

在使用调试器的情况下,用于进行函数扩展的密钥如图中橙色方框所示,此时按照mb_mgodlfyn大佬的思路patch在这个基本块Patch一个死循环,然后再附加(这样就可以过掉反调试了,或者像中午吃什么大佬那样,注入自己的Dll,在算法前后打印出相应的参数值),然后比较一下密钥的值

这里OD附加不了Patch的程序,所以用了x32dbg,可以看到,Patch后停下来得到的密钥确实和原先的不一样。或许这就是真实的密钥

修改box后重新运行一遍解密程序,可以发现,用于匹配的字符串后半部分算出来刚好是0,也就是说,确实只用到了前16字节进行运算。然后我们拼接一下计算出的结果,就可以得到"FAA2FBAEDFBAA3C2E3EC40AFCD4D9E43",与"55555555555555555555555555555555"进行异或,就可以得到"AFF7AEFB8AEFF697B6B915FA9818CB16"。带入到程序中,成功运行

 
# 加密算法
 
s1 = 'A1234567123456781234567812345678'
s2 = '00000000000000000000000000000000'
 
byte_7EC3E8 = [
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7,
0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3,
0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A,
0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95,
0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA,
0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B,
0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2,
0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52,
0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5,
0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55,
0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60,
0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F,
0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F,
0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD,
0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E,
0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20,
0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48
]
 
box = [
0x8C925023,
0x4BBE4C99,
0x1BF3D26F,
0x1E193BDF,
0x37B81FD9,
0xF82AEB6B,
0x0EB8EA2C,
0x01F7CCC7,
0xC3495601,
0x23FE4548,
0x4A3FC333,
0xCFDF05E8,
0x141FB615,
0x9EF7B415,
0x466E0E37,
0x8BE01DE9,
0xD7566D09,
0xBD20455F,
0xCCC85ED0,
0xC5303952,
0xC847CE90,
0x4ADFA7C6,
0x46803565,
0x1873D9A8,
0xE9AD4459,
0x307C97E3,
0x3ECF9AD7,
0x1C72E515,
0x8F1B291C,
0xFEAB7BE6,
0x677FBEB8,
0xF1EC5D67
]
 
def sub_7CD07F(box, s):
 
    res = []
    v15 = []
    for i in range(36):
        v15.append(0)
    v4 = int(s[5])
    v15[0] = int(s[3]) | ((int(s[2]) | ((int(s[1]) | (int(s[0]) << 8)) << 8)) << 8)
    v15[1] = int(s[7]) | ((int(s[6]) | ((v4 | (int(s[4]) << 8)) << 8)) << 8);
    v6 = int(s[9])
    v15[2] = int(s[11]) | ((int(s[10]) | ((v6 | (int(s[8]) << 8)) << 8)) << 8)
    v8 = int(s[13])
    v15[3] = int(s[15]) | ((int(s[14]) | ((v8 | (int(s[12]) << 8)) << 8)) << 8)
    for i in range(4):
        print(hex(v15[i]))
 
    for i in range(0x20):
 
        # assign
        ecx = (v15[i+1] ^ v15[i+2] ^ v15[i+3] ^ box[i])
        idx_a = ecx >> 0x18
        #print(hex(ecx))
        val_a = byte_7EC3E8[idx_a]
        #print(hex(val_a))
        idx_b = (ecx >> 0x10) & 0x000000FF
        val_b = byte_7EC3E8[idx_b]
        val_ab = val_b | (val_a << 8)
        #print(hex(val_b))
        #print(hex(val_ab))
        idx_c = (ecx >> 0x8) & 0x000000FF
        val_c = byte_7EC3E8[idx_c]
        val_abc = val_c | (val_ab << 8)
        #print(hex(val_c))
        #print(hex(val_abc))
        idx_d = ecx & 0x000000FF
        val_d = byte_7EC3E8[idx_d]
        val_abcd = val_d | (val_abc << 8)
        #print(hex(val_d))
        #print('val_abcd: ', hex(val_abcd))
 
        # extent   
        temp_a = ((val_abcd << 18) & 0xFFFFFFFF) | (val_abcd >> 14)
        temp_b = (val_abcd >> 22) | ((val_abcd << 10) & 0xFFFFFFFF)
        temp_c = ((val_abcd << 24) & 0xFFFFFFFF) | (val_abcd >> 8)
        temp_d = (val_abcd >> 30) | ((val_abcd << 2) & 0xFFFFFFFF)
        #print(hex(temp_a))
        #print(hex(temp_b))
        #print(hex(temp_c))
        #print(hex(temp_d))
        #print(hex(v15[i]))
        v15[i+4] = val_abcd ^ v15[i] ^ temp_a ^ temp_b ^ temp_c ^ temp_d
        res.append(hex(v15[i+4]))
        print('v15[i+4]: ', hex(v15[i+4]))
        #break
 
    '''   
    res = res[::-1][:4]
    for x in res:
        print(x)
    '''
 
def sub_7CD025(box, s1, s2):
 
    v7 = ((0x20-1) >> 4)+ 1
    #for i in range(v7):
    sub_7CD07F(box, s1)
    sub_7CD07F(box, s2)
 
if __name__ == '__main__':
 
    s1 = [0x1A, 0x32, 0x54, 0x76, 0x21, 0x43, 0x65, 0x87, 0x21, 0x43, 0x65, 0x87, 0x21, 0x43, 0x65, 0x87]
    s2 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
    sub_7CD025(box, s1, s2)
# 加密算法
 
s1 = 'A1234567123456781234567812345678'
s2 = '00000000000000000000000000000000'
 
byte_7EC3E8 = [
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7,
0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3,
0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A,
0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95,
0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA,
0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B,
0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2,
0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52,
0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5,
0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55,
0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60,
0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F,
0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F,
0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD,
0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E,
0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20,
0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48
]
 
box = [
0x8C925023,
0x4BBE4C99,
0x1BF3D26F,
0x1E193BDF,
0x37B81FD9,
0xF82AEB6B,
0x0EB8EA2C,
0x01F7CCC7,
0xC3495601,
0x23FE4548,
0x4A3FC333,
0xCFDF05E8,
0x141FB615,
0x9EF7B415,
0x466E0E37,
0x8BE01DE9,
0xD7566D09,
0xBD20455F,
0xCCC85ED0,
0xC5303952,
0xC847CE90,
0x4ADFA7C6,
0x46803565,
0x1873D9A8,
0xE9AD4459,
0x307C97E3,
0x3ECF9AD7,
0x1C72E515,
0x8F1B291C,
0xFEAB7BE6,
0x677FBEB8,
0xF1EC5D67
]
 
def sub_7CD07F(box, s):
 
    res = []
    v15 = []
    for i in range(36):
        v15.append(0)
    v4 = int(s[5])
    v15[0] = int(s[3]) | ((int(s[2]) | ((int(s[1]) | (int(s[0]) << 8)) << 8)) << 8)
    v15[1] = int(s[7]) | ((int(s[6]) | ((v4 | (int(s[4]) << 8)) << 8)) << 8);
    v6 = int(s[9])
    v15[2] = int(s[11]) | ((int(s[10]) | ((v6 | (int(s[8]) << 8)) << 8)) << 8)
    v8 = int(s[13])
    v15[3] = int(s[15]) | ((int(s[14]) | ((v8 | (int(s[12]) << 8)) << 8)) << 8)
    for i in range(4):
        print(hex(v15[i]))
 
    for i in range(0x20):
 
        # assign
        ecx = (v15[i+1] ^ v15[i+2] ^ v15[i+3] ^ box[i])
        idx_a = ecx >> 0x18
        #print(hex(ecx))
        val_a = byte_7EC3E8[idx_a]
        #print(hex(val_a))
        idx_b = (ecx >> 0x10) & 0x000000FF
        val_b = byte_7EC3E8[idx_b]
        val_ab = val_b | (val_a << 8)
        #print(hex(val_b))
        #print(hex(val_ab))
        idx_c = (ecx >> 0x8) & 0x000000FF
        val_c = byte_7EC3E8[idx_c]
        val_abc = val_c | (val_ab << 8)
        #print(hex(val_c))
        #print(hex(val_abc))
        idx_d = ecx & 0x000000FF
        val_d = byte_7EC3E8[idx_d]
        val_abcd = val_d | (val_abc << 8)
        #print(hex(val_d))
        #print('val_abcd: ', hex(val_abcd))
 
        # extent   
        temp_a = ((val_abcd << 18) & 0xFFFFFFFF) | (val_abcd >> 14)
        temp_b = (val_abcd >> 22) | ((val_abcd << 10) & 0xFFFFFFFF)
        temp_c = ((val_abcd << 24) & 0xFFFFFFFF) | (val_abcd >> 8)
        temp_d = (val_abcd >> 30) | ((val_abcd << 2) & 0xFFFFFFFF)
        #print(hex(temp_a))
        #print(hex(temp_b))
        #print(hex(temp_c))
        #print(hex(temp_d))
        #print(hex(v15[i]))
        v15[i+4] = val_abcd ^ v15[i] ^ temp_a ^ temp_b ^ temp_c ^ temp_d
        res.append(hex(v15[i+4]))
        print('v15[i+4]: ', hex(v15[i+4]))
        #break
 
    '''   
    res = res[::-1][:4]
    for x in res:
        print(x)
    '''
 
def sub_7CD025(box, s1, s2):
 
    v7 = ((0x20-1) >> 4)+ 1
    #for i in range(v7):
    sub_7CD07F(box, s1)
    sub_7CD07F(box, s2)
 
if __name__ == '__main__':
 
    s1 = [0x1A, 0x32, 0x54, 0x76, 0x21, 0x43, 0x65, 0x87, 0x21, 0x43, 0x65, 0x87, 0x21, 0x43, 0x65, 0x87]
    s2 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
    sub_7CD025(box, s1, s2)
# 解密算法
# 解密算法也需要用到box和数组byte_7EC3E8,这里就不重复复制了
 
def sub_7CD07F_decode(box):
 
    #rst_test = [0x3b0e071, 0x3a904877, 0x45ef484e, 0xb45d2d80]
    #rst = [0x907CBE0E, 0x68F4E360, 0x8D2AA89A, 0xFCFFBE78]
    rst = [0x553786E8, 0x9B5D05F5, 0x5FDC04DD, 0xE12A7721]
    rst_v15 = []
    for i in range(36):
        rst_v15.append(0)
    rst_v15[35] = rst[0]
    rst_v15[34] = rst[1]
    rst_v15[33] = rst[2]
    rst_v15[32] = rst[3]
 
 
    for i in range(0x20):
 
        ecx = (rst_v15[35-i-1] ^ rst_v15[35-i-2] ^ rst_v15[35-i-3] ^ box[35-i-4])
        idx_a = ecx >> 0x18
        #print(hex(ecx))
        val_a = byte_7EC3E8[idx_a]
        #print(hex(val_a))
        idx_b = (ecx >> 0x10) & 0x000000FF
        val_b = byte_7EC3E8[idx_b]
        val_ab = val_b | (val_a << 8)
        #print(hex(val_b))
        #print(hex(val_ab))
        idx_c = (ecx >> 0x8) & 0x000000FF
        val_c = byte_7EC3E8[idx_c]
        val_abc = val_c | (val_ab << 8)
        #print(hex(val_c))
        #print(hex(val_abc))
        idx_d = ecx & 0x000000FF
        val_d = byte_7EC3E8[idx_d]
        val_abcd = val_d | (val_abc << 8)   
        #print('val_abcd: ', hex(val_abcd))       
 
        temp_a = ((val_abcd << 18) & 0xFFFFFFFF) | (val_abcd >> 14)
        temp_b = (val_abcd >> 22) | ((val_abcd << 10) & 0xFFFFFFFF)
        temp_c = ((val_abcd << 24) & 0xFFFFFFFF) | (val_abcd >> 8)
        temp_d = (val_abcd >> 30) | ((val_abcd << 2) & 0xFFFFFFFF)
        #print(hex(temp_a))
        #print(hex(temp_b))
        #print(hex(temp_c))
        #print(hex(temp_d))
        #print(hex(v15[i]))
        rst_v15[35-i-4] = val_abcd ^ rst_v15[35-i] ^ temp_a ^ temp_b ^ temp_c ^ temp_d
        #print('rst_v15[35-i]: ', hex(rst_v15[35-i]))
        print('rst_v15[35-i-4]: ', hex(rst_v15[35-i-4]))
 
if __name__ == '__main__':
 
    sub_7CD07F_decode(box)
# 解密算法
# 解密算法也需要用到box和数组byte_7EC3E8,这里就不重复复制了
 
def sub_7CD07F_decode(box):
 
    #rst_test = [0x3b0e071, 0x3a904877, 0x45ef484e, 0xb45d2d80]
    #rst = [0x907CBE0E, 0x68F4E360, 0x8D2AA89A, 0xFCFFBE78]
    rst = [0x553786E8, 0x9B5D05F5, 0x5FDC04DD, 0xE12A7721]
    rst_v15 = []
    for i in range(36):
        rst_v15.append(0)
    rst_v15[35] = rst[0]
    rst_v15[34] = rst[1]
    rst_v15[33] = rst[2]
    rst_v15[32] = rst[3]
 
 
    for i in range(0x20):
 
        ecx = (rst_v15[35-i-1] ^ rst_v15[35-i-2] ^ rst_v15[35-i-3] ^ box[35-i-4])
        idx_a = ecx >> 0x18
        #print(hex(ecx))
        val_a = byte_7EC3E8[idx_a]
        #print(hex(val_a))
        idx_b = (ecx >> 0x10) & 0x000000FF
        val_b = byte_7EC3E8[idx_b]
        val_ab = val_b | (val_a << 8)
        #print(hex(val_b))

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-6-2 17:58 被Ally Switch编辑 ,原因: 一些细节的修改
收藏
免费 8
支持
分享
最新回复 (6)
雪    币: 640
活跃值: (1101)
能力值: ( LV4,RANK:44 )
在线值:
发帖
回帖
粉丝
2
findcrypt没有收录国密,可以在findcrypt.rules里面自己加
2022-6-3 17:46
0
雪    币: 8195
活跃值: (6419)
能力值: ( LV12,RANK:207 )
在线值:
发帖
回帖
粉丝
3
Ysiel findcrypt没有收录国密,可以在findcrypt.rules里面自己加
原来如此,感谢指点!
2022-6-4 16:51
0
雪    币: 3159
活跃值: (2839)
能力值: ( LV12,RANK:383 )
在线值:
发帖
回帖
粉丝
4
tql
2022-6-5 00:13
0
雪    币: 8195
活跃值: (6419)
能力值: ( LV12,RANK:207 )
在线值:
发帖
回帖
粉丝
5
wx_孤城 tql
还远不及师傅
2022-6-5 12:20
0
雪    币: 1066
活跃值: (1483)
能力值: ( LV6,RANK:149 )
在线值:
发帖
回帖
粉丝
6
分析的很细致,学会了
2022-6-6 10:55
0
雪    币: 8195
活跃值: (6419)
能力值: ( LV12,RANK:207 )
在线值:
发帖
回帖
粉丝
7
KEEEY 分析的很细致,学会了
师傅web题分析的也很细
2022-6-6 14:00
0
游客
登录 | 注册 方可回帖
返回
//