新手学破解记录贴【160个CrackMe】之001
本人刚刚入门汇编逆向破解分析,本帖将记录我对160个CrackMe程序中的第001程序的分析过程。在学习的过程中,我会边学边记录。如果有不正确之处,还请各位指正。
首先打开程序后,输入假的用户名和密码 会直接弹出错误提示:Sorry,The serial is incorect!
现在把程序拖入到x32dbg里面来 来到程序模块进行搜索当前模块的字符串
搜索完成看到有两个输入不正确的提示 在这两个字符串上都下断点 然后重新输入用户名和密码进行注册看是否会断下来。
断在了第二个字符串的断点,一眼就看到了上方一个关键跳转 跳过了 Good job dude 这行代码。 把上面的jne 改成je或者直接nop掉 叫他不进行跳转然后在重新输入用户名和密码进行注册,这样就已经暴力破解成功了。
通过之前断点可以看到一关键数据,其中CW-7954-CRACKED 就是正确的注册码,这个注册码是怎么生成的具体再来分析一下。 在地址头部 0042FA79地址 下一个断点 然后逐行分析一下代码
首先第一个取了一下用户名的长度
0042FA79 | 8D55 F0 | lea edx,dword ptr ss: | :"a123456789"
0042FA7C | 8B83 DC010000 | mov eax,dword ptr ds: | eax:"a123456789", :&"d稝"
0042FA82 | E8 D1AFFEFF | call acid burn.41AA58 | 取用户名长度
然后把用户名:"a123456789" 放到了eax当中movzx eax, byte ptr ds: 会读取内存地址 eax 处的字节 'a',它的 ASCII 值是 0x61。
接着 imul dword ptr ds: 0x00431750地址的值为 0x29也就是相当于 0x61*0x29 = F89 这个时候的eax的值为 F89
下面又把eax放到了内存地址当中 然后又取出来在加上eax的值 相当于 eax*2 = 1F12 对应十进制就是 7954对应正确的激活码中间的哪个字段
0042FA87 | 8B45 F0 | mov eax,dword ptr ss: | 把用户名给eax
0042FA8A | 0FB600 | movzx eax,byte ptr ds: | 取首个字节 'a' ascll 0x61
0042FA8D | F72D 50174300 | imul dword ptr ds: | 0x00431750的值是0x29eax*0x29
0042FA93 | A3 50174300 | mov dword ptr ds:,eax | 把计算后的F89放到 0x00431750地址中
0042FA98 | A1 50174300 | mov eax,dword ptr ds: |
0042FA9D | 0105 50174300 | add dword ptr ds:,eax | 相当于eax+eax
再往下看就是一些常量拼接的操作
0042FAA3 | 8D45 FC | lea eax,dword ptr ss: | :"CW"
0042FAA6 | BA ACFB4200 | mov edx,acid burn.42FBAC | edx:"asasas", 42FBAC:"CW"
0042FAAB | E8 583CFDFF | call acid burn.403708 |
0042FAB0 | 8D45 F8 | lea eax,dword ptr ss: | :"CRACKED"
0042FAB3 | BA B8FB4200 | mov edx,acid burn.42FBB8 | edx:"asasas", 42FBB8:"CRACKED"
0042FAB8 | E8 4B3CFDFF | call acid burn.403708 |
0042FABD | FF75 FC | push dword ptr ss: | :"CW"
0042FAC0 | 68 C8FB4200 | push acid burn.42FBC8 |
0042FAC5 | 8D55 E8 | lea edx,dword ptr ss: | :"7954"
0042FAC8 | A1 50174300 | mov eax,dword ptr ds: | eax:"CW-7954-CRACKED"
0042FACD | E8 466CFDFF | call acid burn.406718 |
0042FAD2 | FF75 E8 | push dword ptr ss: | :"7954"
0042FAD5 | 68 C8FB4200 | push acid burn.42FBC8 |
0042FADA | FF75 F8 | push dword ptr ss: | :"CRACKED"
0042FADD | 8D45 F4 | lea eax,dword ptr ss: | :"CW-7954-CRACKED"
0042FAE0 | BA 05000000 | mov edx,5 | edx:"asasas"
0042FAE5 | E8 C23EFDFF | call acid burn.4039AC | 传入 CW常量计算出来的 7954 和 CRACKED常量 用 - 拼接出来密码
0042FAEA | 8D55 F0 | lea edx,dword ptr ss: | :"asasas"
0042FAED | 8B83 E0010000 | mov eax,dword ptr ds: | eax:"CW-7954-CRACKED", :&"d稝"
0042FAF3 | E8 60AFFEFF | call acid burn.41AA58 |
0042FAF8 | 8B55 F0 | mov edx,dword ptr ss: | :"asasas"
0042FAFB | 8B45 F4 | mov eax,dword ptr ss: | :"CW-7954-CRACKED"
0042FAFE | E8 F93EFDFF | call acid burn.4039FC | 真假码对比
到此就已经分析完了,总结一下具体的注册码生成算法 还是比较简单的首先取用户名的第一个字节 然后乘以0x29在乘以2 算出来的值 前面拼接上 “CW-”后面在拼接上 “-CRACKED”
下面来写一下注册机
#include <iostream>
#include <string>
using namespace std;
int main()
{
//获取输入字符串
string str;
cout << "请输入账号:" << endl;
cin >> str;
//取字符串的第一个字符
char ch = str;
int num = ch * 0x29*2;
//把num和字符串拼接起来
string key = "CW-"+ to_string(num) + "-CRACKED";
cout<< key << endl;
return 0;
}
注册机生成正确。
页:
[1]