- UID
- 34504
注册时间2007-8-16
阅读权限8
最后登录1970-1-1
初入江湖
该用户从未签到
|
//
// 作者:80王朝.∮明天去要饭
// 主页:http://www.80dnst.com
// 论坛:http://bbs.80dnst.com
// 适合:逆向分析初学者
//
晚上学逆向的时候,拿了个以前分析过的程序再次进行分析,结果发现分析出来的结果不对,本来打算花点时间把整个程序详细分析一下的,可是时间不够,所以这里只挑算法分析过程来写,分析过程中产生的IDA文件和OllyDbg文件,以及注册机源码等都在附件中了,有兴趣的朋友可以下载去看看。
.text:004010FC ; *************** S U B R O U T I N E ***************************************
.text:004010FC
.text:004010FC ; Attributes: bp-based frame
.text:004010FC
.text:004010FC ; int __stdcall ValidKey(HWND hWnd)
.text:004010FC ValidKey proc near ; CODE XREF: DialogFunc+7Bp
.text:004010FC
.text:004010FC hWnd = dword ptr 8
.text:004010FC
.text:004010FC push ebp
.text:004010FD mov ebp, esp
.text:004010FF push 14h ; nMaxCount,说明Name处最长只取20.
.text:00401101 push offset String ; lpString,保存Name值的指针
.text:00401106 push 0BB8h ; nIDDlgItem,即Name处的文本框
.text:0040110B push [ebp+hWnd] ; hDlg
.text:0040110E call GetDlgItemTextA
.text:00401113 mov esi, eax ; 把取到的Name文本框的字符数保存到esi中
.text:00401115 lea eax, [ecx]
.text:00401117 cmp esi, 5 ; 判断Name文本框中的字符个数是否大于等于5
.text:0040111A jge short loc_401134 ; 如果小于5,则提示至少输入5个字符.
.text:0040111C push 40h ; uType
.text:0040111E push offset Caption ; "ArturDents CrackMe#2"
.text:00401123 push offset Text ; "Your name must be at least five charact"...
.text:00401128 push [ebp+hWnd] ; hWnd
.text:0040112B call MessageBoxA
.text:00401130 xor eax, eax
.text:00401132 jmp short FuncLeave
.text:00401134 ; ---------------------------------------------------------------------------
.text:00401134
.text:00401134 loc_401134: ; CODE XREF: ValidKey+1Ej
.text:00401134 push 14h ; nMaxCount
.text:00401136 push offset szPWD ; lpString
.text:0040113B push 0BB9h ; nIDDlgItem,还是取文本内容,这里估计是取密码的内容
.text:00401140 push [ebp+hWnd] ; hDlg
.text:00401143 call GetDlgItemTextA
.text:00401148 mov eax, offset String ; eax指向Name值
.text:0040114D mov ebx, offset szPWD ; ebx指向密码
.text:00401152 mov ecx, esi ; ecx保存取到的用户名的个数,即相当于循环体中的i
.text:00401154
.text:00401154 loc_401154: ; CODE XREF: ValidKey+62j
.text:00401154 mov dl, [eax] ; 用户名一位位取出
.text:00401156 sub dl, cl ; 将取出的那一位 - 用户名的长度
.text:00401158 cmp [ebx], dl ; 将结果与密码相应位的值比较
.text:0040115A jnz short FuncLeave ; 不相等则跳出
.text:0040115C inc eax ; eax加1,即取用户名时下标加1
.text:0040115D inc ebx ; ebx加1
.text:0040115E loop loc_401154 ; ecx大于0时循环,直到用户名取完为止.
.text:0040115E ; 特别提醒:loop会使ecx的值减小.当cx的值不为0时才会循环.
.text:0040115E ; 因此可以得出算法:
.text:0040115E ; 1、从 name 中一位位取出用户名.
.text:0040115E ; 2、将 name - ecx
.text:0040115E ; 3、得到的值保存在 password
.text:0040115E ; 4、然后 ecx - 1
.text:00401160 push 40h ; uType
.text:00401162 push offset Caption ; "ArturDents CrackMe#2"
.text:00401167 push offset aYeahYouDidIt ; "Yeah, you did it!"
.text:0040116C push [ebp+hWnd] ; hWnd
.text:0040116F call MessageBoxA ; 提示注册成功.
.text:00401174
.text:00401174 FuncLeave: ; CODE XREF: ValidKey+36j
.text:00401174 ; ValidKey+5Ej
.text:00401174 leave
.text:00401175 retn 4
.text:00401175 ValidKey endp
有了以上的分析过程,就可以得到算法如下:
//取出用户名的每一位进行处理
// 写法一:
// 第一次分析的时候是这样写的,我也不清楚为什么这么写
// for(int i = 0; i < nameLength; i++)
// {
// tmp = name - (nameLength - i);
// serial = tmp;
// }
// 写法二:
// 这一次分析的时候我是这样写的
// 这样写是为了体现算法
for(int i = 0; nameLength > 0; i++)
{
tmp = name - nameLength;
serial = tmp;
nameLength--;
}
printf("serial:%s\n\n", serial);
另外还发现了另一篇分析这个 Crackme 的文章,也在附件中了,大家可以比对比对。
如果发现有什么问题请到 80王朝论坛 告诉我,非常感谢!
效果截图:
注意:贴子复制过来后着色丢了,我也没时间再一个个着色,带着色的贴子在这:
http://bbs.80dnst.com/thread-42-1-1.html
[ 本帖最后由 kgdiwss 于 2007-11-21 23:35 编辑 ] |
|