欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

弥补CCDebuger的遗憾

程序员文章站 2024-01-14 17:44:04
作者:KYO=================================== 玩破解 作者:KYO=================================== 作者:KYO===================================...

作者:KYO
===================================

破解的朋友大多都读过CCDebuger的大作OllyDBG入门系列,从第一章到第七章都是篇篇经典。当然,他这几篇文章也给我带来了很大的帮助。当我看到《OllyDBG 入门系列(五)-消息断点及RUN跟踪》这篇文章时(地址http://bbs.pediy.com/showthread.php?t=21532),在文中最后,CCDebuger留下这么一句话:“准备跟踪算法时,才发现这个 crackme 还是挺复杂的,具体算法我就不写了,实在没那么多时间详细跟踪”。可能大虾的确是太忙了,所以我就想利用空闲时间分析一下这个CrackMe的算法,也算是弥补大虾留下的遗憾吧。
当我跟了个把小时后发现,这个算法的确是比较难的,我也没有太多的时间能写出完美的算法注册机(或者说我没那个能力),不过我倒是发现一个小小的BUG,反正写注册机不成问题了。下面我把我的思路给大家分享一下。
前面的如何下断点CCDebuger已经写的很明白了,如果大家还有什么疑问可以到看雪看那篇文章。我们直接打开 RUN 跟踪,添加“所有函数过程的入口”后再回到程序中点“Check”按钮,这时在 OllyDBG 中打开 RUN 跟踪记录就可以找到关键位置,然后就可以在这个位置下断。程序就被断在这里。

004010E2 |. 8BFE MOV EDI,ESI
;用户名送入edi
004010E4 |. 03F8 ADD EDI,EAX
004010E6 |. FC CLD
004010E7 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
004010E9 |. 33C9 XOR ECX,ECX
;清0,设循环计数器
004010EB |. BE 71214000 MOV ESI,cycle.00402171
;注册码送入ESI
004010F0 |> 41 /INC ECX
004010F1 |. AC |LODS BYTE PTR DS:[ESI]
;取注册码的每个字符
004010F2 |. 0AC0 |OR AL,AL
004010F4 |. 74 0A |JE SHORT cycle.00401100
004010F6 |. 3C 7E |CMP AL,7E
;判断字符是否为非ASCII字符
004010F8 |. 7F 06 |JG SHORT cycle.00401100
004010FA |. 3C 30 |CMP AL,30
;判断是否小30H
004010FC |. 72 02 |JB SHORT cycle.00401100
004010FE |.^ EB F0 JMP SHORT cycle.004010F0
00401100 |> 83F9 11 CMP ECX,11
;比较注册码位数,必须为17位。不过这里程序把最后的0x00也算进去了,其实注册码只要为16位长即可。

程序到这里主要限制了上面注释的这么几点,并且用户名做了处理。它采用复制的方法扩展到16位。例如我输入kyo327,扩展以后就是kyo327kyo327kyo3。下面接着按F8走,可以来到下面的代码处。

00401105 |. E8 E7000000  CALL cycle.004011F1
;算法CALL
0040110A |. B9 01FF0000  MOV ECX,0FF01
0040110F |. 51  PUSH ECX
00401110 |. E8 7B000000  CALL cycle.00401190
;算法CALL,如果ECX不等于1将会跳向失败
00401115 |. 83F9 01  CMP ECX,1
00401118 |. 74 06  JE SHORT cycle.00401120
0040111A |> E8 47000000  CALL cycle.00401166
0040111F |> C3  RET
00401120 |> A1 68214000  MOV EAX,DWORD PTR DS:[402168]
;取用户名第9到第12位=user[9-12]
00401125 |. 8B1D 6C214000 MOV EBX,DWORD PTR DS:[40216C]
;取用户名第13到第16位=user[13-16]
0040112B |. 33C3  XOR EAX,EBX
;user[9-12] xor user[13-16]
0040112D |. 3305 82214000 XOR EAX,DWORD PTR DS:[402182]
00401133 |. 0D 40404040  OR EAX,40404040
00401138 |. 25 77777777  AND EAX,77777777
0040113D |. 3305 79214000 XOR EAX,DWORD PTR DS:[402179]
;eax xor注册码第9到第12位
00401143 |. 3305 7D214000 XOR EAX,DWORD PTR DS:[40217D]
;eax xor 注册码第13到第16位,XOR以后只有EAX=0才能跳向成功
00401149 |.^ 75 CF  JNZ SHORT cycle.0040111A
0040114B |. E8 2B000000  CALL cycle.0040117B
00401150 . C3  RET

现在从上面代码分析一下程序注册成功的条件。
1)(User[9-12] xor user[13-16]) xor ds:[00402182]=X1
2)(((X1 or 40404040) and 77777777) xor sn[9-12]) xor sn[13-16]=Y1
由此可以推出只有Y1=0才能注册成功。不过现在未知数还是挺多的,首先ds:[00402182]是未知的,sn[9-12]、sn[13-16]也是未知的。现在假设ds:[00402182]是已知的,并设为P1,那么只要等式(X1 or 40404040) and 77777777= sn[9-12]) xor sn[13-16]成立就OK。现在当务之急就是找找ds:[00402182]是从哪里冒出来的。
向上拖一下代码,在0040109c处发现这么一句:“mov dword ptr ds:[402182],fedcba98”,看来这里首先给了一个定值。在命令框输入“dd 00402182”,可以看到HEX数据为fedcba98,就是刚才程序赋给的值,然后按F8慢慢走,看这个值在哪里会发生变化。一直走到00401115处后发现fedcba98变化了,原因就是经过了“call 00401190”。看来要找答案还得F7进“call 00401190”看看。进去这个CALL后发现有两个参数,eax和ebx分别赋给了某个寄存器值,然后参与了运算,而这两个参数的值也是莫名其妙的。接着往上看看,这才明白是“call 004011f1”这个重要的算法CALL在作怪,就是这个CALL以后才有了eax和ebx这两个莫名其妙的值。现在从头来过,到了00401105时F7进去看看吧。

