下载了一个流行时代整理的密界文集,资料丰富。其中有个CRACKME练习表,以为找到入门的好材料,准备一个个练下去。但看了以后实在不明白为什么会这样或那样,发帖请教大家。
CrackMe之chap204 破解分析
【破文标题】 CrackMe之chap204 破解分析
【破文作者】 weiyi75[Dfcg][D.4S]
【作者邮箱】 [email]weiyi75@sohu.com[/email]
【作者主页】 Dfcg官方大本营、龙族联盟论坛
【使用工具】 peid,W32Dasm,olldbg,Keymake
【破解平台】 Win2000/XP
【软件名称】 chap204
【软件大小】 24KB
【下载地址】 本地下载
【编程语言】 Microsoft Visual C++ 6.0
【软件简介】 加密和解密第一版第二章第四个CrackMe。
【破解目的】 从头学起,打好基础。
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
------------------------------------------------------------
首先 Peid 检测程序编程语言是Microsoft Visual C++ 6.0,运行程序。
没输入用户名提示
"User Name must have at least 5."
错误注册码提示
"Incorrect!!, Try Again."
用W32Dasm查找字符参考。
于是为OD的动态跟踪找到下面一段代码。
* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
|
:00401565 E820080000 Call 00401D8A
:0040156A 8D4DEC lea ecx, dword ptr [ebp-14]
:0040156D E8DE020000 call 00401850
:00401572 8945E4 mov dword ptr [ebp-1C], eax
:00401575 837DE405 cmp dword ptr [ebp-1C], 00000005
:00401579 7D43 jge 004015BE
:0040157B 6A40 push 00000040
* Possible StringData Ref from Data Obj ->"CrackMe"
|
:0040157D 6820404000 push 00404020
* Possible StringData Ref from Data Obj ->"User Name must have at least 5 "
->"characters."
..................................................................
我们切换到OD里面。
任意填入
用户
David
序列号
12345
00401551 |. E8 34080000 call <jmp.&MFC42.#3097_?GetDlgItemTextA@>
00401556 |. 8D4D E8 lea ecx, dword ptr ss:[ebp-18] //读取用户名 David
00401559 |. 51 push ecx
0040155A |. 68 E9030000 push 3E9
0040155F |. 8B8D 40FEFFFF mov ecx, dword ptr ss:[ebp-1C0]
00401565 |. E8 20080000 call <jmp.&MFC42.#3097_?GetDlgItemTextA@>
0040156A |. 8D4D EC lea ecx, dword ptr ss:[ebp-14] //读取注册码123456789
0040156D |. E8 DE020000 call chap204.00401850
00401572 |. 8945 E4 mov dword ptr ss:[ebp-1C], eax //eax=5=用户名位数
00401575 |. 837D E4 05 cmp dword ptr ss:[ebp-1C], 5 //比较姓名是否大于等于5个字符。
00401579 |. 7D 43 jge short chap204.004015BE
0040157B |. 6A 40 push 40
0040157D |. 68 20404000 push chap204.00404020 ; ASCII "CrackMe"
00401582 |. 68 28404000 push chap204.00404028 ; ASCII "User Name must have at least 5 characters." //提示用户名必需是5个字符。
00401587 |. 8B8D 40FEFFFF mov ecx, dword ptr ss:[ebp-1C0]
0040158D |. E8 F2070000 call <jmp.&MFC42.#4224_?MessageBoxA@CWnd>
00401592 |. C645 FC 01 mov byte ptr ss:[ebp-4], 1
00401596 |. 8D4D DC lea ecx, dword ptr ss:[ebp-24]
00401599 |. E8 C2070000 call <jmp.&MFC42.#800_??1CString@@QAE@XZ>
0040159E |. C645 FC 00 mov byte ptr ss:[ebp-4], 0
004015A2 |. 8D4D E8 lea ecx, dword ptr ss:[ebp-18]
004015A5 |. E8 B6070000 call <jmp.&MFC42.#800_??1CString@@QAE@XZ>
004015AA |. C745 FC FFFFF>mov dword ptr ss:[ebp-4], -1
004015B1 |. 8D4D EC lea ecx, dword ptr ss:[ebp-14]
004015B4 |. E8 A7070000 call <jmp.&MFC42.#800_??1CString@@QAE@XZ>
004015B9 |. E9 F9010000 jmp chap204.004017B7
004015BE |> C745 E0 00000>mov dword ptr ss:[ebp-20], 0 //ebp-20=0,这个程序的算法比较麻烦,准备好纸笔记录每次寄存器等值,详细见标签1。
004015C5 |. EB 09 jmp short chap204.004015D0
004015C7 |> 8B55 E0 /mov edx, dword ptr ss:[ebp-20] //edx=ebp-20=0(开始记数n)
004015CA |. 83C2 01 |add edx, 1 //edx=edx+1=1
004015CD |. 8955 E0 |mov dword ptr ss:[ebp-20], edx //记数n=edx
004015D0 |> 8B45 E0 mov eax, dword ptr ss:[ebp-20] //eax=记数n
004015D3 |. 3B45 E4 |cmp eax, dword ptr ss:[ebp-1C] //eax与姓名长度比较
004015D6 |. 7D 42 |jge short chap204.0040161A //大于等于就跳走。
004015D8 8B4D E0 |mov ecx, dword ptr ss:[ebp-20] //ecx=记数n
004015DB |. 51 |push ecx ; /Arg1
004015DC |. 8D4D EC |lea ecx, dword ptr ss:[ebp-14] ; |
004015DF |. E8 1C030000 |call chap204.00401900 ; \chap204.00401900
004015E4 |. 0FBED0 |movsx edx, al //取用户名第0位,44('D')
004015E7 8B45 F0 |mov eax, dword ptr ss:[ebp-10] //注册码将起始值81276345放入eax,地址ebp-10将一直保存注册码。
004015EA |. 03C2 |add eax, edx //edx=eax+edx //就是 81276345+44('d')=81276389
004015EC |. 8945 F0 |mov dword ptr ss:[ebp-10], eax //保存结果。
004015EF |. 8B4D E0 |mov ecx, dword ptr ss:[ebp-20] //ecx=记数n
004015F2 |. C1E1 08 |shl ecx, 8 SHL SHl 逻辑左移 这个命令不是很理解
0 SHL 8 =0
1 SHL 8 =100 //感觉就是*100一样。
2 SHL 8 =200
004015F5 |. 8B55 F0 |mov edx, dword ptr ss:[ebp-10]
004015F8 |. 33D1 |xor edx, ecx //edx=ecx xor edx
004015FA |. 8955 F0 |mov dword ptr ss:[ebp-10], edx //保存结果。
004015FD |. 8B45 E0 |mov eax, dword ptr ss:[ebp-20] //eax=记数n
00401600 |. 83C0 01 |add eax, 1 eax=eax+1=1
00401603 |. 8B4D E4 |mov ecx, dword ptr ss:[ebp-1C] ecx=5=姓名长度。
00401606 |. 0FAF4D E0 |imul ecx, dword ptr ss:[ebp-20] ecx=ecx*记数n
0040160A |. F7D1 |not ecx //not ecx 取反
0040160C |. 0FAFC1 |imul eax, ecx //eax=eax*ecx
0040160F |. 8B55 F0 |mov edx, dword ptr ss:[ebp-10] //eax=ebp-10
00401612 |. 0FAFD0 |imul edx, eax //edx=edx*eax
00401615 |. 8955 F0 |mov dword ptr ss:[ebp-10], edx //保存结果。
00401618 |.^ EB AD \jmp short chap204.004015C7 //循环。
0040161A |> 8B45 F0 mov eax, dword ptr ss:[ebp-10] //循环完毕的ebp-10即是真码
eax=D6AA35BC
0040161D |. 50 push eax
0040161E |. 68 54404000 push chap204.00404054 ; ASCII "%lu"
00401623 |. 8D4D DC lea ecx, dword ptr ss:[ebp-24]
00401626 |. 51 push ecx
00401627 |. E8 52070000 call <jmp.&MFC42.#2818_?Format@CString@@>
0040162C |. 83C4 0C add esp, 0C //格式转换 D6AA35BC to 3601479100
0040162F |. 8D4D DC lea ecx, dword ptr ss:[ebp-24]
00401632 |. E8 79020000 call chap204.004018B0
00401637 |. 50 push eax ; /Arg1
00401638 |. 8D4D E8 lea ecx, dword ptr ss:[ebp-18] ; |
0040163B |. E8 80020000 call chap204.004018C0 //判断是否注册正确。
00401640 |. 85C0 test eax, eax //eax=0 就注册。
00401642 |. 0F85 FF000000 jnz chap204.00401747
00401648 |. 8D8D ACFEFFFF lea ecx, dword ptr ss:[ebp-154]
0040164E |. E8 19070000 call <jmp.&MFC42.#540_??0CString@@QAE@XZ>
00401653 |. C645 FC 03 mov byte ptr ss:[ebp-4], 3
00401657 |. 6A 66 push 66
00401659 |. 8D8D ACFEFFFF lea ecx, dword ptr ss:[ebp-154]
0040165F |. E8 02070000 call <jmp.&MFC42.#4160_?LoadStringA@CStr>
00401664 |. B9 07000000 mov ecx, 7
00401669 |. BE 58404000 mov esi, chap204.00404058 ; ASCII "Correct!!
"
............................................................................
标签1
第一次循环。 第二次循环。
ecx=0 ecx=1
edx=44('D') edx=61('a')
ebp-10=81276345 ebp-10=7ED89C77
eax=81276345 eax=7ED89C77
eax=81276345+44=81276389 eax=7ED89C77+61=7ED89CD8
ebp-10=81276389 ebp-10=7ED89CD8
ecx=0 ecx=100
edx=812276389 xor 0 =81276389 edx=7ED89CD8 xor 100 =7ED89DD8
ebp-10=812276389 ebp-10=7ED89DD8
eax=1 eax=2
ecx=5 ecx=5
ecx=0*5=000 ecx=1*5=5
ecx=not 0=-1 ecx=not 5=FFFFFFFA
eax=-1*1=-1 eax=FFFFFFA*2=FFFFFFF4
edx=812276389*-1=7ED89C77 edx=7ED89CD8*FFFFFFF4=0DD899E0
ebp-10=7ED89C77 ebp-10=0DD899E0
第三次循环。 第四次循环。
ecx=2 ecx=3
edx=76('V') edx=69('i')
ebp-10=0DD899E0 ebp-10=37145CEA
eax=0DD899E0 eax=37145CEA
eax=0DD899E0+76=0DD89A56 eax=37145CEA+69=37145d53
ebp-10=0DD89A56 ebp-10=37145d53
ecx=200 ecx=300
edx=0DD89A56 xor 200 =0DD89856 edx=37145d53 xor 300 =37145E53
ebp-10=0DD89856 ebp-10=37145E53
eax=3 eax=4
ecx=5 ecx=5
ecx=2*5=A ecx=3*5=F
ecx=not A=FFFFFFF5 ecx=not F=FFFFFFF0
eax=FFFFFF5*3=FFFFFFDF eax=FFFFFFA*2=FFFFFF4
edx=0DD89856 *FFFFFFDF=37145CEA edx=37145E53*FFFFFFF4=3AE86B40
ebp-10=37145CEA ebp-10=3AE86B40
第五次循环。
ecx=4
edx=64('d')
ebp-10=3AE86B40
eax=3AE86B40
eax=3AE86B40+64=3AE86BA4
ebp-10=3AE86BA4
ecx=400
edx=3AE86BA4 xor 400 =3AE86FA4
ebp-10=3AE86FA4
eax=5
ecx=5
ecx=4*5=14
ecx=not 14=FFFFFFEB
eax=FFFFFEB*5=FFFFFF97
edx=3AE86FA4*FFFFFF97=D6AA35BC
ebp-10=D6AA35BC
算法总结,我都弄糊涂了。
N=0
{812276345(基值)+用户名第一位(16进制)} Xor (第N位*100) //A部分
Not[(第N位)*总位数]*(第N位+1) //B部分
A*B=C
循环累加结果C,N=4循环结束,算得真心烦。
【内存注册机】
中断地址
0040163B
中断次数 1
第一字节 E8
指令长度 5
内存方式寄存器 EAX
最后请看胜利截图
到这就不明白了
用W32Dasm查找字符参考。
于是为OD的动态跟踪找到下面一段代码。
* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
我找到的和他不一样啊,请大家帮帮我
附件:chap204.rar 附件:chap204.rar
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课