新160个CrackMe 002号:abexcm5 逆向分析
一、暴力破解
先用DIE查壳:程序为PE32,无壳,Delphi编写。
爆破的思路是:找到关键判断,让程序强制走成功分支。
1. 定位关键跳转
将程序拖入x32dbg,右键搜索 → 所有用户模块 → 字符串,找到成功/失败提示。
双击定位到汇编代码,发现一处关键条件跳转
je 004010xx ; 如果条件成立,跳去失败分支2. 修改指令
选中这行,按空格键,将je改为jmp,让程序无论结果如何都执行成功分支。
3. 保存补丁
右键 → 补丁 → 全选 → 修补文件,另存为abexcm5_1.exe。
4. 验证
运行修改后的程序,输入任意序列号(如 输入框内有自带字符,不修改),点击Check,弹出成功窗口。
至此,爆破完成。
二、算法还原
爆破虽然快,但要想真正理解程序,必须还原算法。
1. 静态分析(IDA)
将程序拖入IDA,找到关键函数sub_401056(右上角点击View-Open subviews-Generatepseudocode,观察反汇编出来的代码)。
// positive sp value has been detected, the output may be wrong! BOOL __userpurge sub_401056@<eax>(int a1@<ebp>, int a2, int a3, int a4, int a5) { char n2; // dl if ( *(_DWORD *)(a1 + 16) == 101 ) { GetDlgItemTextA(*(HWND *)(a1 + 8), 104, String, 37);// GetDlgItemTextA是API获取输入函数,字符串整体不超过37-1 GetVolumeInformationA( // 获取硬盘信息的API,获取C盘序列号 0, VolumeNameBuffer, 0x32u, &VolumeSerialNumber, &MaximumComponentLength, &FileSystemFlags, 0, 0); lstrcatA(VolumeNameBuffer, String2); // "4562-ABEX" n2 = 2; do { ++*(_DWORD *)VolumeNameBuffer; ++*(_DWORD *)&VolumeNameBuffer[1]; ++*(_DWORD *)&VolumeNameBuffer[2]; ++*(_DWORD *)&VolumeNameBuffer[3]; --n2; } while ( n2 ); lstrcatA(lpString1, aL2c5781); // "L2C-5781" lstrcatA(lpString1, VolumeNameBuffer); if ( lstrcmpiA(lpString1, String) ) MessageBoxA( *(HWND *)(a1 + 8), Text, // "The serial you entered is not correct!" Caption, // "Error!" MB_OK); else MessageBoxA( *(HWND *)(a1 + 8), aYepYouEnteredA, // "Yep, you entered a correct serial!" aWellDone, // "Well Done!" MB_OK); } else if ( *(_DWORD *)(a1 + 16) != 2 ) { return 0; } return EndDialog_wrp(a1, a2, a3, a4, a5); }整体代码逻辑:
if ( *(_DWORD *)(a1 + 16) == 101 )//判断是否点击注册,点击了 { // ... 注册逻辑 ...判断是否注册成功; } else if ( *(_DWORD *)(a1 + 16) != 2 )//“取消”或“关闭”按钮 { return 0; } return EndDialog_wrp(a2, a3, a4, a5);//关闭窗口。2. 动态验证(x32dbg)
理论分析后,需要动态跟踪验证。
逐步跟踪,观察内存变化:
第1步:在主要运行程序区域找一断点(这里在ret 10后增加断点,后面为主要实现程序区域),双击机器码区域,增加断点
第2步:在系统输入函数前,鼠标左键双击机器码区域,增加断点,一直点运行直到弹出输入界面,随便输入(这里输入123456为例),点击check。
第3步:接下来一直点步进,发现C盘序列号“新加卷”出现。
继续步进可以看到字符串“4562-ABEX”加到“新加卷”(每个人的字符串可能会有差别,这里是我电脑上的)之后。
然后进行while循环操作,dl等于2,字符串“新加卷4562-ABEX”前四位每个都加1,之后dl--,相当于前四位每位分别加2。
第4步:继续步进发现程序正在将我们输入的123456与一个固定答案做字符串“L2C-5781夷菊卷4562-ABEX”比对,比对结果存在eax为1,接着对比了eax和0是否相等,不等讲ZF为存为0,不跳转继续运行弹注册失败页面
由此我们可知字符串“L2C-5781夷菊卷4562-ABEX”就是我这台电脑的注册序列号
打开abexcm程序输入字符串“L2C-5781夷菊卷4562-ABEX”即可显示注册成功
动态跟踪确认:算法分析与实际运行完全一致。
3. 算法总结
正确序列号 = "L2C-5781" + 变换( C盘序列号(二进制) + "4562-ABEX" ) 其中变换 = 对前4字节各加2三、参考资料
其他老师的解题思路:https://cn-sec.com/archives/1745668.html
视频参考:艮艮为山老师视频讲解
新160个CrackMe资源:百度网盘 提取码:z2i6
接下来,我将继续更新新160个CrackMe系列,记录每个程序的破解思路和算法分析,欢迎关注。
