-
-
[原创]First CrackMe
-
发表于:
2019-12-11 17:44
10375
-
前段时间看完王爽老师的《汇编语言》,受益匪浅。近日开始看《加密与解密》,学习逆向分析技术。下文是对2.1.3
中的CrackMe
——TraceMe 动态分析技术
调试分析过程及笔者个人思路的总结。
运行TraceMe.exe
,有两个输入框,分别是获取用户名与序列号:
那断点应该下在GetDlgItemTextA
或GetWindowText
,Ctrl+G先搜索GetDlgItemTextA
:
之后F2在此处下断点。F9开始执行该程序,输入用户名与序列号如下所示:
点击"Check",程序停在断点处,查看栈中内容:
GetDlgItemText
函数原型如下:
于数据面板中Ctrl+G,定位到0019F6B8处:
Ctrl+F9,F7返回应用程序领空:
可以看到绿色方框是应用程序调用GetDlgItemText
函数,红色圆框中是笔者输入的用户名。
既然上一个GetDlgItemText
函数是获取用户名,那么下一个GetDlgItemText
函数应该是获取序列号,跟进call指令验证:
注意上图中的红色划线地址,推测其后保存着序列号,Ctrl+G定位到0019F708处后剩余操作同上。推测得以验证:
下面三条指令检查用户名是否为空:
如果未输入用户名,je指令跳转到TraceMe.00401248处执行,输出提示信息:
接下来的两条指令检查用户名是否少于5个字符,若少于5个字符,同上处理。
下图白色圆框中指令分别将用户名长度、保存用户名地址、保存序列号地址入栈:
接下来call调用函数的功能为计算正确序列号。
F8暂且不跟进,继续分析,je指令跳转到TraceMe.0040122E,而由TraceMe.0040122E起始的三条指令是为lstrcpyA()
函数——将"序列号错误,再来一次!"复制到TraceMe.004054E4处传递参数:
由上述程序流程分析可知,只要004011F5处的je指令不执行,即注册成功。在程序执行到004011F5处时,于寄存器窗口中找到Z标志位,Enter键将其值由1修改为0,je指令不再会执行:
修改完成后,F9,注册成功:
执行004011E5处的call指令。暂且不分析如何计算序列号。F8一直执行下去,到0040138A处停止:
推测1770是正确序列号,而lstrcmpA则是在比较输入序列号是否与正确序列号相符。那么修改内存中的"12345"为"1770":
修改完成后,F9,注册成功:
重新运行程序,执行004011E5处的call指令。下面是笔者一边分析算法,一边在记事本中的记录:
根据上图写出了计算序列号的简易C代码:
CA
中数据是由下面横线处指令确定:
运行结果如下,1770,与正确序列号相符:
将unsigned char Name[6] = "ERFZE";
改为unsigned char Name[10] = "ERFZE1999";
,结果为4525。验证:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)