首页
社区
课程
招聘
[原创]菜鸟试手crackme
发表于: 2011-9-29 14:32 5432

[原创]菜鸟试手crackme

2011-9-29 14:32
5432

在『CrackMe◇ReverseMe』版面看到一个帖子http://http://bbs.pediy.com/showthread.php?t=140109,决定试试如何进行crack,下面是自己的过程,高手飘过

使用工具
windbg    idapro

首先打开程序,是一个简单的窗口,一个输入框,一个ok按钮
在输入框里面随便输入一些数字,然后点击ok,发现程序退出消失了,那我们就从捕获ok这个按钮消息来入手吧

使用windbg载入程序,F5继续运行下去,出现窗口,使用spy+++工具,获取ok窗口的句柄



然后在windbg中中断程序运行,输入命令
bp USER32!TranslateMessage "j dwo(dwo(@esp+4))=002E01B8 & dwo(dwo(@esp+4)+4)=202 '' ; 'gc'"

命令的意思是对USER32!TranslateMessage 系统api设置断点,因为改函数是消息分发的核心函数(当然其他消息分发的函数也可以)

该函数的原型是
BOOL WINAPI TranslateMessage(
  __in  const MSG *lpMsg
);

其第一个参数就是一个消息指针,而消息的结构是
typedef struct tagMSG
        
{
        
    HWND   hwnd ;
        
    UINT   message ;
        
    WPARAM wParam ;
        
    LPARAM lParam ;
        
    DWORD  time ;
        
    POINT  pt ;
        
}
        
MSG, * PMSG ;

因此,这里dwo(dwo(@esp+4))=002E01B8 & dwo(dwo(@esp+4)+4)=202 指的是
第一个参数(esp+4)存放的是msg的指针,因此dwo(@esp+4)是改指针值,然后该指针值指向的是消息结构,所以dwo(dwo(@esp+4))就是消息结构的第一个成员,即处理消息的窗口句柄,而dwo(dwo(@esp+4)+4)就是消息类型

因而,改命令的整个意思,就是当窗口句柄为ok(002E01B8 ,看spy++的图)这个button的时候,并且消息类型是202(WM_LBUTTONUP)时,中断,而其他情况下不中断,其实就是用windbg实现了消息中断,然后F5继续运行起来
在输入框中输入fuckyou(系统中不太可能出现的字符,当然我的有些不雅……),然后用鼠标点击OK键(必须用鼠标点击,不能直接用回车键,因为我们只断了鼠标的消息)
这样,当点击OK键后,windbg就会中断到我们的位置来
eax=00000001 ebx=00000002 ecx=00631748 edx=7c92e401 esi=00432810 edi=00631748
eip=77d18bf6 esp=0012fd38 ebp=0012fd58 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
USER32!TranslateMessage:
77d18bf6 8bff            mov     edi,edi
输入命令kv查看一下栈的情况
ChildEBP RetAddr  Args to Child              
0012fd34 77d274f9 00432810 00432810 00432818 USER32!TranslateMessage (FPO: [1,0,0])
0012fd58 77d3c6d3 0035019c 0067ae90 00432810 USER32!IsDialogMessageW+0x36f (FPO: [2,3,0])
0012fd78 0041dc9b 0035019c 00432810 0012fe40 USER32!IsDialogMessageA+0xfd (FPO: [2,1,4])
WARNING: Stack unwind information not available. Following frames may be wrong.
0012fd88 0041d6a4 00432810 0041a9bf 00432810 image00400000+0x1dc9b
0012febc 00421b37 0000000e 001660a0 00434814 image00400000+0x1d6a4
0012fedc 00421cc8 00000003 001660c8 004327e0 image00400000+0x21b37
0012ffc0 7c817067 010df6f2 010df726 7ffde000 image00400000+0x21cc8
0012fff0 00000000 0040ab8d 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo])
然后shift+f11跳槽系统api,一直运行到程序自己的代码中
eax=00000001 ebx=77d2aeab ecx=00000000 edx=00000000 esi=0012fe40 edi=00432810
eip=0041dc9b esp=0012fd88 ebp=00432810 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
image00400000+0x1dc9b:
0041dc9b 5e              pop     esi
单步走几步看看
同时结合idapro,发现这里好像并没有特别的处理,那么应该校验的地方并不在这里,那么我们就去内存中找找我们刚才输入的字符串
s -a 0 Lffffff "fuckyou" (范围设置大一些)
0:000> s -a 0 lffffff "fuckyou"
00943990  66 75 63 6b 79 6f 75 00-0d f0 ad ba 0d f0 ad ba  fuckyou.........
可以看到字串存放的地址是00943990  
于是对该地址下硬件访问断点
ba r1 00943990  
然后F5运行
0:000> ba r1 00943990  
0:000> g
Breakpoint 1 hit
eax=00000066 ebx=ffffffff ecx=0012ff08 edx=7c92e4f4 esi=004327e0 edi=00943990
eip=0040a6e9 esp=0012fe20 ebp=0012ffc0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image00400000+0xa6e9:
0040a6e9 8b0d68f24200    mov     ecx,dword ptr [image00400000+0x2f268 (0042f268)] ds:0023:0042f268=0042f272
看到代码来到了image00400000+0xa6e9:处
于是去IDAPro看看能否有啥新发现
G到地址0040a6e9处
.text:0040A6C5 ; __int64 __cdecl _atoi64(const char *String)
.text:0040A6C5 __atoi64        proc near               ; CODE XREF: sub_401EF0+68p
.text:0040A6C5
.text:0040A6C5 var_4           = dword ptr -4
.text:0040A6C5 String          = dword ptr  4
.text:0040A6C5
.text:0040A6C5                 push    ecx
.text:0040A6C6                 push    ebx
.text:0040A6C7                 push    ebp
.text:0040A6C8                 push    esi
.text:0040A6C9                 push    edi
.text:0040A6CA                 mov     edi, [esp+14h+String]
.text:0040A6CE
.text:0040A6CE loc_40A6CE:                             ; CODE XREF: __atoi64+35j
.text:0040A6CE                 cmp     dword_42F474, 1
.text:0040A6D5                 jle     short loc_40A6E6
.text:0040A6D7                 movzx   eax, byte ptr [edi]
.text:0040A6DA                 push    8               ; Type
.text:0040A6DC                 push    eax             ; C
.text:0040A6DD                 call    __isctype
.text:0040A6E2                 pop     ecx
.text:0040A6E3                 pop     ecx
.text:0040A6E4                 jmp     short loc_40A6F5
.text:0040A6E6 ; ---------------------------------------------------------------------------
.text:0040A6E6
.text:0040A6E6 loc_40A6E6:                             ; CODE XREF: __atoi64+10j
.text:0040A6E6                 movzx   eax, byte ptr [edi]
.text:0040A6E9                 mov     ecx, dword ptr byte_42F268
.text:0040A6EF                 mov     al, [ecx+eax*2]
.text:0040A6F2                 and     eax, 8
.text:0040A6F5
.text:0040A6F5 loc_40A6F5:                             ; CODE XREF: __atoi64+1Fj
.text:0040A6F5                 test    eax, eax
.text:0040A6F7                 jz      short loc_40A6FC
.text:0040A6F9                 inc     edi
.text:0040A6FA                 jmp     short loc_40A6CE
.text:0040A6FC ; ---------------------------------------------------------------------------
.text:0040A6FC
....................

