新手之家 │有问必答│     我要上雅虎首页    我也使用这个模板 http://i.cn.yahoo.com/03003734155 复制 收藏

史密斯
史密斯 史密斯 史密斯
  • 当前所在地:美国 Iowa
  • 最高学历:博士
  • 婚姻状况:未婚

史密斯不在你的朋友圈

更新时间:2008年10月15日 注册时间:2007年5月

访问量

38,958

“如果你是优秀的黑客,山姆大叔现在需要你加入美国军队。” 查看更多

[精] 华盟解密游戏第四期通关手记
2007-09-16 17:50:53

华盟解密游戏 第四期 通关手记
游戏地址:
http://crack.77169.com/
第四期入口:
http://crack.77169.com/v4/go.html
难度:很难很难……

第一关:
地址:stage1.html
密码:77169
    在 MSVBVM60 的 _vbaStrComp 处下断点,程序会停留在:

660E8A03 M>  FF7424 08          push dword ptr ss:[esp+8]
    此时堆栈中能看到明文密码:77169,而跟用户名无关。

第二关:
地址:77169.html
密码:40121570(124315391)
    看到错误密码提示框中提示“重来撒....”,于是搜索“....”字串,在 00467976 处找到。向上一点有几个 je,分别下断。再次运行,程序停留在 0046790B 处的 je 时,堆栈中显示出密码为:40121570。

第三关:
地址:40121570.html
密码:77huaxia169(huaxia)
    Flash 对我来说就没难度了,先把 exe 脱成 swf,然后用 ASV 查看,发现 if (((77 + name) + 169) == key) 的判断,因此密码为用户名前缀77再后缀169。

第四关:
地址:77huaxia169.html
密码:2006250(123456)
    由于只能输入数字,估计是要对输入的数字做运算。在 GetWindowsTextA 处下断点,程序停在 MFC42D 的 5F42E176 处。回到主程序领空后,果然对输入字串分别进行了 atoi 操作,之后 00401A87 的 jnz 为关键判断跳转,00401A99 为失败地址,00401A89 为成功地址,程序代码如下:
00401A1A   |.  E8 6F030000      call
00401A1F   |.  8D4D E8          lea ecx,dword ptr ss:[ebp-18]
00401A22   |.  51               push ecx
00401A23   |.  8B4D F0          mov ecx,dword ptr ss:[ebp-10]
00401A26   |.  81C1 A0000000    add ecx,0A0
00401A2C   |.  E8 5D030000      call
00401A31   |.  8D4D EC          lea ecx,dword ptr ss:[ebp-14]
00401A34   |.  E8 4F030000      call
00401A39   |.  8BF4             mov esi,esp
00401A3B   |.  50               push eax                                         ; /s
00401A3C   |.  FF15 30764100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
00401A42   |.  83C4 04          add esp,4
00401A45   |.  3BF4             cmp esi,esp
00401A47   |.  E8 4E030000      call
00401A4C   |.  8D9400 712D0100  lea edx,dword ptr ds:[eax+eax+12D71]
00401A53   |.  8955 E4          mov dword ptr ss:[ebp-1C],edx
00401A56   |.  8D4D E8          lea ecx,dword ptr ss:[ebp-18]
00401A59   |.  E8 2A030000      call
00401A5E   |.  8BF4             mov esi,esp
00401A60   |.  50               push eax                                         ; /s
00401A61   |.  FF15 30764100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
00401A67   |.  83C4 04          add esp,4
00401A6A   |.  3BF4             cmp esi,esp
00401A6C   |.  E8 29030000      call
00401A71   |.  99               cdq
00401A72   |.  B9 0A000000      mov ecx,0A
00401A77   |.  F7F9             idiv ecx
00401A79   |.  05 40E20100      add eax,1E240
00401A7E   |.  8945 E0          mov dword ptr ss:[ebp-20],eax
00401A81   |.  8B55 E4          mov edx,dword ptr ss:[ebp-1C]
00401A84   |.  3B55 E0          cmp edx,dword ptr ss:[ebp-20]
00401A87   |.  75 10            jnz short 4.00401A99
00401A89   |.  6A 00            push 0
00401A8B   |.  6A 00            push 0
00401A8D   |.  68 A4524100      push 4.004152A4
00401A92   |.  E8 EB020000      call
00401A97   |.  EB 0E            jmp short 4.00401AA7
00401A99   |>  6A 00            push 0
00401A9B   |.  6A 00            push 0
00401A9D   |.  68 8C524100      push 4.0041528C
00401AA2   |.  E8 DB020000      call
    其中 00401A1A 和 00401A2C 是两次 GetWindowsTextA,之后是两次 atoi。从 00401A87 处的 jnz 向上可以看到,最终的关键比较是比较 ebp-1C 和 ebp-20 中的值,而 ebp-20 的值是 eax 传给的。在这之前,eax 的值在 00401A61 的 atoi 过后,变为输入密码的 int 值,之后 00401A72 和 00401A77 将该值除以 10,00401A79 又将其再加上 1E240。另一方面,ebp-1C 的值在 00401A4C、00401A4C 和 00401A53 处由 eax+eax+12D71 赋予,而 eax 的值在 00401A3C 的 atoi 之后变为输入用户名的 int 值。因此整理得到,只需 用户名 + 用户名 + 12D71 = ( 密码 / 10 ) + 1E240 的等式成立即可。即当用户名为“123456”时,密码 = ( 123456 + 123456 + 0x12D71 - 0x1E240 ) * 10 = 2006250。有意思的是,0x12D71 就是 77169,而 0x1E240 就是 123456。

