首页
社区
课程
招聘
[原创]看雪2016 第十四题 CrackMe逆向分析
发表于: 2016-11-30 11:07 5229

[原创]看雪2016 第十四题 CrackMe逆向分析

2016-11-30 11:07
5229

OD打开crackme后在 GetWindowTextW下断,尝试输入注册码111111111111111111111111111断下,返回到程序空间后来到
004015FD  |> \68 FF000000   push    0FF                              ; /Count = FF (255.)
00401602  |.  8D4424 4C     lea     eax, dword ptr [esp+4C]          ; |
00401606  |.  50            push    eax                              ; |Buffer
00401607  |.  68 E9030000   push    3E9                              ; |ControlID = 3E9 (1001.)
0040160C  |.  FF35 106C4200 push    dword ptr [426C10]               ; |hWnd = 002604A6 ('Crack Me',class='CrackMe')
00401612  |.  FF15 40B14100 call    dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextW
00401618  |.  8D4C24 48     lea     ecx, dword ptr [esp+48]
0040161C  |.  E8 AF050000   call    00401BD0
00401621  |>  8B8C24 4C0200>mov     ecx, dword ptr [esp+24C]         ;  Cases 1 (WM_CREATE),110 (WM_INITDIALOG)
00401628  |.  33C0          xor     eax, eax
0040162A  |.  5E            pop     esi

call    00401BD0 这个函数就是主要算法,大致跑了一下发现注册码长度为0x27且前几个字符为acd_b,其中‘_’占位还不确定是什么。进一步发现前0x20个字符必须为a-d的字符。所以注册码改为acdabaabbbccbbbbbbaaadccccaddaaazzzzzzz
00401D16   .  E8 A51A0000   call    004037C0                                        ;根据sn创建了一张表
00401D1B   .  E8 C01B0000   call    004038E0                                        ;根据上面的表创建了另外一张表
00401D20   .  8D95 90FDFFFF lea     edx, dword ptr [ebp-270]
00401D26   .  8D8D 90FBFFFF lea     ecx, dword ptr [ebp-470]
00401D2C   .  E8 1F1D0000   call    00403A50                                        ;用上面那张表解码sn
00401D31   .  66:83BD 0CFEF>cmp     word ptr [ebp-1F4], 0                ;解码后长度必须为0x6c,且为0或1的字符
00401D39   .  0F85 65150000 jnz     004032A4
00401D3F   .  66:83BD 0AFEF>cmp     word ptr [ebp-1F6], 0
00401D47   .  0F84 57150000 je      004032A4

下面是解码后的sn,sn的第一个字节不解码
0019F660  30 00 31 00 30 00 30 00 31 00 31 00 31 00 30 00  0.1.0.0.1.1.1.0.
0019F670  31 00 31 00 31 00 31 00 31 00 30 00 31 00 30 00  1.1.1.1.1.0.1.0.
0019F680  31 00 30 00 30 00 31 00 30 00 31 00 31 00 30 00  1.0.0.1.0.1.1.0.
0019F690  31 00 30 00 31 00 30 00 31 00 30 00 31 00 30 00  1.0.1.0.1.0.1.0.
0019F6A0  31 00 30 00 31 00 31 00 31 00 31 00 31 00 31 00  1.0.1.1.1.1.1.1.
0019F6B0  30 00 30 00 30 00 31 00 30 00 31 00 30 00 31 00  0.0.0.1.0.1.0.1.
0019F6C0  30 00 31 00 31 00 31 00 30 00 30 00              0.1.1.1.0.0.