可以看到是系统api __atoi64在引用,于是直接跳到调用改系统函数的地方sub_401EF0+68地方
.text:00401F53 loc_401F53:                             ; CODE XREF: sub_401EF0+51j
.text:00401F53                 mov     eax, [esp+0D8h+String]
.text:00401F57                 push    eax             ; String
.text:00401F58                 call    __atoi64
.text:00401F5D                 add     esp, 4
.text:00401F60                 cmp     eax, 417981B2h
.text:00401F65                 jnz     short loc_401F6C
.text:00401F67                 cmp     edx, 3
.text:00401F6A                 jz      short loc_401F79
.text:00401F6C
.text:00401F6C loc_401F6C:                             ; CODE XREF: sub_401EF0+75j
.text:00401F6C                 mov     [esp+0D8h+var_4], 2
.text:00401F77                 jmp     short loc_401FE0
有两处关键比对代码
可以看到,是那edx eax组成的64位数(__atoi64返回的结果)与数字3417981b2进行对比,于是讲3417981b2转换成10进制
13983383986

于是尝试输入该号码到输入框,ok,通过……

呵呵,该CM比较简单,很适合新手上路,这里没有对windbg和idapro的操作进行详细说明,不懂的可以参考windbg的帮助文档和论坛大神们的帖子,呵呵,第一次,高兴ing:)


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
haw
2
学习了,看到别人用过OD,第一次看到用windbg和IDA
2011-9-29 15:56
0
雪    币: 397
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
分析的十分详细!一起学习!
2011-9-29 16:02
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
同时初学者
2011-10-6 12:04
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
应该是做得不错的吧 我都没有看明白啊
2011-10-7 08:52
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
新手表示很有压力。等转正式会员再下下来看看
2011-10-10 23:48
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
刚学,希望多多指教
2011-10-11 08:34
0
雪    币: 68
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我也是新学,大家一起交流,共同进步,呵呵
2011-10-12 09:59
0
游客
登录 | 注册 方可回帖
返回
//