-
-
[原创]01.11.12.28 CrackMe分析
-
发表于: 2011-12-28 07:35 5632
-
【文章标题】: CrackMe分析1.11.12.28
【文章作者】: HcyRcer
【作者邮箱】: 421458119@qq.com
【作者主页】: http://hi.baidu.com/kao4ni/home
【作者QQ号】: 421458119
【加壳方式】: 无
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
载入 CrackMe 后,输入 名 和 码 后,下 GetDlgItemTextA断点!点击[OK]后,弹出英文,翻译为 无法下 BPX 断点,
发现此CrackMe有 反调试。
既然有反调试,那我就下 MessageBoxA断点,点[OK]后,将 这个弹出 [无法下 BPX 断点]的 对话框,成功断下!!
随即来到 MessageBoxA 的函数调用处!发现 调用MessageBoxA 来自 00401246,我们就跟这个地址 看看!
!到了 00401243 cmp byte ptr ds:[eax],0CC ; 00401246je 004012F7 //想必大家都懂了吧,检测CC断点。。好了。
我们把这两句NOP掉, 不让它绕过下面的 GetDlgItemTextA 函数!!
NOP掉之后保存下文件!!
,重新载入,再下 GetDlgItemTextA 断点 !发现 GetDlgItemTextA 仍然断不下来,提示一个
对话框,程序好像又 检测到了什么?
我们再下 MessageBoxA 断点 ! 哈哈,程序又被 相同的方法断下了,返回到
MessageBoxA 的函数调用处! 发现 跳转来自 00401228 。我们跟上去看看
00401220 mov edi,crcme1.00401247
00401225 cmp byte ptr ds:[edi],84
00401228 jnz crcme1.0040130D
发现 MessageBoxA 的弹出 跟 00401247处的 内容 有关! 那我们就看看 00401247 到底是什么重要的东西 能够检测到我们下断!!
我们 CTRL+G 来到 00401247地址 !发现此处的内容已经被我们NOP掉了!! 我们刚NOP掉的是
【00401243 cmp byte ptr ds:[eax],0CC ; 00401246je 004012F7】 ,上面的 【!】那行!!!
我们也 NOP 掉 00401220 - 00401228 3行代码。保存文件(保存时会提示 重定位,不要理会!)
我们重载 CrackMe ;输入 名:11111 码:22222下 GetDlgItemTextA 断点!!点击确定!发现程序断下来了!!
然后我们就可以分析程序了!! 算法很简单!!
算法解析:
0040124C . 6>push 28 ; /Count = 28 (40.)
0040124E . 6>push crcme1.00402106 ; |Buffer = crcme1.00402106
00401253 . 6>push 3E9 ; |ControlID = 3E9 (1001.)
00401258 . F>push dword ptr ss:[ebp+8] ; |hWnd
0040125B . E>call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
00401260 . 8>cmp eax,5 //用户名 位数必须大于5
00401263 . 0>jb crcme1.00401326
00401269 . 6>push 28 ; /Count = 28 (40.)
0040126B . 6>push crcme1.0040212E ; |Buffer = crcme1.0040212E
00401270 . 6>push 3EA ; |ControlID = 3EA (1002.)
00401275 . F>push dword ptr ss:[ebp+8] ; |hWnd
00401278 . E>call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
0040127D . B>mov edi,crcme1.00402106 //算法开始
00401282 . 3>xor ebx,ebx
00401284 . 3>xor eax,eax
00401286 > 8>mov bl,byte ptr ds:[edi]
00401288 . 8>cmp bl,20
0040128B . 0>jb crcme1.00401326 用户名第一位小于20H 则错
00401291 . 0>add eax,ebx
00401293 . 4>inc edi
00401294 . 8>cmp byte ptr ds:[edi],0
00401297 .^ 7>jnz short crcme1.00401286 这是个循环,累加 用户名每次 ASCII码 放入EAX
00401299 . C>rol eax,3 EAX循环左移 3位
0040129C . 3>xor eax,515A5 EAX异或 515A5
004012A1 . 5>push eax 保存 EAX //用户名计算结果 放到了EAX
004012A2 . 3>xor eax,eax
004012A4 . 3>xor ebx,ebx
004012A6 . 3>xor edi,edi
004012A8 . B>mov esi,crcme1.0040212E 码放到 ESI中
004012AD > B>mov eax,0A EAX =10
004012B2 . 8>mov bl,byte ptr ds:[esi]
004012B4 . 8>test ebx,ebx
004012B6 . 7>je short crcme1.004012CD 为0则跳出循环
004012B8 . 8>cmp bl,30
004012BB . 7>jb short crcme1.00401326 码小于 30H 则错
004012BD . 8>cmp bl,39
004012C0 . 7>jg short crcme1.00401326 码大于 39H 则错
004012C2 . 8>sub ebx,30
004012C5 . 0>imul edi,eax
004012C8 . 0>add edi,ebx //上3句为 将 码的字符串 转为 数字 放入EDI
004012CA . 4>inc esi
004012CB .^ E>jmp short crcme1.004012AD //循环每位
004012CD > 8>xor edi,87CA EDI异或 87CA
004012D3 . 8>mov ebx,edi EBX = EDI
004012D5 . 5>pop eax 取出保存的 EAX
004012D6 . 0>add eax,ebx EAX = EAX + EBX
004012D8 . 3>xor eax,797E7 结果 异或 797E7
004012DD . 8>test eax,eax 判断结果是否为 797E7
004012DF . 7>jnz short crcme1.00401326 //此处算法完毕,进入判断正确!!
004012E1 . 6>push 0 ; /Style = MB_OK|MB_APPLMODAL
004012E3 . 6>push crcme1.0040201B ; |Title = "-=ACG=- T h e B e s t -=ACG=-"
004012E8 . 6>push crcme1.00402077 ; |Text = "Yeah You Did It!!!
Czyli nareszczie ci si?uda硂
Teraz mo縠sz przy彻czy?si?do ACG"
004012ED . F>push dword ptr ss:[ebp+8] ; |hOwner
004012F0 . E>call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
~~~~~~~~~~~~~~~~~~~~~~
这是一个死码的 判断 !! 经过一系列 用户名 与 注册码 的运算,判断结果 是否为 797E7 !!是则成功,否则错误!!
(F用户名 + F码)异或 = 797E7
注册机:
int len;
TCHAR szEnchar[] = TEXT ("你输入字符要大于5 个!") ;
int h1=0;
int bian;
len=GetDlgItemText(hDlg,IDC_TXT0,cName,sizeof(cName)/sizeof(TCHAR)+1); //取用户名
GetDlgItemText(hDlg,IDC_TXT1,cCode,sizeof(cCode)/sizeof(TCHAR)+1); //取注册码
if (len<5)
{
MessageBox(0,szEnchar,0,0);
return 0;
}
for (int i =0 ;i<len;i++)
{
h1 +=cName[i];
}
h1= h1<<3;
h1 = h1 ^ 0x515A5;
bian = 0x797e7 - h1;
bian = bian ^0x87CA;
wsprintf(szFail,"%d",bian);
SetDlgItemText(hDlg,IDC_TXT1,szFail);
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2011年12月28日 6:36:55
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!