第五关:
地址:2006250.html
密码:7777777777(372852712)
    由错误提示:“再试试吧....”查找字符串“....”,位置在 004678A0。向上找到 00467788 的 push ebp,就是程序入口。下面部分代码如下:
004677B1   |.  E8 DEBDFCFF      call 5.00433594
004677B6   |.  8D55 F8          lea edx,dword ptr ss:[ebp-8]
004677B9   |.  8B83 00030000    mov eax,dword ptr ds:[ebx+300]
004677BF   |.  E8 D0BDFCFF      call 5.00433594
两次 call 5.00433594 分别读取输入的用户名和密码
004677C4   |.  8B45 FC          mov eax,dword ptr ss:[ebp-4]
004677C7   |.  E8 40C9F9FF      call 5.0040410C
004677CC   |.  8BD8             mov ebx,eax
004677CE   |.  8B45 F8          mov eax,dword ptr ss:[ebp-8]
004677D1   |.  E8 36C9F9FF      call 5.0040410C
两次 call 5.0040410C 分别计算用户名和密码的长度
004677D6   |.  8BF0             mov esi,eax
004677D8   |.  8BC3             mov eax,ebx
004677DA   |.  F7EB             imul ebx
004677DC   |.  8945 E4          mov dword ptr ss:[ebp-1C],eax
计算用户名长度的平方
004677DF   |.  DB45 E4          fild dword ptr ss:[ebp-1C]
004677E2   |.  DD5D F0          fstp qword ptr ss:[ebp-10]
004677E5   |.  9B               wait
004677E6   |.  33C0             xor eax,eax
004677E8   |.  8945 E8          mov dword ptr ss:[ebp-18],eax
004677EB   |.  8945 EC          mov dword ptr ss:[ebp-14],eax
004677EE   |.  837D FC 00       cmp dword ptr ss:[ebp-4],0
004677F2   |.  74 29            je short 5.0046781D
004677F4   |.  8BC3             mov eax,ebx
004677F6   |.  85C0             test eax,eax
004677F8   |.  7E 23            jle short 5.0046781D
当用户名为空的时候跳过对用户名的处理
004677FA   |.  BA 01000000      mov edx,1
004677FF   |>  8B4D FC       /  mov ecx,dword ptr ss:[ebp-4]
00467802   |.  8A4C11 FF     |  mov cl,byte ptr ds:[ecx+edx-1]
00467806   |.  81E1 FF000000 |  and ecx,0FF
0046780C   |.  894D E4       |  mov dword ptr ss:[ebp-1C],ecx
0046780F   |.  DB45 E4       |  fild dword ptr ss:[ebp-1C]
注意第一次循环时,基数为用户名长度的平方
00467812   |.  DC45 F0       |  fadd qword ptr ss:[ebp-10]
00467815   |.  DD5D F0       |  fstp qword ptr ss:[ebp-10]
00467818   |.  9B            |  wait
00467819   |.  42            |  inc edx
0046781A   |.  48            |  dec eax
0046781B   |.^ 75 E2         \  jnz short 5.004677FF
对用户名逐位的AscII码进行累加
0046781D   |>  8BC6             mov eax,esi
0046781F   |.  85C0             test eax,eax
00467821   |.  7E 23            jle short 5.00467846
当密码为空的时候跳过对密码的处理
00467823   |.  BA 01000000      mov edx,1
00467828   |>  8B4D F8       /  mov ecx,dword ptr ss:[ebp-8]
0046782B   |.  8A4C11 FF     |  mov cl,byte ptr ds:[ecx+edx-1]
0046782F   |.  81E1 FF000000 | and ecx,0FF
00467835   |.  894D E4       | mov dword ptr ss:[ebp-1C],ecx
00467838   |.  DB45 E4       | fild dword ptr ss:[ebp-1C]
0046783B   |.  DC45 E8       | fadd qword ptr ss:[ebp-18]
0046783E   |.  DD5D E8       | fstp qword ptr ss:[ebp-18]
00467841   |.  9B            | wait
00467842   |.  42            | inc edx
00467843   |.  48            | dec eax
00467844   |.^ 75 E2         \ jnz short 5.00467828
对密码逐位的AscII码进行累加,基数为 0
00467846   |>  DD45 F0          fld qword ptr ss:[ebp-10]
00467849   |.  DC5D E8          fcomp qword ptr ss:[ebp-18]
关键比较,比较用户名和密码的AscII码累加结果
0046784C   |.  DFE0             fstsw ax
0046784E   |.  9E               sahf
0046784F   |.  74 0C            je short 5.0046785D
如果比较不等则跳转到失败地址,下面是成功地址
00467851   |.  B8 98784600      mov eax,5.00467898
00467856   |.  E8 61FFFBFF      call 5.004277BC
0046785B   |.  EB 0A            jmp short 5.00467867
下面是失败地址
0046785D   |>  B8 B0784600      mov eax,5.004678B0
00467862   |.  E8 55FFFBFF      call 5.004277BC
    由此可知,注册算法为:用户名长度平方 + 用户名逐位AscII码累加和 = 密码逐位AscII码累加和。因此按网页上的要求,用户名为 372852712 时,长度平方加AscII码累加和为 550,长度为10位的密码,平均每位为55,即“7”的AscII码。所以密码为10个“7”。
    有意思的是,用户名密码均为空时,也可以通过注册。