004011F1 /$ A1 60214000 MOV EAX,DWORD PTR DS:[402160]
;取用户名前4位=user[1-4]
004011F6 |. 8B1D 64214000 MOV EBX,DWORD PTR DS:[402164]
;取用户名第5位到第8位
004011FC |. 3305 71214000 XOR EAX,DWORD PTR DS:[402171]
;User[1-4] xor sn[1-4]=k1
00401202 |. 331D 75214000 XOR EBX,DWORD PTR DS:[402175]
;User[5-8] xor sn[5-8]=k2
00401208 |. 25 0F1F3F7F  AND EAX,7F3F1F0F
;K1 and 7f3f1f0f=p1
0040120D |. 81E3 00010307 AND EBX,7030100
;K2 and 7030100=p2
00401213 |. 33C9  XOR ECX,ECX
;用ECX做循环
00401215 |> 8BF0  /MOV ESI,EAX
00401217 |. 8BFB  |MOV EDI,EBX
00401219 |. D3E6  |SHL ESI,CL
0040121B |. D3E7  |SHL EDI,CL
0040121D |. 81E6 80808080 |AND ESI,80808080
00401223 |. 81E7 80808080 |AND EDI,80808080
00401229 |. 8BD6  |MOV EDX,ESI
0040122B |. C0EE 07    |SHR DH,7
0040122E |. 66:C1E2 07  |SHL DX,7
00401232 |. C1EA 08    |SHR EDX,8
00401235 |. C0EE 07    |SHR DH,7
00401238 |. 66:C1E2 07  |SHL DX,7
0040123C |. C1EA 08    |SHR EDX,8
0040123F |. C0EE 07    |SHR DH,7
00401242 |. 66:D1EA    |SHR DX,1
00401245 |. 8BF2  |MOV ESI,EDX
00401247 |. 8BD7  |MOV EDX,EDI
00401249 |. C0EE 07    |SHR DH,7
0040124C |. 66:C1E2 07  |SHL DX,7
00401250 |. C1EA 08    |SHR EDX,8
00401253 |. C0EE 07    |SHR DH,7
00401256 |. 66:C1E2 07  |SHL DX,7
0040125A |. C1EA 08    |SHR EDX,8
0040125D |. C0EE 07    |SHR DH,7
00401260 |. 66:C1EA 05  |SHR DX,5
00401264 |. 8BFA  |MOV EDI,EDX
00401266 |. 33FE  |XOR EDI,ESI
00401268 |. 8BD7  |MOV EDX,EDI
0040126A |. 81E2 FF000000 |AND EDX,0FF
;上面都是p1 p2参与运算
00401270 |. 51   |PUSH ECX
00401271 |. 52   |PUSH EDX
00401272 |. BA 08000000  |MOV EDX,8
00401277 |. 91   |XCHG EAX,ECX
00401278 |. 83F8 03    |CMP EAX,3
0040127B |. 7F 0F  |JG SHORT cycle.0040128C
0040127D |. F6E2  |MUL DL
0040127F |. 5A   |POP EDX
00401280 |. 83C0 08    |ADD EAX,8
00401283 |. 91   |XCHG EAX,ECX
00401284 |. D3C0  |ROL EAX,CL
00401286 |. 33C2  |XOR EAX,EDX
00401288 |. D3C8  |ROR EAX,CL
0040128A |. EB 0D  |JMP SHORT cycle.00401299
0040128C |> 83E8 03    |SUB EAX,3
0040128F |. F6E2  |MUL DL
00401291 |. 5A   |POP EDX
00401292 |. 91   |XCHG EAX,ECX
00401293 |. D3C3  |ROL EBX,CL
00401295 |. 33DA  |XOR EBX,EDX
00401297 |. D3CB  |ROR EBX,CL
00401299 |> 59   |POP ECX
0040129A |. 41   |INC ECX
0040129B |. 83