目标程序
程序下载:CRACKME2
解压密码:9unk
任务目标:分析程序的算法,并写出注册机程序。
观察程序
算法分析
加载程序到入口点
查看程序的 API ,并设置断点
继续运行程序
执行到返回,查看程序返回的参数
转到内存数据窗口,然后将对 password 设置内存访问断点
“F9” 继续运行程序,此时程序来到了判断序列号的地方。并单步运行并分析程序。
1 | mov byte ptr ds:[0x00402118], 0x0 |
1 | mov al, byte ptr ds:[esi] // 把 password 传入 al 中 |
1 | cmp al, 0x41 // al 的值和 A(0x41) 比较 |
我们这里还需要再注意一下它跳转的地址,加上我们之前的跳转一共有三个。第一个跳转(程序正常循环结束:pop esi,并跳转到 call-2);第二个跳转(password 的值是数字:esi+1,并跳转循环);第三个跳转(password 的值是字母:跳转到 call-1)
很明显这里的第三次跳转是错误的,因为它没有正常的进行循环判断;第一次跳转可能是用来生成正确的序列号;第二次跳转可能是正常的序列号判断。
这里没判断到 A~Z 之间的字符串
我们正常循环结束到 call 指令处,可以看到这里把之前压入栈中的 password ,又重新弹出给 esi 寄存器了。
步入 call-2 的部分,查看其中的算法。
先把寄存器清零
然后将 4021A3 内存地址中的数据(Messing_in_byte)存入 cl
1 | mov bl, byte ptr ds:[esi] // password 存入 bl 中 |
1 | xor bl, cl // bl = bl xor cl |
可以看到这里把异或出来的值替换到原来的 password 处
1 | inc esi |
结束第一次循环
循环结束后,可以看到此时的 “123456” 计算成了 “|W@G\X”。继续单步运行
继续单步运行
执行到 call 指令处
单步步入,寄存器清零
1 | mov cl, byte ptr ds:[0x00402118] |
我们转到内存数据窗口查看这个数据,发现这个就是我们输入序列号的字符数
1 | mov esi, dword ptr ss:[esp+0x4] |
生成的序列号存到 esi 中
这里多个反斜杠,这个应该是转义字符串
1 | mov edi, 0x402150 |
1 | // repe 是一个串操作前缀,它重复串操作指令,每重复一次 ECX 的值就减 1,一直到 CX 为 0 或 ZF 为 0 时停止。 |
我们这里把之前 xor 的值 和 比较的值都记录下来。
1 | 异或值:Messing_in_bytes |
继续单步执行
1 | add esp, 0x4 // esp + 4 |
我们现在再来分析一下算法部分:
1 | 序列号 xor Messing_in_bytes = 比较值 |
这里的序列号是固定值,就不编写注册机了。
reference
- 本文标题:x64dbg-算法分析三.md
- 本文作者:9unk
- 创建时间:2020-12-30 01:48:18
- 本文链接:https://9unkk.github.io/2020/12/30/x64dbg-suan-fa-fen-xi-san/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!