第六关:
地址:7777777777.html
密码:77254995(38588913)
    先运行了一下试了试,发现只有当用户名、密码均为数字时才有反应,所以估计是要转换成数字做运算。看了看失败提示,打开 OD 搜索失败字符串,没有搜到。没关系,直接找,很快在 0040A1B0 处发现程序入口,下断点一试,果然停了下来。
    单步向下,在 0040A24B 处 EAX 中出现了用户名字串,且后面果然有 MSVBVM60.rtcIsNumeric 的判断。再向下 0040A2C0 处 EAX 中出现了密码字串,且后面又是 MSVBVM60.rtcIsNumeric。继续单步,出现下面的一系列代码:
0040A335    .  8B4D D4          mov ecx,dword ptr ss:[ebp-2C]
这步之后,ECX 中再次出现用户名字串,估计是要开始运算了
0040A338    .  51               push ecx
0040A339    .  FF15 38104000    call dword ptr ds:[<&MSVBVM60.__vbaCyStr>]       ;  MSVBVM60.__vbaCyStr
开始我还一直注意着寄存器里有没有 38588913 的16进制值 24CD1F1,一直没有发现,还在郁闷呢,后来查了一下 vbaCyStr 这个函数,发现是把字符串转换成 Currency 类型,即转换成整型后乘以 10000。经过此步,EAX 中为 D8C8D610,EDX 中为 00000059。注:385889130000 = 0x59D8C8D610。
0040A33F    .  8D4D D4          lea ecx,dword ptr ss:[ebp-2C]
0040A342    .  8BF8             mov edi,eax
0040A344    .  8BDA             mov ebx,edx
将结果转存
0040A346    .  FF15 B0104000    call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>]     ;  MSVBVM60.__vbaFreeStr
0040A34C    .  8D4D D0          lea ecx,dword ptr ss:[ebp-30]
0040A34F    .  FF15 AC104000    call dword ptr ds:[<&MSVBVM60.__vbaFreeObj>]     ;  MSVBVM60.__vbaFreeObj
0040A355    .  68 712D0100      push 12D71
0x12D71 = 77169
0040A35A    .  FF15 48104000    call dword ptr ds:[<&MSVBVM60.__vbaCyI4>]        ;  MSVBVM60.__vbaCyI4
这是把整数转换为 Currency 类型
0040A360    .  52               push edx
0040A361    .  50               push eax
0040A362    .  53               push ebx
0040A363    .  57               push edi
0040A364    .  6A 02            push 2
0040A366    .  FF15 78104000    call dword ptr ds:[<&MSVBVM60.__vbaCyMulI2>]     ;  MSVBVM60.__vbaCyMulI2
跟进去看是把 385889130000 * 2,结果为 0xB3 B191AC20
0040A36C    .  52               push edx
0040A36D    .  50               push eax
0040A36E    .  FF15 28104000    call dword ptr ds:[<&MSVBVM60.__vbaCyAdd>]       ;  MSVBVM60.__vbaCyAdd
再加上 771690000,结果为 0xB3 DF90BA30
0040A374    .  8BDA             mov ebx,edx
0040A376    .  8B16             mov edx,dword ptr ds:[esi]
0040A378    .  56               push esi
0040A379    .  8BF8             mov edi,eax
将结果转存后,EBX = 0xB3,EDI = 0xDF90BA30
    再往下就是对密码字串的处理:
0040A3B3    .  8B45 D4          mov eax,dword ptr ss:[ebp-2C]
这步之后,ECX 中出现密码字串
0040A3B6    .  50               push eax
0040A3B7    .  FF15 38104000    call dword ptr ds:[<&MSVBVM60.__vbaCyStr>]       ;  MSVBVM60.__vbaCyStr
同样将密码转换成 Currency 类型
0040A3BD    .  8D4D D4          lea ecx,dword ptr ss:[ebp-2C]
0040A3C0    .  8BF0             mov esi,eax
0040A3C2    .  8955 DC          mov dword ptr ss:[ebp-24],edx
将结果高位存入 ebp-24,低位存入 ESI
0040A3C5    .  FF15 B0104000    call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>]     ;  MSVBVM60.__vbaFreeStr
0040A3CB    .  8D4D D0          lea ecx,dword ptr ss:[ebp-30]
0040A3CE    .  FF15 AC104000    call dword ptr ds:[<&MSVBVM60.__vbaFreeObj>]     ;  MSVBVM60.__vbaFreeObj
0040A3D4    .  3BFE             cmp edi,esi
关键比较一:比较低位
0040A3D6    .  75 7D            jnz short 6.0040A455
0040A3D8    .  3B5D DC          cmp ebx,dword ptr ss:[ebp-24]
关键比较二:比较高位
0040A3DB    .  75 78            jnz short 6.0040A455
因此下面的 0040A3DD 就是成功入口,而 0040A455 就是失败地址。
    通过以上分析,可知注册算法为:用户名 * 10000 * 2 + 77169 * 10000 = 密码 * 10000。化简后为:密码 = 用户名 * 2 + 77169。其中用户名密码都必须为数字,小数也可以。
    因此,本关密码为:38588913 * 2 + 77169 = 77254995。

