一个小CrackMe的分析
本帖最后由 _BaZzi 于 2016-3-19 18:27 编辑来自@Shiny 的一个小CrackMe
正脸照一张
查壳显示 PeSpin v1.32 (2008.03.09) by CyberBob 然而这篇帖子并不讲脱壳
OD载入 F9运行 CTRL+G到00401000
看到熟悉的xor eax, eax / retn 可以判断程序为易语言编写
搜索按钮事件特征码 FF55FC5F5E 下断
输入假码666666 点击注册后断下 F7进CALL
来到00401168 如下 单步跟踪
00401168/.55 push ebp
00401169|.8BEC mov ebp,esp
0040116B|.81EC 30000000 sub esp,0x30
00401171|.C745 FC 00000>mov ,0x0
00401178|.C745 F8 00000>mov ,0x0
0040117F|.C745 F4 00000>mov ,0x0
00401186|.C745 F0 00000>mov ,0x0
0040118D|.C745 EC 00000>mov ,0x0
00401194|.6A FF push -0x1
00401196|.6A 08 push 0x8
00401198|.68 35000116 push 0x16010035
0040119D|.68 01000152 push 0x52010001
004011A2|.E8 BD140000 call CM.00402664 // EAX出现注册码
004011A7|.83C4 10 add esp,0x10
004011AA|.8945 E8 mov ,eax
004011AD|.68 04000080 push 0x80000004
004011B2|.6A 00 push 0x0
004011B4|.8B45 E8 mov eax, ;CM.004B4768
004011B7|.85C0 test eax,eax
004011B9|.75 05 jnz short CM.004011C0
004011BB|.B8 403C4800 mov eax,CM.00483C40
004011C0|>50 push eax
004011C1|.68 01000000 push 0x1
004011C6|.BB 40294000 mov ebx,CM.00402940
004011CB|.E8 8E140000 call CM.0040265E // 将注册码从文本转换到整数
004011D0|.83C4 10 add esp,0x10
004011D3|.8945 E4 mov ,eax
004011D6|.8B5D E8 mov ebx, ;CM.004B4768
004011D9|.85DB test ebx,ebx
004011DB|.74 09 je short CM.004011E6
004011DD|.53 push ebx
004011DE|.E8 69140000 call CM.0040264C
004011E3|.83C4 04 add esp,0x4
004011E6|>8B45 E4 mov eax,
004011E9|.8945 FC mov ,eax
004011EC|.33C9 xor ecx,ecx
004011EE|.8D45 F8 lea eax,
004011F1|.8BD8 mov ebx,eax
004011F3|>41 /inc ecx // 循环 将整数型注册码转换为二进制文本
004011F4|.51 |push ecx
004011F5|.53 |push ebx
004011F6|.890B |mov dword ptr ds:,ecx
004011F8|.83F9 20 |cmp ecx,0x20
004011FB|.0F8F 8D000000 |jg CM.0040128E
00401201|.FF75 F8 |push
00401204|.FF75 FC |push ;CM.00401168
00401207|.E8 A5020000 |call CM.004014B1
0040120C|.8945 F4 |mov ,eax
0040120F|.837D F4 01 |cmp ,0x1
00401213|.0F85 07000000 |jnz CM.00401220
00401219|.C745 F0 01000>|mov ,0x1
00401220|>837D F0 01 |cmp ,0x1
00401224|.0F85 5D000000 |jnz CM.00401287
0040122A|.68 01030080 |push 0x80000301
0040122F|.6A 00 |push 0x0
00401231|.FF75 F4 |push
00401234|.68 01000000 |push 0x1
00401239|.BB A02E4000 |mov ebx,CM.00402EA0
0040123E|.E8 1B140000 |call CM.0040265E
00401243|.83C4 10 |add esp,0x10
00401246|.8945 E8 |mov ,eax
00401249|.FF75 E8 |push ;CM.004B4768
0040124C|.FF75 EC |push
0040124F|.B9 02000000 |mov ecx,0x2
00401254|.E8 16FEFFFF |call CM.0040106F
00401259|.83C4 08 |add esp,0x8
0040125C|.8945 E4 |mov ,eax
0040125F|.8B5D E8 |mov ebx, ;CM.004B4768
00401262|.85DB |test ebx,ebx
00401264|.74 09 |je short CM.0040126F
00401266|.53 |push ebx
00401267|.E8 E0130000 |call CM.0040264C
0040126C|.83C4 04 |add esp,0x4
0040126F|>8B45 E4 |mov eax,
00401272|.50 |push eax
00401273|.8B5D EC |mov ebx,
00401276|.85DB |test ebx,ebx
00401278|.74 09 |je short CM.00401283
0040127A|.53 |push ebx
0040127B|.E8 CC130000 |call CM.0040264C
00401280|.83C4 04 |add esp,0x4
00401283|>58 |pop eax ;CM.0041B8C0
00401284|.8945 EC |mov ,eax
00401287|>5B |pop ebx ;CM.0041B8C0
00401288|.59 |pop ecx ;CM.0041B8C0
00401289|.^ E9 65FFFFFF \jmp CM.004011F3
0040128E|>83C4 08 add esp,0x8
00401291|.B8 413C4800 mov eax,CM.00483C41 ;ASCII "1111000011000101100001001101001"
00401296|.8945 E8 mov ,eax
00401299|.8D45 E8 lea eax,
0040129C|.50 push eax
0040129D|.8D45 EC lea eax,
004012A0|.50 push eax
004012A1|.E8 74020000 call CM.0040151A // 将两个文本形式的二进制进行xor(异或)004012A6|.8945 E4 mov ,eax004012A9|.8B5D E8 mov ebx, ;CM.004B4768
004012AC|.85DB test ebx,ebx
004012AE|.74 09 je short CM.004012B9
004012B0|.53 push ebx
004012B1|.E8 96130000 call CM.0040264C
004012B6|.83C4 04 add esp,0x4
004012B9|>8D45 E4 lea eax,
004012BC|.50 push eax
004012BD|.E8 E5060000 call CM.004019A7 // 将上一步结果进行not(取反)
004012C2|.8945 E0 mov ,eax
004012C5|.8B5D E4 mov ebx,
004012C8|.85DB test ebx,ebx
004012CA|.74 09 je short CM.004012D5
004012CC|.53 push ebx
004012CD|.E8 7A130000 call CM.0040264C
004012D2|.83C4 04 add esp,0x4
004012D5|>68 04000080 push 0x80000004
004012DA|.6A 00 push 0x0
004012DC|.8B45 E0 mov eax, ;CM.004B4768
004012DF|.85C0 test eax,eax
004012E1|.75 05 jnz short CM.004012E8
004012E3|.B8 403C4800 mov eax,CM.00483C40
004012E8|>50 push eax
004012E9|.68 01000000 push 0x1
004012EE|.BB 702A4000 mov ebx,CM.00402A70
004012F3|.E8 66130000 call CM.0040265E
004012F8|.83C4 10 add esp,0x10
004012FB|.8945 DC mov ,eax
004012FE|.8B5D E0 mov ebx, ;CM.004B4768
00401301|.85DB test ebx,ebx
00401303|.74 09 je short CM.0040130E
00401305|.53 push ebx
00401306|.E8 41130000 call CM.0040264C
0040130B|.83C4 04 add esp,0x4
0040130E|>B8 613C4800 mov eax,CM.00483C61 ;ASCII "Shiny"
00401313|.8945 D8 mov ,eax
00401316|.8D45 D8 lea eax,
00401319|.50 push eax
0040131A|.8D45 DC lea eax,
0040131D|.50 push eax
0040131E|.E8 3E090000 call CM.00401C61 // 将上一步结果进行加密 "Shiny"为加密密钥 得到密文文本
00401323|.8945 D4 mov ,eax
00401326|.8B5D DC mov ebx,
00401329|.85DB test ebx,ebx
0040132B|.74 09 je short CM.00401336
0040132D|.53 push ebx
0040132E|.E8 19130000 call CM.0040264C
00401333|.83C4 04 add esp,0x4
00401336|>8B5D D8 mov ebx, ;CM.004B4768
00401339|.85DB test ebx,ebx
0040133B|.74 09 je short CM.00401346
0040133D|.53 push ebx
0040133E|.E8 09130000 call CM.0040264C
00401343|.83C4 04 add esp,0x4
00401346|>68 673C4800 push CM.00483C67 ;ASCII "ga!a~a!aPaba7a2aYaNamaXaXa2aJawaSaVaPa5ataQaQaIa1aCaDaFayaiaIaAa"
0040134B|.FF75 D4 push
0040134E|.E8 78FDFFFF call CM.004010CB // 加密结果与"ga!a~a!aPaba7a2aYaNamaXaXa2aJawaSaVaPa5ataQaQaIa1aCaDaFayaiaIaAa"进行比较
00401353|.83C4 08 add esp,0x8
00401356|.83F8 00 cmp eax,0x0
00401359|.B8 00000000 mov eax,0x0
0040135E|.0F94C0 sete al
00401361|.8945 D0 mov ,eax
00401364|.8B5D D4 mov ebx,
00401367|.85DB test ebx,ebx
00401369|.74 09 je short CM.00401374
0040136B|.53 push ebx
0040136C|.E8 DB120000 call CM.0040264C
00401371|.83C4 04 add esp,0x4
00401374|>837D D0 00 cmp ,0x0
00401378|.0F84 E3000000 je CM.00401461
0040137E|.6A FF push -0x1
00401380|.6A 08 push 0x8
00401382|.68 35000116 push 0x16010035
00401387|.68 01000152 push 0x52010001
0040138C|.E8 D3120000 call CM.00402664
00401391|.83C4 10 add esp,0x10
00401394|.8945 E8 mov ,eax
00401397|.8D45 E8 lea eax,
0040139A|.50 push eax
0040139B|.B8 A83C4800 mov eax,CM.00483CA8 ;ASCII "adqd*bldMb^backdJcbd(bhdod"
004013A0|.8945 E4 mov ,eax
004013A3|.8D45 E4 lea eax,
004013A6|.50 push eax
004013A7|.E8 070D0000 call CM.004020B3 // 以注册码为密钥 解密"adqd*bldMb^backdJcbd(bhdod" 得到的结果作为成功信息框的文本内容
004013AC|.8945 E0 mov ,eax
004013AF|.8B5D E4 mov ebx,
004013B2|.85DB test ebx,ebx
004013B4|.74 09 je short CM.004013BF
004013B6|.53 push ebx
004013B7|.E8 90120000 call CM.0040264C
004013BC|.83C4 04 add esp,0x4
004013BF|>8B5D E8 mov ebx, ;CM.004B4768
004013C2|.85DB test ebx,ebx
004013C4|.74 09 je short CM.004013CF
004013C6|.53 push ebx
004013C7|.E8 80120000 call CM.0040264C
004013CC|.83C4 04 add esp,0x4
004013CF|>68 05000080 push 0x80000005
004013D4|.6A 00 push 0x0
004013D6|.8B45 E0 mov eax, ;CM.004B4768
004013D9|.85C0 test eax,eax
004013DB|.75 05 jnz short CM.004013E2
004013DD|.B8 C33C4800 mov eax,CM.00483CC3
004013E2|>50 push eax
004013E3|.68 01000000 push 0x1
004013E8|.BB A02E4000 mov ebx,CM.00402EA0
004013ED|.E8 6C120000 call CM.0040265E
004013F2|.83C4 10 add esp,0x10
004013F5|.8945 DC mov ,eax
004013F8|.8B5D E0 mov ebx, ;CM.004B4768
004013FB|.85DB test ebx,ebx
004013FD|.74 09 je short CM.00401408
004013FF|.53 push ebx
00401400|.E8 47120000 call CM.0040264C
00401405|.83C4 04 add esp,0x4
00401408|>6A 00 push 0x0
0040140A|.6A 00 push 0x0
0040140C|.6A 00 push 0x0
0040140E|.68 04000080 push 0x80000004
00401413|.6A 00 push 0x0
00401415|.68 CB3C4800 push CM.00483CCB
0040141A|.68 01030080 push 0x80000301
0040141F|.6A 00 push 0x0
00401421|.68 40000000 push 0x40
00401426|.68 04000080 push 0x80000004
0040142B|.6A 00 push 0x0
0040142D|.8B45 DC mov eax,
00401430|.85C0 test eax,eax
00401432|.75 05 jnz short CM.00401439
00401434|.B8 403C4800 mov eax,CM.00483C40
00401439|>50 push eax
0040143A|.68 04000000 push 0x4
0040143F|.BB B02F4000 mov ebx,CM.00402FB0
00401444|.E8 15120000 call CM.0040265E // 弹出信息框
00401449|.83C4 34 add esp,0x34
0040144C|.8B5D DC mov ebx,
0040144F|.85DB test ebx,ebx
00401451|.74 09 je short CM.0040145C
00401453|.53 push ebx
00401454|.E8 F3110000 call CM.0040264C
00401459|.83C4 04 add esp,0x4
0040145C|>E9 3C000000 jmp CM.0040149D
00401461|>6A 00 push 0x0
00401463|.6A 00 push 0x0
00401465|.6A 00 push 0x0
00401467|.68 04000080 push 0x80000004
0040146C|.6A 00 push 0x0
0040146E|.68 CB3C4800 push CM.00483CCB
00401473|.68 01030080 push 0x80000301
00401478|.6A 00 push 0x0
0040147A|.68 40000000 push 0x40
0040147F|.68 04000080 push 0x80000004
00401484|.6A 00 push 0x0
00401486|.68 D13C4800 push CM.00483CD1 ;ASCII "失败"
0040148B|.68 04000000 push 0x4
00401490|.BB B02F4000 mov ebx,CM.00402FB0
00401495|.E8 C4110000 call CM.0040265E
0040149A|.83C4 34 add esp,0x34
0040149D|>8B5D EC mov ebx,
004014A0|.85DB test ebx,ebx
004014A2|.74 09 je short CM.004014AD
004014A4|.53 push ebx
004014A5|.E8 A2110000 call CM.0040264C
004014AA|.83C4 04 add esp,0x4
004014AD|>8BE5 mov esp,ebp
004014AF|.5D pop ebp ;CM.0041B8C0
004014B0\.C3 retn
跟踪过程
假码出现
整数型假码
二进制文本
箭头所指即为 666666的二进制 此时准备进行异或
00401291|.B8 413C4800 mov eax,CM.00483C41 ;ASCII "1111000011000101100001001101001"
0018F5D4 00660690ASCII "10100010110000101010"
箭头所指为上一步异或结果 此时准备进行取反
0018F5D4 0065B3E0ASCII "1111000011010001110111001000011"
箭头所指为加密密钥与上一步取反结果 准备进行加密
0018F5B4 0027E240ASCII "10000111100101110001000110111100"
箭头所指为上一补加密结果 与程序内文本进行比较
0018F5B8 0027D5A0ASCII "ga!a!a!aPaba8a2aZaManaWaXa1aIaxaSaUaOa6ataRaRaIa1aCaDaFazajaJaBa"
0018F5BC 00483C67ASCII "ga!a~a!aPaba7a2aYaNamaXaXa2aJawaSaVaPa5ataQaQaIa1aCaDaFayaiaIaAa"
相同则进行后续解码文本 不同则弹出失败信息框
由于存在以注册码为密钥进行解密的操作 所以此CrackMe只能Keygen实现破解
解密信息框文本前对注册码进行了校验 表明CrackMe的真码只有一个
从最后的文本比较开始入手 注册码计算结果与"ga!a~a!aPaba7a2aYaNamaXaXa2aJawaSaVaPa5ataQaQaIa1aCaDaFayaiaIaAa"比较
可以看到 文本长度为64 且文本中双数位上都是'a' 将'a'删除后得
"g!~!Pb72YNmXX2JwSVP5tQQI1CDFyiIA"
长度为32 而最后注册码加密前长度也是32
以此猜想 加密前的二进制每一位0/1与加密后的文本对应 如果某一位上的文本与程序内文本不同 则对应二进制上的位也不同
可以直接对比加密后的文本 从而找到假码与真码不同的位置
构造假码:
1. 使加密前二进制为
11111111111111111111111111111111
2. 取反
00000000000000000000000000000000
3. 与 1111000011000101100001001101001 (0x7862C269) 异或
1111000011000101100001001101001
4. 转为十进制
2019738217
输入假码后再次跟踪 过程中出现的中间变量如下
1. 转换为二进制
0018F5D4 0028B458ASCII "1111000011000101100001001101001"
2. 异或
0018F5D4 0028B458ASCII "0000000000000000000000000000000"
3. 取反
0018F5B4 0027E1E0ASCII "11111111111111111111111111111111"
4. 加密
0018F5B8 0027D5A0ASCII "ga~a~a~aOaba8a2aZaNamaWaWa1aIaxaTaVaPa6asaQaQaIa1aDaDaFazajaIaAa"
将删去'a'的两个文本进行比较
真码 "g!~!Pb72YNmXX2JwSVP5tQQI1CDFyiIA"
假码 "g~~~Ob82ZNmWW1IxTVP6sQQI1DDFzjIA"
所示假码中第2 4 5 7 9 11 12 13 14 15 16 19 20 25 26 28 29位与真码不同 再次构造假码
1. 使加密前二进制为
10100101011000000110011110110011
2. 取反
1011010100111111001100001001100
3. 与 1111000011000101100001001101001 (0x7862C269) 异或
100010111111010101101000100101
4. 转为十进制
587029029
输入第二次构造的假码 破解成功
原CrackMe下载:
本帖最后由 闲月疏云 于 2016-3-19 18:32 编辑
给KeyGen过程点赞。不过在真正的软件中,以注册码为密匙进行加密的手法真的会用到吗…… 厉害 赞一个 前排膜拜靶子大牛,羡慕算法分析的这么好的 这个帖子的确经典 赞赞赞!!! 支持原创 pizza!!
页:
[1]