吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9348|回复: 4
收起左侧

[CrackMe] 【吾爱2013CM大赛解答】--crack me-RedAgl详细分析

[复制链接]
h_one 发表于 2013-12-17 23:17
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

【文章标题】: 【吾爱2013CM大赛解答】--crack me-RedAgl
【文章作者】:zxcfvasd
【作者主页】: 无
【操作平台】: win xp
【工具】 OD,IDA
【博客地址】http://honeblog.duapp.com/

详细分析:
call 401110,里面主要对窗口类填充,最关心的就是WinProc,窗口消息处理函数了,成功找到并下断。然后根据消息ID下断点,对于这种程序的关心寻找
WM_INIT(初始化),WM_TIMER,WM_COMMAND或按钮消息。这就就很快能分析道程序关键点了。

WM_TIMER 中反调试:

BOOL bRet = EnumWindows(lpEnumFunc/*00402460*/, lParam/*NULL*/);这个函数会列出屏幕上所有的顶级窗口,并以窗口句柄作为的LpEnumFunc参数,这个函数会一直工作到列出所有窗口,
0040132A  |> \6A 00         push 0x0                                              ; /lParam = 0; Case 113 (WM_TIMER) of switch 004011DC
0040132C  |.  68 60244000   push 2013CM1.00402460                                 ; |Callback = 2013CM1.00402460
00401331  |.  FF15 78414000 call dword ptr ds:[<&USER32.EnumWindows>]             ; \EnumWindows
00401337  |.  85C0          test eax,eax
00401339  |.  E9 A0030000   jmp 2013CM1.004016DE
0040133E  |   90            nop      
0040133F  |>  6A 00         push 0x0
00401341  |>  6A 00         push 0x0                                              ; |wParam = 0
00401343  |.  6A 10         push 0x10                                             ; |Message = WM_CLOSE
00401345  |.  57            push edi                                              ; |hWnd
00401346  |.  FF15 A0414000 call dword ptr ds:[<&USER32.SendMessageW>]            ; \SendMessageW
LpEnumFunc函数   查看进程列表是否运行OllyDbg

0040249B  |.  68 04010000   push 0x104                                            ; /Count = 104 (260.)
004024A0  |.  56            push esi                                              ; |Buffer
004024A1  |.  68 66200000   push 0x2066                                           ; |RsrcID = STRING "ollydbg"
004024A6  |.  FF35 B0534000 push dword ptr ds:[0x4053B0]                          ; |hInst = NULL
004024AC  |.  FF15 9C414000 call dword ptr ds:[<&USER32.LoadStringW>]             ; \LoadStringW
004024B2  |.  8B5D 08       mov ebx,[arg.1]
004024B5  |.  53            push ebx                                              ; /hWnd
004024B6  |.  FF15 54414000 call dword ptr ds:[<&USER32.IsWindowVisible>]         ; \IsWindowVisible
004024BC  |.  85C0          test eax,eax
004024BE  |.  74 53         je X2013CM1.00402513
004024C0  |.  68 04010000   push 0x104                                            ; /Count = 104 (260.)
004024C5  |.  57            push edi                                              ; |Buffer
004024C6  |.  53            push ebx                                              ; |hWnd
004024C7  |.  FF15 50414000 call dword ptr ds:[<&USER32.GetWindowTextW>]          ; \GetWindowTextW
004024CD  |.  8B1D 2C414000 mov ebx,dword ptr ds:[<&SHLWAPI.StrStrIW>]            ;  SHLWAPI.StrStrIW
004024D3  |.  56            push esi                                              ; /Pattern
004024D4  |.  57            push edi                                              ; |String
004024D5  |.  FFD3          call ebx                                              ; \StrStrIW
可以直接将je,改成jmp就可以了(上面红色字体),,,,也可以在初始化消息中xxooSetTimer等等