第七关:
地址:77254995.html
密码:leve7
    贪食蛇?我拿手,30000分还是很简单的嘛,1分钟搞定,下一关密码为:leve7。
    不过这个游戏明显有 Bug,当180°转弯按键太快的时候,会直接 Lose,这是因为蛇头还没有进入下一行就转弯了,程序就判断成和自己的身体撞上了。我第一次玩到 26000 分的时候,就这样被郁闷了,还好第二次就成功突破 30000 了。我在做 Flash 版的贪食蛇游戏的时候,就遇到了这个问题,应该做一下专门的判断,改为在下一行转弯。
    破解的方法也很容易,看到“本关KEY *******”,直接查找字串“*******”,在 004017AE 出发现:
004017A3   |.  817B 78 30750000 cmp dword ptr ds:[ebx+78],7530
这是关键比较,0x7530 不就是 30000 么
004017AA   |.  7D 09            jge short 7.004017B5
大于 30000 分则转向成功入口,下面则是失败入口
004017AC   |.  6A 07            push 7
004017AE   |.  68 A4904000      push 7.004090A4                                  ;  ASCII "*******"
004017B3   |.  EB 07            jmp short 7.004017BC
下面是成功入口
004017B5   |>  6A 05            push 5
004017B7   |.  68 9C904000      push 7.0040909C                                  ;  ASCII "leve7"
这个就是 KEY 啦

第八关:
地址:leve7.html
密码:152448380(59280880)
    还是先运行了一下,根据提示来看,肯定是写注册表了。试着输入用户名密码,发现又是只能输入数字。查看了一下程序的数据段,里面有“Software\Microsoft”、“regcode”、“name”等字串,于是简单注册了一下,果然在注册表 HKEY_CURRENT_USER\Software\Microsoft 项下,发现了 regcode 和 name 两项。通过几次小数字的注册(如用户名“2”,密码“1”之类的),很快发现 name = 用户名 * 2 + 77169,而 regcode = 密码 + 180346。虽然不知道注册表操作的断点是什么,但是猜测有输入数据的运算,所以在 atoi 处设断点。点击确定后,程序果然在 00401F90 处停了下来:
00401F6E   |.  E8 8B040000      call
读入用户名
00401F73   |.  8D4D E8          lea ecx,dword ptr ss:[ebp-18]
00401F76   |.  51               push ecx
00401F77   |.  8B4D F0          mov ecx,dword ptr ss:[ebp-10]
00401F7A   |.  81C1 A0000000    add ecx,0A0
00401F80   |.  E8 79040000      call
读入密码
00401F85   |.  8D4D EC          lea ecx,dword ptr ss:[ebp-14]
00401F88   |.  E8 6B040000      call
再次取出用户名
00401F8D   |.  8BF4             mov esi,esp
00401F8F   |.  50               push eax                                         ; /s
00401F90   |.  FF15 E4864100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
将用户名转换为整数
00401F96   |.  83C4 04          add esp,4
00401F99   |.  3BF4             cmp esi,esp
00401F9B   |.  E8 6A040000      call
00401FA0   |.  8D9400 712D0100  lea edx,dword ptr ds:[eax+eax+12D71]
很熟悉的算法吧,跟第六关的一样,乘 2 加 77169
00401FA7   |.  8955 E4          mov dword ptr ss:[ebp-1C],edx
00401FAA   |.  8D4D E8          lea ecx,dword ptr ss:[ebp-18]
00401FAD   |.  E8 46040000      call
去除密码
00401FB2   |.  8BF4             mov esi,esp
00401FB4   |.  50               push eax                                         ; /s
00401FB5   |.  FF15 E4864100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
将密码转换为整数
00401FBB   |.  83C4 04          add esp,4
00401FBE   |.  3BF4             cmp esi,esp
00401FC0   |.  E8 45040000      call
00401FC5   |.  05 7AC00200      add eax,2C07A
将密码加上 0x2C07A = 180346
00401FCA   |.  8945 E0          mov dword ptr ss:[ebp-20],eax
00401FCD   |.  8D4D DC          lea ecx,dword ptr ss:[ebp-24]
00401FD0   |.  E8 2F040000      call
00401FD5   |.  C645 FC 02       mov byte ptr ss:[ebp-4],2
00401FD9   |.  8D4D D8          lea ecx,dword ptr ss:[ebp-28]
00401FDC   |.  E8 23040000      call
00401FE1   |.  C645 FC 03       mov byte ptr ss:[ebp-4],3
00401FE5   |.  8B45 E4          mov eax,dword ptr ss:[ebp-1C]
00401FE8   |.  50               push eax
00401FE9   |.  68 4C534100      push 8.0041534C                                  ;  ASCII "%d"
00401FEE   |.  8D4D DC          lea ecx,dword ptr ss:[ebp-24]
00401FF1   |.  51               push ecx
00401FF2   |.  E8 FB030000      call
再将经过转换的用户名转换为字符串
00401FF7   |.  83C4 0C          add esp,0C
00401FFA   |.  8B55 E0          mov edx,dword ptr ss:[ebp-20]
00401FFD   |.  52               push edx
00401FFE   |.  68 4C534100      push 8.0041534C                                  ;  ASCII "%d"
00402003   |.  8D45 D8          lea eax,dword ptr ss:[ebp-28]
00402006   |.  50               push eax
00402007   |.  E8 E6030000      call
将经过转换的密码转换为字符串
0040200C   |.  83C4 0C          add esp,0C
0040200F   |.  8D4D DC          lea ecx,dword ptr ss:[ebp-24]
00402012   |.  E8 E1030000      call
00402017   |.  8945 D4          mov dword ptr ss:[ebp-2C],eax
0040201A   |.  C705 A46D4100 0C>mov dword ptr ds:[416DA4],8.0041520C             ;  ASCII "name"
00402024   |.  8B4D D4          mov ecx,dword ptr ss:[ebp-2C]
00402027   |.  890D A06D4100    mov dword ptr ds:[416DA0],ecx
0040202D   |.  8B15 A06D4100    mov edx,dword ptr ds:[416DA0]
00402033   |.  52               push edx
00402034   |.  A1 A46D4100      mov eax,dword ptr ds:[416DA4]
00402039   |.  50               push eax
0040203A   |.  8B0D AC6D4100    mov ecx,dword ptr ds:[416DAC]                    ;  8.00415220
00402040   |.  51               push ecx
00402041   |.  8B15 B06D4100    mov edx,dword ptr ds:[416DB0]
00402047   |.  52               push edx
00402048   |.  E8 03F0FFFF      call 8.00401050
将转换后的用户名写入注册表
0040204D   |.  83C4 10          add esp,10
00402050   |.  85C0             test eax,eax
00402052   |.  74 0E            je short 8.00402062
判断是否写入成功
00402054   |.  6A 00            push 0
00402056   |.  6A 00            push 0
00402058   |.  68 3C534100      push 8.0041533C
0040205D   |.  E8 34020000      call
00402062   |>  8D4D D8          lea ecx,dword ptr ss:[ebp-28]
00402065   |.  E8 8E030000      call
0040206A   |.  8945 D0          mov dword ptr ss:[ebp-30],eax
0040206D   |.  C705 A46D4100 14>mov dword ptr ds:[416DA4],8.00415214             ;  ASCII "regcode"
00402077   |.  8B45 D0          mov eax,dword ptr ss:[ebp-30]
0040207A   |.  A3 A06D4100      mov dword ptr ds:[416DA0],eax
0040207F   |.  8B0D A06D4100    mov ecx,dword ptr ds:[416DA0]
00402085   |.  51               push ecx
00402086   |.  8B15 A46D4100    mov edx,dword ptr ds:[416DA4]                    ;  8.00415214
0040208C   |.  52               push edx
0040208D   |.  A1 AC6D4100      mov eax,dword ptr ds:[416DAC]
00402092   |.  50               push eax
00402093   |.  8B0D B06D4100    mov ecx,dword ptr ds:[416DB0]
00402099   |.  51               push ecx
0040209A   |.  E8 B1EFFFFF      call 8.00401050
将转换后的密码写入注册表
0040209F   |.  83C4 10          add esp,10
004020A2   |.  85C0             test eax,eax
004020A4   |.  74 0E            je short 8.004020B4
判断是否写入成功
    可是这里并没有判断输入的用户名和密码是否匹配,按程序提示,应该是在程序刚开始运行的时候比较判断的。因此重新运行程序,运行后程序停在 00401A22 处的 atoi 上:
00401A0F    .  E8 0FF6FFFF      call 8.00401023
读注册表的 regcode 值
00401A14    .  83C4 0C          add esp,0C
00401A17    .  85C0             test eax,eax
00401A19    .  75 1A            jnz short 8.00401A35
00401A1B    .  8BF4             mov esi,esp
00401A1D    .  68 B46D4100      push 8.00416DB4                                  ; /s = "834667"
00401A22    .  FF15 E4864100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
将 regcode 值转换为整数
00401A28    .  83C4 04          add esp,4
00401A2B    .  3BF4             cmp esi,esp
00401A2D    .  E8 D8090000      call
00401A32    .  8945 EC          mov dword ptr ss:[ebp-14],eax
00401A35    >  C705 A46D4100 0C>mov dword ptr ds:[416DA4],8.0041520C             ;  ASCII "name"
00401A3F    .  A1 A46D4100      mov eax,dword ptr ds:[416DA4]
00401A44    .  50               push eax
00401A45    .  8B0D AC6D4100    mov ecx,dword ptr ds:[416DAC]                    ;  8.00415220
00401A4B    .  51               push ecx
00401A4C    .  8B15 B06D4100    mov edx,dword ptr ds:[416DB0]
00401A52    .  52               push edx
00401A53    .  E8 CBF5FFFF      call 8.00401023
读注册表的 name 值
00401A58    .  83C4 0C          add esp,0C
00401A5B    .  85C0             test eax,eax
00401A5D    .  75 1A            jnz short 8.00401A79
00401A5F    .  8BF4             mov esi,esp
00401A61    .  68 B46D4100      push 8.00416DB4                                  ; /s = "834667"
00401A66    .  FF15 E4864100    call dword ptr ds:[<&MSVCRTD.atoi>]              ; \atoi
将 name 值转换为整数
00401A6C    .  83C4 04          add esp,4
00401A6F    .  3BF4             cmp esi,esp
00401A71    .  E8 94090000      call
00401A76    .  8945 E8          mov dword ptr ss:[ebp-18],eax
00401A79    >  8B45 EC          mov eax,dword ptr ss:[ebp-14]
00401A7C    .  50               push eax
00401A7D    .  E8 9CF5FFFF      call 8.0040101E
再次对 regcode 做运算,跟进去看是将其减 77169,关键地址为 004018CB,结果在 EAX 中
00401A82    .  83C4 04          add esp,4
00401A85    .  8BF0             mov esi,eax
将结果转存到 ESI 中
00401A87    .  8B4D E8          mov ecx,dword ptr ss:[ebp-18]
00401A8A    .  51               push ecx
00401A8B    .  E8 E3F5FFFF      call 8.00401073
再对 name 做运算,跟进去看是再乘 2 加 0xFAF32DE3,关键地址为 0040191B,结果在 EAX 中
00401A90    .  83C4 04          add esp,4
00401A93    .  3BF0             cmp esi,eax
关键比较,比较运算后的值
00401A95    .  75 14            jnz short 8.00401AAB
关键判断,不等则跳转到失败地址
    因此,注册算法为:( 用户名 * 2 + 0x12D71 ) * 2 + 0xFAF32DE3 = 密码 + 0x2C07A - 0x12D71。简化后为:密码 = 用户名 * 4 + 4210292156。
    其中写入注册表的值为:name = 用户名 * 2 + 0x12D71,regcode = 密码 + 0x2C07A。
本关密码为:59280880 * 4 + 4210292156 = 4447415676。由于 4447415676 = 0x109162D7C 超过了双字的长度,因此密码只需为 0x9162D7C = 152448380 即可。

第九关:
地址:152448380.html
密码:016483(180346)
    不知道为什么,我的 OD 运行到 00401265 处总是提示违法访问:
00401263    .  33C0             xor eax,eax
00401265       C700 00000000    mov dword ptr ds:[eax],0
往 00000000 里写?那当然违法了,不知道怎么回事
    没办法,不动态调试了,直接往下看:
004012D2    > \8D1D 10304000    lea ebx,dword ptr ds:[403010]
EBX 中为用户名
004012D8    .  8A13             mov dl,byte ptr ds:[ebx]
取用户名第一位
004012DA    .  8D3D D8304000    lea edi,dword ptr ds:[4030D8]
EDI 中为密码
004012E0    .  8A4F 01          mov cl,byte ptr ds:[edi+1]
取密码第二位
004012E3    .  38CA             cmp dl,cl
比较用户名第一位和密码第二位
004012E5    .  75 4B            jnz short 9.00401332
如不等则跳转到失败地址
004012E7    .  8A53 02          mov dl,byte ptr ds:[ebx+2]
004012EA    .  8A0F             mov cl,byte ptr ds:[edi]
004012EC    .  38CA             cmp dl,cl
比较用户名第三位和密码第一位
004012EE    .  75 42            jnz short 9.00401332
004012F0    .  8A57 03          mov dl,byte ptr ds:[edi+3]
004012F3    .  75 05            jnz short 9.004012FA
004012F5    .  74 03            je short 9.004012FA
004012F7    .  56               push esi
004012F8       03               db 03
004012F9       25               db 25                                            ;  CHAR '%'
004012FA    >  8A4B 04          mov cl,byte ptr ds:[ebx+4]
004012FD    .  38CA             cmp dl,cl
比较用户名第五位和密码第四位
004012FF    .  75 31            jnz short 9.00401332
00401301    .  8A4B 03          mov cl,byte ptr ds:[ebx+3]
00401304    .  8A57 05          mov dl,byte ptr ds:[edi+5]
00401307    .  38CA             cmp dl,cl
比较用户名第四位和密码第六位
00401309    .  75 27            jnz short 9.00401332
0040130B    .  8A4B 05          mov cl,byte ptr ds:[ebx+5]
0040130E    .  8A57 02          mov dl,byte ptr ds:[edi+2]
00401311    .  38D1             cmp cl,dl
比较用户名第六位和密码第三位
00401313    .  75 1D            jnz short 9.00401332
00401315    .  8A4F 04          mov cl,byte ptr ds:[edi+4]
00401318    .  8A53 01          mov dl,byte ptr ds:[ebx+1]
0040131B    .  38D1             cmp cl,dl
比较用户名第二位和密码第五位
0040131D    .  75 13            jnz short 9.00401332
下面为成功地址
0040131F    .  6A 00            push 0                                           ; /Style = MB_OK|MB_APPLMODAL
00401321    .  68 46204000      push 9.00402046                                  ; |Title = "CRACKME 9"
00401326    .  68 50204000      push 9.00402050                                  ; |Text = "当您看到这个信息的时候,您已经成功了!"
0040132B    .  6A 00            push 0                                           ; |hOwner = NULL
0040132D    .  E8 8A000000      call                    ; \MessageBoxA
    此外,在地址 004010EB 到 0040114B 处的代码同上面的也基本一致。
    由此可见,注册算法为简单的用户名字符重排,对于6位用户名 123456,其密码为 316524。

第十关:
地址:016483.html
密码:314068(180346)
    提示有壳,用 PEID 查看,显示“UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo”。先要把 UPX 的壳脱掉,可是我的 UPX 脱壳工具都脱不下来,先用 UPXFIX 也不行。没办法,只能手工脱。我的方法是:一直单步运行到 0040E68F 的 jmp 10.00401426,再单步则跳转到 00401426。在此处右键选择“用ollydump脱壳调试进程”,点击“脱壳”保存文件即可。
    再用 PEID 查看脱壳后的文件,为“MASM32 / TASM32”,没壳了。调试运行,输入用户名密码后,在程序中又能看到和第九关类似的字符重排算法,这里就不列出来了,对于6位用户名 123456,其密码为 415362。因此本关密码为:314068。
    不过,好像是我的脱壳没脱好,虽然 PEID 显示没壳了,但实际上还是有点问题:脱壳后的的文件虽然能运行,但是存在一些非法指令,不知道是怎么回事。

    最终输入密码后网页转向 314068.html,通关!

最近更新时间:2007-10-10 00:57:47 浏览数(63)

发表评价

(0)(0)

登录雅虎空间,给你喜欢的博客发表评论。

精华区