CrackMe-CrackHead-内存断点

上一篇的传送门 http://blog.csdn.net/airuozhaoyang/article/details/49872887

在上一篇的调试中,我们发现esi在最后的xor前,不同电脑上的值是不一样的。esi在关键call前存在了一部明显赋值的操作

0040130E  |. /75 63         jnz short CrackHea.00401373
00401310  |. |8B35 9C334000 mov esi,dword ptr ds:[0x40339C]
00401316  |. |6A 28         push 0x28                                ; /Count = 28 (40.)
00401318  |. |68 C4334000   push CrackHea.004033C4                   ; |Buffer = CrackHea.004033C4
0040131D  |. |FF35 90314000 push dword ptr ds:[0x403190]             ; |hWnd = NULL
00401323  |. |E8 4C010000   call <jmp.&USER32.GetWindowTextA>        ; \GetWindowTextA
00401328  |. |E8 A5000000   call CrackHea.004013D2                   ;  这是干嘛的
0040132D  |. |3BC6          cmp eax,esi                              ;  这个地方要返回zf=0 也就是eax=esi

mov esi,dword ptr ds:[0x40339C]

可是重新载入OD,发现一开始这个内存位置是0,看来一定是经过一系列初始化才导致不同pc的这个位置的数据不同从而使每个机器的最终结果也不同的。

我们在0x40339C处下断。
内存访问断点,OD内存断点只能设置一个。且程序重新加载后就会消失、
F9运行。

断点停在了ntdll.dll系统领空,alt+f9回到用户领空。

关键代码出现了。

0040140C  /$  60            pushad
0040140D  |.  6A 00         push 0x0                                 ; /RootPathName = NULL
0040140F  |.  E8 B4000000   call <jmp.&KERNEL32.GetDriveTypeA>       ; \GetDriveTypeA
00401414  |.  A2 EC334000   mov byte ptr ds:[0x4033EC],al            ;  磁盘类型参数送内存地址4033EC al=3
00401419  |.  6A 00         push 0x0                                 ; /pFileSystemNameSize = NULL
0040141B  |.  6A 00         push 0x0                                 ; |pFileSystemNameBuffer = NULL
0040141D  |.  6A 00         push 0x0                                 ; |pFileSystemFlags = NULL
0040141F  |.  6A 00         push 0x0                                 ; |pMaxFilenameLength = NULL
00401421  |.  6A 00         push 0x0                                 ; |pVolumeSerialNumber = NULL
00401423  |.  6A 0B         push 0xB                                 ; |MaxVolumeNameSize = B (11.)
00401425  |.  68 9C334000   push CrackHea.0040339C                   ; |VolumeNameBuffer = CrackHea.0040339C
0040142A  |.  6A 00         push 0x0                                 ; |RootPathName = NULL
0040142C  |.  E8 A3000000   call <jmp.&KERNEL32.GetVolumeInformation>; \GetVolumeInformationA
00401431  |.  8D35 9C334000 lea esi,dword ptr ds:[0x40339C]          ;  把crackme程序所在分区的卷标名称送到ESI  不过得到的值是0 啊
00401437  |.  0FB60D EC3340>movzx ecx,byte ptr ds:[0x4033EC]         ;  磁盘类型参数地址送到ecx中 此处ecx=3
0040143E  |.  33FF          xor edi,edi                              ;  edi=0
00401440  |>  8BC1          mov eax,ecx                              ;  eax=ecx=磁盘类型的参数地址、
00401442  |.  8B1E          mov ebx,dword ptr ds:[esi]               ;  分区的卷标名称以数值的形式存到ebx中
00401444  |.  F7E3          mul ebx                                  ;  循环相乘 累加
00401446  |.  03F8          add edi,eax
00401448  |.  49            dec ecx
00401449  |.  83F9 00       cmp ecx,0x0
0040144C  |.^ 75 F2         jnz short CrackHea.00401440
0040144E  |.  893D 9C334000 mov dword ptr ds:[0x40339C],edi          ;  把edi的值写回给内存地址
00401454  |.  61            popad
00401455  \.  C3            retn

分析到这里 思路就清晰了、程序调用了两个windows api

GetVolumeInformation
GetDriveTypeA

得到他们的记过并进行一系列的运算,从而得出esi的值。
我这里GetDriveTypeA返回的是3.GetVolumeInformation返回的是0,
所以最后的答案也是0,如果别的电脑也像我这样磁盘返回的卷标为0的话,最后esi的值很有可能和我一样。
所以这个程序并不能做到真正的一机一码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值