WM_CREATE(初始化中)
首先创建一个互斥对象,保证系统中只有一个程序实例运行
00401240  |.  FF35 C0534000 push dword ptr ds:[0x4053C0]                          ; /MutexName = NULL
00401246  |.  6A 00         push 0x0                                              ; |InitialOwner = FALSE
00401248  |.  6A 00         push 0x0                                              ; |pSecurity = NULL
0040124A  |.  FF15 88404000 call dword ptr ds:[<&KERNEL32.CreateMutexW>]          ; \CreateMutexW
00401250  |.  FF15 80404000 call dword ptr ds:[<&KERNEL32.GetLastError>]          ; [GetLastError
00401256  |.  3D B7000000   cmp eax,0xB7
0040125B  |.  0F84 DE000000 je 2013CM1.0040133F
call 00401700函数中,这个call是创建静态文本框,和编辑框函数。注意最后几行位置00401A8A  |.  A3 78534000   mov dword ptr ds:[0x405378],eax ,全局变量【0x405378】是保存的用户名编辑框句柄,接下来调用SetWindowLongW(NULL, GWL_WNDPROC, EditProc/*401AA0*/);这是给用户名编辑框设置窗口消息回调函数,所以跟上继续分析,

00401ABA  |.  3D 02010000   cmp eax,0x102    MSG
接下来会调用GetWindowText获取到输入用户名
00401B38  |.  E8 E30A0000   call 2013CM1.00402620 进入
可以了解输入用户名位数大于4
int len = strlen(user);
int sum = 0, temp;
char *userstr1;
for(int i; i < len; i++)
{
    sum += user;

}
temp = sum+0x7DD;
temp =temp*0x34;
itoa(temp, usestr1);
这里就是将输入的用户名计算的过程,最后将得到的userstr1,strcat到user后面。保存在[0x4053D0]
004026A5  |.  8D46 FF       lea eax,dword ptr ds:[esi-0x1]
004026A8  |.  8985 ECFEFFFF mov [local.69],eax
004026AE  |.  8BF0          mov esi,eax
004026B0  |>  0FBE040A      /movsx eax,byte ptr ds:[edx+ecx]
004026B4  |.  03F8          |add edi,eax
004026B6  |.  0FBE440A 01   |movsx eax,byte ptr ds:[edx+ecx+0x1]
004026BB  |.  83C1 02       |add ecx,0x2
004026BE  |.  03D8          |add ebx,eax
004026C0  |.  3BCE          |cmp ecx,esi
004026C2  |.^ 7C EC         \jl X2013CM1.004026B0
004026C4  |.  8BB5 E8FEFFFF mov esi,[local.70]
004026CA  |>  3BCE          cmp ecx,esi
004026CC  |.  7D 0A         jge X2013CM1.004026D8
004026CE  |.  0FBE040A      movsx eax,byte ptr ds:[edx+ecx]
004026D2  |.  8985 F0FEFFFF mov [local.68],eax
004026D8  |>  8B8D F0FEFFFF mov ecx,[local.68]
004026DE  |.  6A 0A         push 0xA
004026E0  |.  68 04010000   push 0x104
004026E5  |.  8D85 F8FEFFFF lea eax,[local.66]
004026EB  |.  50            push eax
004026EC  |.  81C1 DD070000 add ecx,0x7DD
004026F2  |.  8D043B        lea eax,dword ptr ds:[ebx+edi]
004026F5  |.  03C1          add eax,ecx                                           ;  usersum + 0x7DD
004026F7  |.  6BC0 34       imul eax,eax,0x34
004026FA  |.  50            push eax
004026FB  |.  FF15 04414000 call dword ptr ds:[<&MSVCR110._itoa_s>]               ;  MSVCR110._itoa_s
00402701  |.  8D85 F8FEFFFF lea eax,[local.66]
00402707  |.  50            push eax
00402708  |.  68 04010000   push 0x104
0040270D  |.  FF35 D0534000 push dword ptr ds:[0x4053D0]
00402713  |.  FF15 08414000 call dword ptr ds:[<&MSVCR110.strcat_s>]              ;  MSVCR110.strcat_s


WM_LBUTTONUP消息


接下来隐藏窗口,然后调用本进程权限,以备后面远程线程注入准备
BOOL EnablePriv()
{
HANDLE hToken;
if ( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
{
       TOKEN_PRIVILEGES tkp;

       LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid );//修改进程权限
       tkp.PrivilegeCount=1;
       tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
       AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL );//通知系统修改进程权限

       return( (GetLastError()==ERROR_SUCCESS) );
}
       return TRUE;
}

