-
-
[原创]一个简单的ASMCrackme分析
-
发表于: 2012-11-5 14:14 4229
-
**Crackmes.de下的。当时已经有solution了自己无聊分析了下。。
【文章标题】: 一个简单的CrackMe
【文章作者】: 大卡神
【作者邮箱】: 287925394@qq.com
【作者QQ号】: 287925394
【下载地址】: http://crackmes.de/users/ksydfius/the_xor_algorithm_ii/download
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
最近一直dota很久没破解了。。
在Crackmes.de随便下了个简单的Crackme来热热手先哈。
==========================================================
The XOR Algorithm II - easy Windows crackme by ksydfius
【ReadMe】的内容
==========================================================
well my first edition of the xor algorithm was too easy
but perhaps that is because u know the position of the key
that is XORed with the plaintext?
anyway i have adjusted the algorithm with a simple modification :)
did this make the algo more secure?
:)
Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: Assembler
Published: 19. Sep, 2012
===========================================================
readme中有说明汇编写的。省去了用peid查了~
因为是win7-64位系统,所以就先改了下兼容模式运行。winxpsp3
OD载入:
004010B5 >/$ 6A 00 push 0 ; /pModule = NULL
004010B7 |. E8 D0000000 call <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
004010BC |. A3 60324000 mov dword ptr [403260], eax
004010C1 |. 6A 00 push 0 ; /lParam = NULL
004010C3 |. 68 DD104000 push 004010DD ; |DlgProc = the_xor_.004010DD
004010C8 |. 6A 00 push 0 ; |hOwner = NULL
004010CA |. 6A 65 push 65 ; |pTemplate = 65
004010CC |. FF35 60324000 push dword ptr [403260] ; |hInst = NULL
004010D2 |. E8 97000000 call <jmp.&user32.DialogBoxParamA> ; \DialogBoxParamA
004010D7 |. 50 push eax ; /ExitCode
004010D8 \. E8 A9000000 call <jmp.&kernel32.ExitProcess> ; \ExitProcess
很常规的入口直接运行。简单分析后来到这里【我就是鼠标上下滚了下就找到了O.O】:
004010F2 . 68 80000000 push 80 ; /Count = 80 (128.)
004010F7 . 68 64324000 push 00403264 ; |Buffer = the_xor_.00403264
004010FC . 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
00401101 . FF75 08 push dword ptr [ebp+8] ; |hWnd
00401104 . E8 71000000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
00401109 . E8 60FFFFFF call 0040106E
0040110E . 33C0 xor eax, eax
00401110 . 33DB xor ebx, ebx
00401112 . 33C9 xor ecx, ecx
00401114 . 33D2 xor edx, edx
00401116 . 8D35 00304000 lea esi, dword ptr [403000] 【操作字串】
0040111C . 8D3D F1304000 lea edi, dword ptr [4030F1] 【目标字串】
00401122 > 8A06 mov al, byte ptr [esi]
00401124 . 8A0F mov cl, byte ptr [edi]
00401126 . 38C8 cmp al, cl
00401128 . 75 25 jnz short 0040114F
0040112A . 46 inc esi
0040112B . 47 inc edi
0040112C . 42 inc edx
0040112D . 81FA F0000000 cmp edx, 0F0
00401133 . 74 02 je short 00401137
00401135 .^ EB EB jmp short 00401122
00401137 > E8 F1FEFFFF call 0040102D 【这个Call用来防止爆破的。没看】
0040113C . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
0040113E . 68 E2314000 push 004031E2 ; |Title = "Nice one!"
00401143 . 68 EC314000 push 004031EC ; |Text = "hU",19,"-",17,"e0lU",1E,"vW]3",81,"",07,"ohcRPd$w\",1D,"<)p]9rA",TAB,"-O'/-\d(Q?.OhO.#JG,L",14,"d$:s?rLR4f,]q:+gmXq?5-e~/",19,"1O",1A,"",1A,"#aJ0hL]$>)!O",1C,";"
00401148 . 6A 00 push 0 ; |hOwner = NULL
0040114A . E8 31000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
那个CALL加这段基本就是这个程序的所有验证了。
跟进CALL内容:
0040106E /$ 55 push ebp
0040106F |. 8BEC mov ebp, esp
00401071 |. 83EC 10 sub esp, 10
00401074 |. 33DB xor ebx, ebx
00401076 |. 33C9 xor ecx, ecx
00401078 |. 33D2 xor edx, edx
0040107A |. 83F8 20 cmp eax, 20 【这句要求注册码有0x20个字符】
0040107D |. 75 31 jnz short 004010B0
0040107F |. 8D3D 00304000 lea edi, dword ptr [403000]
00401085 |. E8 8AFFFFFF call 00401014 【这个CALL跟进】
{
00401014 /$ 33D2 xor edx, edx
00401016 |. 8D35 64324000 lea esi, dword ptr [403264]
0040101C |. B9 20000000 mov ecx, 20
00401021 |> 0216 /add dl, byte ptr [esi]
00401023 |. 46 |inc esi
00401024 |. 49 |dec ecx
00401025 |. 83F9 00 |cmp ecx, 0
00401028 |.^ 7F F7 \jg short 00401021
0040102A |. 33F6 xor esi, esi
0040102C \. C3 retn
【这里获得所有的字符的和并存到dl中】
}
0040108A |. 8BDA mov ebx, edx
0040108C |. E8 6FFFFFFF call 00401000 【这个CALL一样跟进】
{
00401000 /$ 51 push ecx
00401001 |. 8BC3 mov eax, ebx
00401003 |. BB 20000000 mov ebx, 20
00401008 |. 8BCA mov ecx, edx
0040100A |. 33D2 xor edx, edx
0040100C |. F7F3 div ebx
0040100E |. 33DB xor ebx, ebx
00401010 |. 33C9 xor ecx, ecx
00401012 |. 59 pop ecx
00401013 \. C3 retn
【这里把上个CALL得到的值除0x20.余数和商分别在EDX和EAX】
}
00401091 |> 8D35 64324000 /lea esi, dword ptr [403264]
00401097 |. 803F 00 |cmp byte ptr [edi], 0
0040109A |. 74 14 |je short 004010B0
0040109C |. 03F2 |add esi, edx
0040109E |. 8A06 |mov al, byte ptr [esi]
==============
这个EDI是个常量字符串很长。ESI中为我们的输入。
00403000 57 65 20 67 6F 20 61 62 6F 75 74 20 6F 75 72 20 We go about our
00403010 64 61 69 6C 79 20 6C 69 76 65 73 20 75 6E 64 65 daily lives unde
00403020 72 73 74 61 6E 64 69 6E 67 20 61 6C 6D 6F 73 74 rstanding almost
00403030 20 6E 6F 74 68 69 6E 67 20 6F 66 20 74 68 65 20 nothing of the
00403040 77 6F 72 6C 64 2E 20 46 65 77 20 6F 66 20 75 73 world. Few of us
00403050 20 73 70 65 6E 64 20 6D 75 63 68 20 74 69 6D 65 spend much time
00403060 20 77 6F 6E 64 65 72 69 6E 67 20 77 68 79 20 6E wondering why n
00403070 61 74 75 72 65 20 69 73 20 74 68 65 20 77 61 79 ature is the way
00403080 20 69 74 20 69 73 3B 20 77 68 65 72 65 20 74 68 it is; where th
00403090 65 20 63 6F 73 6D 6F 73 20 63 61 6D 65 20 66 72 e cosmos came fr
004030A0 6F 6D 3B 2E 2E 2E 20 77 68 79 20 77 65 20 72 65 om;... why we re
004030B0 6D 65 6D 62 65 72 20 74 68 65 20 70 61 73 74 20 member the past
004030C0 61 6E 64 20 6E 6F 74 20 74 68 65 20 66 75 74 75 and not the futu
004030D0 72 65 3B 20 61 6E 64 20 77 68 79 20 74 68 65 72 re; and why ther
004030E0 65 20 69 73 20 61 20 75 6E 69 76 65 72 73 65 2E e is a universe.
====
004010A0 |. 3007 |xor byte ptr [edi], al
004010A2 |. 0017 |add byte ptr [edi], dl
004010A4 |. 021F |add bl, byte ptr [edi]
004010A6 |. 02DA |add bl, dl
004010A8 |. E8 53FFFFFF |call 00401000 【这个CALL前面分析过了就是把EBX除0x20】
004010AD |. 47 |inc edi
004010AE |.^ EB E1 \jmp short 00401091
004010B0 |> 83C4 10 add esp, 10
004010B3 |. 5D pop ebp
004010B4 \. C3 retn
【稍微总结下就是取注册码每一位操作最后EDI:Ti=[Ky xor Si+dl(y=(dl+bl)mod0x20),其中bl每次+=Ti+和上次的dl].最后处理结果于[4030F1]的数据相同】
4030F1数据如下
004030F1 87 2B 73 5A 30 20 5F 5F 27 39 1E 73 2E 64 5D 72 ?sZ0 __'9s.d]r
00403101 29 68 76 67 19 23 42 3C 1E 5C 3D 6D 48 78 37 37 )hvg#B<\=mHx77
00403111 5B 37 47 32 52 3A 76 69 65 64 20 2D 54 48 3D 39 [7G2R:vied -TH=9
00403121 60 2E 52 34 3B 6A 71 29 8D 2D 5A 6D 47 2B 41 6D `.R4;jq)?ZmG+Am
00403131 4A 38 24 6D 29 66 72 07 5E 6B 20 5D 57 24 1B 45 J8$m)fr^k ]W$E
00403141 68 71 60 55 37 55 70 6E 3A 4C 4F 64 35 29 33 49 hq`U7Upn:LOd5)3I
00403151 73 6A 5D 5F 37 37 5B 1D 6F 57 60 35 61 19 23 44 sj]_77[oW`5a#D
00403161 31 39 33 3B 5C 70 6A 5C 60 34 3B 5E 14 36 60 68 193;\pj\`4;^6`h
00403171 76 60 65 31 2B 23 24 64 36 59 2B 25 23 77 65 2E v`e1+#$d6Y+%#we.
00403181 59 7E 4C 25 6A 33 43 6A 76 5A 62 64 54 10 69 5B Y~L%j3CjvZbdTi[
00403191 23 2B 7D 6F 1B 84 72 38 28 46 17 28 59 7E 5B 3B #+}o剅8(F(Y~[;
004031A1 6E 2A 41 4B 2E 56 09 46 61 49 73 67 58 67 47 73 n*AK.V.FaIsgXgGs
004031B1 58 3C 4D 23 44 27 38 19 6B 77 2B 73 59 38 2A 65 X<M#D'8kw+sY8*e
004031C1 65 50 70 8D 1F 34 51 0D 5E 6B 5A 73 39 28 2A 40 ePp?4Q.^kZs9(*@
004031D1 49 73 50 24 09 33 71 4E 22 2F 69 64 25 31 6C 62 IsP$.3qN"/id%1lb
==========
(0x57 xor x)+d=0x87[d<0x20]
令d=0..0x20.然后求得x。依次排除就可以了吧。
==========
直接用C++编程实现。暴力枚举。
#include<cstdio>
int S[0xF0]=
{
0x57, 0x65, 0x20, 0x67, 0x6F, 0x20, 0x61, 0x62, 0x6F, 0x75,
0x74, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x64, 0x61, 0x69, 0x6C,
0x79, 0x20, 0x6C, 0x69, 0x76, 0x65, 0x73, 0x20, 0x75, 0x6E,
0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x69, 0x6E,
0x67, 0x20, 0x61, 0x6C, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6E,
0x6F, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x6F, 0x66, 0x20,
0x74, 0x68, 0x65, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x2E,
0x20, 0x46, 0x65, 0x77, 0x20, 0x6F, 0x66, 0x20, 0x75, 0x73,
0x20, 0x73, 0x70, 0x65, 0x6E, 0x64, 0x20, 0x6D, 0x75, 0x63,
0x68, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x77, 0x6F, 0x6E,
0x64, 0x65, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x68, 0x79,
0x20, 0x6E, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x69, 0x73,
0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x61, 0x79, 0x20, 0x69,
0x74, 0x20, 0x69, 0x73, 0x3B, 0x20, 0x77, 0x68, 0x65, 0x72,
0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x73, 0x6D,
0x6F, 0x73, 0x20, 0x63, 0x61, 0x6D, 0x65, 0x20, 0x66, 0x72,
0x6F, 0x6D, 0x3B, 0x2E, 0x2E, 0x2E, 0x20, 0x77, 0x68, 0x79,
0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x6D, 0x65, 0x6D, 0x62,
0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73,
0x74, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6E, 0x6F, 0x74, 0x20,
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65,
0x3B, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x68, 0x79, 0x20,
0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61,
0x20, 0x75, 0x6E, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x2E};
int T[0xF0]=
{
0x87, 0x2B, 0x73, 0x5A, 0x30, 0x20, 0x5F, 0x5F, 0x27, 0x39,
0x1E, 0x73, 0x2E, 0x64, 0x5D, 0x72, 0x29, 0x68, 0x76, 0x67,
0x19, 0x23, 0x42, 0x3C, 0x1E, 0x5C, 0x3D, 0x6D, 0x48, 0x78,
0x37, 0x37, 0x5B, 0x37, 0x47, 0x32, 0x52, 0x3A, 0x76, 0x69,
0x65, 0x64, 0x20, 0x2D, 0x54, 0x48, 0x3D, 0x39, 0x60, 0x2E,
0x52, 0x34, 0x3B, 0x6A, 0x71, 0x29, 0x8D, 0x2D, 0x5A, 0x6D,
0x47, 0x2B, 0x41, 0x6D, 0x4A, 0x38, 0x24, 0x6D, 0x29, 0x66,
0x72, 0x07, 0x5E, 0x6B, 0x20, 0x5D, 0x57, 0x24, 0x1B, 0x45,
0x68, 0x71, 0x60, 0x55, 0x37, 0x55, 0x70, 0x6E, 0x3A, 0x4C,
0x4F, 0x64, 0x35, 0x29, 0x33, 0x49, 0x73, 0x6A, 0x5D, 0x5F,
0x37, 0x37, 0x5B, 0x1D, 0x6F, 0x57, 0x60, 0x35, 0x61, 0x19,
0x23, 0x44, 0x31, 0x39, 0x33, 0x3B, 0x5C, 0x70, 0x6A, 0x5C,
0x60, 0x34, 0x3B, 0x5E, 0x14, 0x36, 0x60, 0x68, 0x76, 0x60,
0x65, 0x31, 0x2B, 0x23, 0x24, 0x64, 0x36, 0x59, 0x2B, 0x25,
0x23, 0x77, 0x65, 0x2E, 0x59, 0x7E, 0x4C, 0x25, 0x6A, 0x33,
0x43, 0x6A, 0x76, 0x5A, 0x62, 0x64, 0x54, 0x10, 0x69, 0x5B,
0x23, 0x2B, 0x7D, 0x6F, 0x1B, 0x84, 0x72, 0x38, 0x28, 0x46,
0x17, 0x28, 0x59, 0x7E, 0x5B, 0x3B, 0x6E, 0x2A, 0x41, 0x4B,
0x2E, 0x56, 0x09, 0x46, 0x61, 0x49, 0x73, 0x67, 0x58, 0x67,
0x47, 0x73, 0x58, 0x3C, 0x4D, 0x23, 0x44, 0x27, 0x38, 0x19,
0x6B, 0x77, 0x2B, 0x73, 0x59, 0x38, 0x2A, 0x65, 0x65, 0x50,
0x70, 0x8D, 0x1F, 0x34, 0x51, 0x0D, 0x5E, 0x6B, 0x5A, 0x73,
0x39, 0x28, 0x2A, 0x40, 0x49, 0x73, 0x50, 0x24, 0x09, 0x33,
0x71, 0x4E, 0x22, 0x2F, 0x69, 0x64, 0x25, 0x31, 0x6C, 0x62};
char KeyStr[0x21];
int GetKeyOfD(int n)
{
int i,d,s;
d=n;
for(i=0;i<0xF0;i++)
{
if(KeyStr[d]<0)KeyStr[d]=(T[i]-d)^S[i];
else
{
if(KeyStr[d]!=((T[i]-d)^S[i]))return 0;
}
d=T[i]+d;
d%=0x20;
}
return 1;
}
void main()
{
int i,j;
for(i=0;i<0x20;i++)
{
for(j=0;j<0x20;j++)KeyStr[j]=-1;
if(GetKeyOfD(i))printf("ValidKey:%s\n",KeyStr);
}
while(1);
}
==========
最后得到结果Key:A(U*SYGF(GH9(*5y9][@%}+)78y3htxa
输入后成功了。虽然还有很多不明白的哈哈。马马虎虎就这样吧。
--------------------------------------------------------------------------------
【经验总结】
暴力才是王道。。
--------------------------------------------------------------------------------
2012年11月05日 13:56:34
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)