本文为看雪论坛优秀文章
看雪论坛作者ID:erfze
前段时间看完王爽老师的《汇编语言》,受益匪浅。近日开始看《加密与解密》,学习逆向分析技术。
下文是对2.1.3中的CrackMe——TraceMe 动态分析技术调试分析过程及笔者个人思路的总结。
运行TraceMe.exe,有两个输入框,分别是获取用户名与序列号:
那断点应该下在GetDlgItemTextA或GetWindowText,Ctrl+G先搜索GetDlgItemTextA:之后F2在此处下断点。F9开始执行该程序,输入用户名与序列号如下所示:点击"Check",程序停在断点处,查看栈中内容:
UINT GetDlgItemText(
HWND hDlg,
// handle of dialog box
int nIDDlgItem,
// identifier of control
LPTSTR lpString,
// address of buffer for text
int nMaxCount
// maximum size of string
);
于数据面板中Ctrl+G,定位到0019F6B8处:可以看到绿色方框是应用程序调用GetDlgItemText函数,红色圆框中是笔者输入的用户名。既然上一个GetDlgItemText函数是获取用户名,那么下一个GetDlgItemText函数应该是获取序列号,跟进call指令验证:注意上图中的红色划线地址,推测其后保存着序列号,Ctrl+G定位到0019F708处后剩余操作同上。推测得以验证:如果未输入用户名,je指令跳转到TraceMe.00401248处执行,输出提示信息:接下来的两条指令检查用户名是否少于5个字符,若少于5个字符,同上处理。下图白色圆框中指令分别将用户名长度、保存用户名地址、保存序列号地址入栈:F8暂且不跟进,继续分析,je指令跳转到TraceMe.0040122E,而由TraceMe.0040122E起始的三条指令是为lstrcpyA()函数——将"序列号错误,再来一次!"复制到TraceMe.004054E4处传递参数:由上述程序流程分析可知,只要004011F5处的je指令不执行,即注册成功。在程序执行到004011F5处时,于寄存器窗口中找到Z标志位,Enter键将其值由1修改为0,je指令不再会执行:执行004011E5处的call指令。暂且不分析如何计算序列号。F8一直执行下去,到0040138A处停止:
推测1770是正确序列号,而lstrcmpA则是在比较输入序列号是否与正确序列号相符。那么修改内存中的"12345"为"1770":重新运行程序,执行004011E5处的call指令。下面是笔者一边分析算法,一边在记事本中的记录:#include <stdio.h>
#include <string.h>
void main(void)
{
unsigned char Name[6] = "ERFZE";
unsigned char CA[8] = {
0x0C,0x0A,0x13,0x09,0x0C,0x0B,0x0A,0x08
};
int i = 3;
int x = 0, y = 0;
int j = 0, k = 0;
if (strlen(Name) > i)
{
for (; i <= strlen(Name); ++i,++y)
{
if (y > 7)
y = 0;
j = Name[i];
k = CA[y];
x = x + j * k;
}
}
printf("%d", x);
}
将unsigned char Name[6] = "ERFZE;改为unsigned char Name[10] = "ERFZE1999";,结果为4525。验证:虽然此次分析过程耗费一下午的时间,但从中收获乐趣,领略到逆向工程之魅力,心情或多或少有些激动,故发文为念。看雪ID:erfze
https://bbs.pediy.com/user-817966.htm
*本文由看雪论坛 erfze 原创,转载请注明来自看雪社区好书推荐
文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458303076&idx=2&sn=613a600b0b9619ab8047a41624ce6971&chksm=b1818aee86f603f82829a6740c688e68c6c40ec1f537878837b7c27ef0219d3713089f0fe11c#rd
如有侵权请联系:admin#unsafe.sh