接下来进入两个关键call
00401474  |.  E8 C70B0000   call 2013CM1.00402040
00401479  |.  E8 F2060000   call 2013CM1.00401B70
0040147E  |>  6A 05         push 0x5
00401480  |.  57            push edi
call 2013CM1.00402040:

调用CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)函数拍进程成快照,查找PID大于1000的进程,然后调用CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0)拍进程模块,得到kerner32,user32模块地址,然后调用LoadStringW解密字符(),然后比较当前进程是否为解密出进程名其中一个,若是则找到远程注入线程,然后保存该进程PID,在call 2013CM1.00401B70中进行远程注入
004020A2  |.  56            push esi                                              ; /ProcessID => 0
004020A3  |.  6A 02         push 0x2                                              ; |Flags = TH32CS_SNAPPROCESS
004020A5  |.  FF15 2C404000 call dword ptr ds:[<&KERNEL32.CreateToolhelp32Snapsho>; \CreateToolhelp32Snapshot
004020AB  |.  8985 9CF9FFFF mov [local.409],eax
004020B1  |.  83F8 FF       cmp eax,-0x1
004020B4  |.  0F84 37020000 je 2013CM1.004022F1
004020BA  |.  8D8D C8FDFFFF lea ecx,[local.142]
004020C0  |.  51            push ecx
004020C1  |.  50            push eax
004020C2  |.  C785 C8FDFFFF>mov [local.142],0x22C
004020CC  |.  C785 A0F9FFFF>mov [local.408],0x428
004020D6  |.  FF15 30404000 call dword ptr ds:[<&KERNEL32.Process32FirstW>]       ;  kernel32.Process32FirstW
004020DC  |.  85C0          test eax,eax
004020DE  |.  0F84 0D020000 je 2013CM1.004022F1
004020E4  |.  8B1D 00414000 mov ebx,dword ptr ds:[<&MSVCR110._wcsicmp>]           ;  MSVCR110._wcsicmp
004020EA  |.  8D9B 00000000 lea ebx,dword ptr ds:[ebx]
004020F0  |>  8B85 D0FDFFFF /mov eax,[local.140]
004020F6  |.  8985 8CF9FFFF |mov [local.413],eax
004020FC  |.  3905 AC534000 |cmp dword ptr ds:[0x4053AC],eax                      ;  判断是否是当前进程
00402102  |.  0F84 C2010000 |je 2013CM1.004022CA
00402108  |.  3D E8030000   |cmp eax,0x3E8                                        ;  保存pid大于1000 ,,,kernel,user32
0040210D  |.  0F8E B7010000 |jle 2013CM1.004022CA
00402113  |.  50            |push eax                                             ; /ProcessID
00402114  |.  6A 08         |push 0x8                                             ; |Flags = TH32CS_SNAPMODULE
00402116  |.  FF15 2C404000 |call dword ptr ds:[<&KERNEL32.CreateToolhelp32Snapsh>; \CreateToolhelp32Snapshot
0040211C  |.  8D8D A0F9FFFF |lea ecx,[local.408]
00402122  |.  51            |push ecx
00402123  |.  50            |push eax
00402124  |.  8985 98F9FFFF |mov [local.410],eax
0040212A  |.  FF15 34404000 |call dword ptr ds:[<&KERNEL32.Module32FirstW>]       ;  kernel32.Module32FirstW
00402130  |.  85C0          |test eax,eax         
00402132  |.  0F84 86010000 |je 2013CM1.004022BE
00402138  |.  8BBD 98F9FFFF |mov edi,[local.410]
0040213E  |.  8BFF          |mov edi,edi
00402140  |>  8D85 C0F9FFFF |/lea eax,[local.400]
00402146  |.  50            ||push eax
00402147  |.  FF35 C0534000 ||push dword ptr ds:[0x4053C0]                        ;  kernel32
0040214D  |.  FFD3          ||call ebx
0040214F  |.  83C4 08       ||add esp,0x8
00402152  |.  85C0          ||test eax,eax
00402154  |.  75 0D         ||jnz X2013CM1.00402163
00402156  |.  8B85 B4F9FFFF ||mov eax,[local.403]                                 ;  ModuelAddr
0040215C  |.  8985 94F9FFFF ||mov [local.411],eax                      ////将kernel32,user32模块地址分别保存在全局变量中,注意地址后面会用到
00402162  |.  46            ||inc esi
00402163  |>  8D85 C0F9FFFF ||lea eax,[local.400]
00402169  |.  50            ||push eax
0040216A  |.  FF35 C4534000 ||push dword ptr ds:[0x4053C4]                        ;  user32
00402170  |.  FFD3          ||call ebx
00402172  |.  83C4 08       ||add esp,0x8
00402175  |.  85C0          ||test eax,eax
00402177  |.  75 0D         ||jnz X2013CM1.00402186
00402179  |.  8B85 B4F9FFFF ||mov eax,[local.403]
0040217F  |.  8985 90F9FFFF ||mov [local.412],eax
00402185  |.  46            ||inc esi
00402186  |>  8D85 A0F9FFFF ||lea eax,[local.408]
0040218C  |.  50            ||push eax
0040218D  |.  57            ||push edi     
0040218E  |.  FF15 38404000 ||call dword ptr ds:[<&KERNEL32.Module32NextW>]       ;  kernel32.Module32NextW
00402194  |.  85C0          ||test eax,eax
00402196  |.^ 75 A8         |\jnz X2013CM1.00402140


004028E9  |.  A3 DC534000   mov dword ptr ds:[0x4053DC],eax                       ;  存找到的进程pid,,,待会儿远程线程注入


call 2013CM1.00401B70
调用GetVolumeInformationW函数获取收卷序列号的变量,然后将输入用户名到的字符串求和(sum)
然后调用itoa分别对sum,和收卷序列号的变量 进行处理最后将得到的字符连接拷贝到 dword ptr ds:[0x4053CC]FinalUser

00402782  |> \83F9 04       cmp ecx,0x4
00402785  |.^ 7C E9         jl X2013CM1.00402770
00402787  |.  68 04010000   push 0x104                                            ; /pFileSystemNameSize = 00000104
0040278C  |.  8D85 D8F6FFFF lea eax,[local.586]                                   ; |
00402792  |.  50            push eax                                              ; |pFileSystemNameBuffer
00402793  |.  8D85 CCF6FFFF lea eax,[local.589]                                   ; |
00402799  |.  50            push eax                                              ; |pFileSystemFlags
0040279A  |.  8D85 D0F6FFFF lea eax,[local.588]                                   ; |
004027A0  |.  50            push eax                                              ; |pMaxFilenameLength
004027A1  |.  8D85 D4F6FFFF lea eax,[local.587]                                   ; |
004027A7  |.  50            push eax                                              ; |pVolumeSerialNumber
004027A8  |.  68 04010000   push 0x104                                            ; |MaxVolumeNameSize = 104 (260.)
004027AD  |.  8D85 E0F8FFFF lea eax,[local.456]                                   ; |
004027B3  |.  50            push eax                                              ; |VolumeNameBuffer
004027B4  |.  6A 00         push 0x0                                              ; |RootPathName = NULL
004027B6  |.  C785 D0F6FFFF>mov [local.588],0xFF                                  ; |
004027C0  |.  FF15 58404000 call dword ptr ds:[<&KERNEL32.GetVolumeInformationW>] ; \GetVolumeInformationW
004027C6  |.  33C9          xor ecx,ecx
004027C8  |.  85F6          test esi,esi
004027CA  |.  7E 11         jle X2013CM1.004027DD
004027CC  |.  8B15 D0534000 mov edx,dword ptr ds:[0x4053D0]
004027D2  |>  0FBE040A      /movsx eax,byte ptr ds:[edx+ecx]                      ;  edi += usertemp
004027D6  |.  41            |inc ecx
004027D7  |.  03F8          |add edi,eax
004027D9  |.  3BCE          |cmp ecx,esi
004027DB  |.^ 7C F5         \jl X2013CM1.004027D2
004027DD  |>  8B35 04414000 mov esi,dword ptr ds:[<&MSVCR110._itoa_s>]            ;  MSVCR110._itoa_s
004027E3  |.  6A 0A         push 0xA                                              ;  10进制
004027E5  |.  68 04010000   push 0x104
004027EA  |.  8D85 F0FCFFFF lea eax,[local.196]
004027F0  |.  50            push eax
004027F1  |.  FFB5 D4F6FFFF push [local.587]                                      ;  指向收卷序列号的变量
004027F7  |.  FFD6          call esi                                              ;  <&MSVCR110._itoa_s>
004027F9  |.  6A 10         push 0x10                                             ;  16进制
004027FB  |.  68 04010000   push 0x104
00402800  |.  8D85 F8FEFFFF lea eax,[local.66]
00402806  |.  50            push eax
00402807  |.  57            push edi                                              ;  sum
00402808  |.  FFD6          call esi
得到FinalUser字符串




终于到最后一个call了,,,
鼠标一拉发现CreateRemoteThread,哈哈作者真有想法,接下来就是为远程函数准备参数(lpParamer)了
参数中第一个双字是FinalUser长度,第二个是输入假吗长度


00401FB2  |> \6A 00         push 0x0                                              ; /lpThreadId = NULL
00401FB4  |.  6A 00         push 0x0                                              ; |dwCreationFlags = 0
00401FB6  |.  57            push edi                                              ; |lpParameter
00401FB7  |.  56            push esi                                              ; |lpStartAddress
00401FB8  |.  6A 00         push 0x0                                              ; |dwStackSize = 0
00401FBA  |.  6A 00         push 0x0                                              ; |lpThreadAttributes
00401FBC  |.  53            push ebx                                              ; |hProcess
00401FBD  |.  FF15 24404000 call dword ptr ds:[<&KERNEL32.CreateRemoteThread>]    ; \CreateRemoteThread

接下来就是对注入进程进行分析了,,,看看传过去的数据是怎么验证的了。提前挂起被注入进程。对lpStartAddress地址下断

然后运行CreateRemoteThread函数
首先判断传入的FinalUser,与假吗长度是否相等,,,然后对FinalUser变换得到真正序列号
00C40029    33C0            xor eax,eax
00C4002B    8BF7            mov esi,edi
00C4002D    FC              cld                                                     ; ecx 作为循环次数,也作为解密秘钥
00C4002E    AC              lods byte ptr ds:[esi]                                  ; 将esi指向的值传给eax
00C4002F    3C 2D           cmp al,0x2D
00C40031    74 02           je X00C40035                                            ; -
00C40033    33C1            xor eax,ecx                                             ; ecx = C
00C40035    AA              stos byte ptr es:[edi]
00C40036  ^ E2 F6           loopd X00C4002E
00C40038    5E              pop esi
00C40039    5F              pop edi
00C4003A    59              pop ecx
00C4003B    FC              cld
00C4003C    F3:A6           repe cmps byte ptr es:[edi],byte ptr ds:[esi]      比较是否输入正确,,,,
00C4003E    74 02           je X00C40042     ,改成jmp
00C40040    61              popad
00C40041    C3              retn


for(int i = 0; i < len; i++)
{
        key = FinalUser^templen;
        templen--;
}


那么直接可以在母本程序中对两处进行jmp修改.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 1热心值 +1 收起 理由
Chief + 1 吾爱破解2013CM大赛,有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2013-12-17 23:25
代码最好用代码框,不然discuz的代码会有反斜杠的问题。
JoyChou 发表于 2013-12-18 10:04
 楼主| h_one 发表于 2013-12-18 11:07
Hmily 发表于 2013-12-17 23:25
代码最好用代码框,不然discuz的代码会有反斜杠的问题。

昨天晚上太急了,,,,下次注意的{:1_903:}

免费评分

参与人数 1热心值 +1 收起 理由
RedAngel丶 + 1 贴子评不上分,只能在这评了,厉害

查看全部评分

 楼主| h_one 发表于 2013-12-18 11:09
JoyChou 发表于 2013-12-18 10:04
帅气的排版。

嘲讽,,,走的太急没管
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 15:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表