下面好多类似这样的
00401D73   .  8B3D 2CB04100 mov     edi, dword ptr [<&KERNEL32.GetVe>;  kernel32.GetVersion
00401D79   .  8985 34F2FFFF mov     dword ptr [ebp-DCC], eax
00401D7F   .  C785 50F3FFFF>mov     dword ptr [ebp-CB0], 0
00401D89   .  FFD7          call    edi                              ;  <&KERNEL32.GetVersion>
00401D8B   .  8B35 30B04100 mov     esi, dword ptr [<&KERNEL32.LoadL>;  kernel32.LoadLibraryW
00401D91   .  3C 06         cmp     al, 6
00401D93   .  73 07         jnb     short 00401D9C
00401D95   .  68 FC184200   push    004218FC                         ;  UNICODE "apphelp_xp.dll"
00401D9A   .  EB 05         jmp     short 00401DA1
00401D9C   >  68 1C194200   push    0042191C                         ;  UNICODE "apphelp.dll"
00401DA1   >  FFD6          call    esi
00401DA3   .  68 70194200   push    00421970                         ; /ProcNameOrOrdinal = "SdbDeclareIndex"
00401DA8   .  50            push    eax                              ; |hModule
00401DA9   .  FF15 34B04100 call    dword ptr [<&KERNEL32.GetProcAdd>; \GetProcAddress

我们先查一下这个API "SdbDeclareIndex" 是什么东东吧,发现是shim,以前没搞过,这里顺便学习一下。查阅MSDN了解各种API的功能及参数,对下面的破解很有效。
shim是为软件兼容及打补丁用的中间件,基于APP 和 API之间。了解这些后我们来看看crackme.exe的版本信息。

发现了一些奇怪的东西,好像同解码后的sn有关系。

开始使用IDA进行下一步分析。分析方式是通过MSDN把API信息补上,如下:


这里对时间设置了一下,TAG是TAG_TIME,代码是5001,所以sn的一部分应该是这个数字

经过OD动态跟踪发现
0012F7A4                                            31[0]                0.
0012F7B4  30[1] 30[4] 30[2] 30[5] 31[7] 31[3] 30[6]        0.0.1.1.1.1.1.

[]表示D几bit,正确组成5001的编码如下:
30 00 31 00 30 00 30 00 30 00 31 00 31 00 30 00        
0.1.0.0.0.1.1.0.

下面比较有用的是TAG_COMPANY_NAME,正确的编码应该是版本信息中所显示的

TAG_COMPANY_NAME
0012F788  31 00 30 00 31 00 31 00 30 00 30 00 30 00 30 00  1.0.1.1.1.1.1.1.
0012F798  31 00 31 00                                      0.0.

31 00 30 00 31 00 31 00 30 00 30 00 30 00 30 00 31 00 31 00
10110000011


同样是版本信息中显示的
TAG_PRODUCT_NAME
0012F79E  30 00 31 00 31 00 31 00 31 00 30 00 31 00 30 00  0.1.1.1.1.0.1.0.
0012F7AE  31 00 31 00                                      1.1.
0111101011


TAG_PRODUCT_VERSION
应该是8, 4, 9, 3
0012F742                                            31 00                1.
0012F752  31 00 31 00 30 00                                1.1.0.
正确的1000

0012F752                                            31 00                1.
0012F762  30 00 31 00 30 00                                0.1.0.
正确的0100

0012F762                                            30 00                0.
0012F772  31 00 31 00 30 00                                1.1.0.
正确的1001

0012F772                                            31 00                1.
0012F782  30 00 31 00 30 00                                0.1.0.
正确的0011


TAG_BIN_FILE_VERSION
应该是8, 4, 9, 3
正确的
1110 + 6
1111 + b
1110 + 5
1110 + b

至此我们收集到了所有正确的 01 组合:
0012F748  31 00 31 00 31 00 30 00 31 00 30 00 30 00 30 00  1.1.1.0.1.0.0.0.
0012F758  31 00 31 00 31 00 31 00 30 00 31 00 30 00 30 00  1.1.1.1.0.1.0.0.
0012F768  31 00 31 00 31 00 30 00 31 00 30 00 30 00 31 00  1.1.1.0.1.0.0.1.
0012F778  31 00 31 00 31 00 30 00 30 00 30 00 31 00 31 00  1.1.1.0.0.0.1.1.
0012F788  31 00 30 00 31 00 31 00 30 00 30 00 30 00 30 00  1.0.1.1.0.0.0.0.
0012F798  30 00 31 00 31 00 30 00 31 00 31 00 31 00 31 00  0.1.1.0.1.1.1.1.
0012F7A8  30 00 31 00 30 00 31 00 31 00 30 00 31 00 30 00  0.1.0.1.1.0.1.0.
0012F7B8  30 00 30 00 31 00 31 00 30 00 30 00              0.0.1.1.0.0.
最后一位是 TAG_OS_PLATFORM,应该为 1,试出来的。如果编码sn后,解码时不对,调整最后一位即可。


是一个名称,应该跟shim的行为有关,查了一下为InjectDll,所以最后7个字符应该填充到相应位置上
0012EB94   0012F97C  UNICODE "IuuuuuDuu"
InjectDll
0012F97C  49 00 73 00 6F 00 6A 00 68 00 79 00 44 00 71 00  I.s.o.j.h.y.D.q.
0012F98C  71 00                                            q.
正确的
s.o.j.h.y.q.q.


这个是注入的命令行,一个名称对应一个命令行,进一步验证上面的猜测。


关闭数据库,并且安装,启动新的crackme.exe,猜测新crackme进程会加载crackme.dll(毕竟上面是InjectDll),在crackme.dll中弹出"成功"对话框。

最后将结果编码成正确的sn。分析如下:
由于前几个字母必须为 acd_b 那么abcd对应的正确编码为(直接对应到我们逆出来01中)
a = 01                // 虽然没有a但是可以推出
b = 00
c = 11
d = 10
手动进行编码为
a
cddb
ccab
cdda
cdbc
dcbb
adcc
aadd
bca                // 这里需要将 a -> b TAG_OS_PLATFORM,必须为1
sojhyqq

最终序列号为
acddbccabcddacdbcdcbbadccaaddbcasojhyqq

上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//