首页
社区
课程
招聘
一个清爽整洁的Crackme的逆向兼形式上去除Bug
发表于: 2006-7-30 19:55 6694

一个清爽整洁的Crackme的逆向兼形式上去除Bug

2006-7-30 19:55
6694

下载地址:http://www.crackmes.de/users/disip/creakme_001

使用工具:
 反编译工具:IDA,Resource Hacker
 程序开发包:MASM32

  一遍又一遍地说差不多的话总觉得烦,干脆直接贴IDA输出的内容算了

======================================================================
; 这些等值定义是用Resource Hacker分析资源得出来的
; enum Control_IDs
ICO_MAIN         = 200
DLG_MAIN         = 1000
ID_EXIT                 = 1001
EDT_NAME         = 1002
EDT_SERIAL         = 1003
ID_REG                 = 1004

                public start            ; 主程序
start                proc near
                push        NULL                ; lpModuleName
                call        GetModuleHandleA
                mov        hInstance, eax
                call        InitCommonControls ; 这个函数好象没起作用,
                                        ; 不过既然无害,姑且留下它,
                                        ; 当然源代码中就应该有包含comctl32.inc(lib)
                push        0                ; dwInitParam
                push        offset _ProcDlgMain ; lpDialogFunc
                                        ; (通过这个参数找到对话框过程)
                push        NULL                ; hWndParent
                push        DLG_MAIN        ; lpTemplateName
                push        hInstance        ; hInstance
                call        DialogBoxParamA
                push        eax                ; uExitCode
                call        ExitProcess
start                endp

; BOOL __stdcall ProcDlgMain(HWND hDlg,UINT uMsg,WPARAM        wParam,LPARAM lParam)
_ProcDlgMain        proc near                ; DATA XREF: start+13o

                                        ; 对话框过程
hDlg                = dword        ptr  8
uMsg                = dword        ptr  0Ch
wParam                = dword        ptr  10h
lParam                = dword        ptr  14h

                push        ebp
                mov        ebp, esp
                mov        eax, [ebp+hDlg]
                mov        hDlgMain, eax
                mov        eax, [ebp+uMsg]
                cmp        eax, WM_INITDIALOG
                jnz        short loc_40106A
                push        ICO_MAIN        ; lpIconName
                push        hInstance        ; hInstance
                call        LoadIconA
                push        eax                ; lParam
                push        ICON_BIG        ; wParam
                push        WM_SETICON        ; Msg
                push        [ebp+hDlg]        ; hWnd
                call        SendMessageA
                jmp        loc_4010F8

loc_40106A:                                ; CODE XREF: _ProcDlgMain+13j
                cmp        eax, WM_COMMAND
                jnz        short loc_4010E9
                mov        eax, [ebp+wParam]
                cmp        eax, ID_EXIT
                jnz        short loc_401089
                push        0                ; lParam
                push        0                ; wParam
                push        WM_CLOSE        ; Msg
                push        [ebp+hDlg]        ; hWnd
                call        SendMessageA

loc_401089:                                ; CODE XREF: _ProcDlgMain+49j
                cmp        eax, ID_REG
                jnz        short loc_4010F8
                push        0FFh                ; nMaxCount
                push        offset szSerial        ; lpString
                push        EDT_SERIAL        ; nIDDlgItem
                push        [ebp+hDlg]        ; hDlg
                call        GetDlgItemTextA
                push        0FFh                ; nMaxCount
                push        offset szUserName ; lpString
                push        EDT_NAME        ; nIDDlgItem
                push        [ebp+hDlg]        ; hDlg
                call        GetDlgItemTextA
                cmp        eax, 3          ; 用户名必须至少3个字符
                jb        short loc_4010CA
                mov        uNameLen, eax
                jmp        short loc_4010E0

loc_4010CA:                                ; CODE XREF: _ProcDlgMain+91j
                push        MB_OK                ; uType
                push        offset szCaption ; ".::        DiS[IP]        Programer ::."
                push        offset szTxtTooShort ; "Min 3 Char on Name!!!"
                push        [ebp+hDlg]        ; hWnd
                call        MessageBoxA
                jmp        short loc_4010E5

loc_4010E0:                                ; CODE XREF: _ProcDlgMain+98j
                call        sub_4010FE        ; 算法过程

loc_4010E5:                                ; CODE XREF: _ProcDlgMain+AEj
                xor        eax, eax
                jmp        short loc_4010F8

loc_4010E9:                                ; CODE XREF: _ProcDlgMain+3Fj
                cmp        eax, WM_CLOSE
                jnz        short loc_4010F8
                push        0                ; nResult
                push        [ebp+hDlg]        ; hDlg
                call        EndDialog

loc_4010F8:                                ; CODE XREF: _ProcDlgMain+35j
                                        ; _ProcDlgMain+5Ej _ProcDlgMain+B7j
                                        ; _ProcDlgMain+BCj
                xor        eax, eax
                leave
                retn        10h
_ProcDlgMain        endp

sub_4010FE        proc near                ; CODE XREF: _ProcDlgMain:loc_4010E0p
                xor        eax, eax
                xor        ebx, ebx
                xor        ecx, ecx
                mov        uLoopCount, eax

loc_401109:                                ; CODE XREF: sub_4010FE+4Fj
                xor        ebx, ebx
                mov        bl, szUserName[eax]
                cmp        bl, 'Z'         ; 如果等于'Z','z','9'之一则减一
                jnz        short loc_401118
                dec        bl

loc_401118:                                ; CODE XREF: sub_4010FE+16j
                cmp        bl, 'z'
                jnz        short loc_40111F
                dec        bl

loc_40111F:                                ; CODE XREF: sub_4010FE+1Dj
                cmp        bl, '9'
                jnz        short loc_401126
                dec        bl

loc_401126:                                ; CODE XREF: sub_4010FE+24j
                push        eax
                add        eax, 'a'
                add        bh, al                ; bh ==        al + 'a'
                pop        eax
                add        bl, 1                ; 这里加了1
                mov        cx, word ptr szSerial[eax*2]
                inc        eax
                push        eax
                cmp        bx, cx
                jnz        short badboy
                add        uLoopCount, 1
                pop        eax
                cmp        eax, uNameLen
                jnz        short loc_401109
                push        eax
                mov        eax, uLoopCount        ; 这里设个变量似乎没必要,
                                        ; 因为eax与uLoopCount的初始值是相等的,
                                        ; 唯一让他们不相等的可能就是在inc eax以后
                                        ; 还没给uLoopCount加1就退出循环,
                                        ; 换言之只可能在cmp bx,        cx以后跳转时发生这种事情,
                                        ; 但这个跳转直接跳到了错误信息分支,
                                        ; 与等到验证eax与uLoopCount不等后跳到的地方是一样的,
                                        ; 所以说uLoopCount这个变量显得多此一举
                cmp        eax, uNameLen
                pop        eax
                jnz        short badboy
                push        MB_OK                ; uType
                push        offset szCaption ; ".::        DiS[IP]        Programer ::."
                push        offset aRegisterCompli ; "Register complite!!!"
                push        hDlgMain        ; hWnd
                call        MessageBoxA
                retn

badboy:                                        ; CODE XREF: sub_4010FE+3Fj
                                        ; sub_4010FE+5Ej
                pop        eax
                push        MB_OK                ; uType
                push        offset szCaption ; ".::        DiS[IP]        Programer ::."
                push        offset aNameOrPassword ; "Name or Password is BAD!!"
                push        hDlgMain        ; hWnd
                call        MessageBoxA
                retn
sub_4010FE        endp

; 常数数据段
; char aNameOrPassword[]
aNameOrPassword        db 'Name or Password is BAD!!',0 ; DATA XREF: sub_4010FE+80o
; char aRegisterCompli[]
aRegisterCompli        db 'Register complite!!!',0 ; DATA XREF: sub_4010FE+67o
; char szCaption[]
szCaption        db '.:: DiS[IP] Programer ::.',0 ; DATA XREF: _ProcDlgMain+9Co
                                        ; sub_4010FE+62o sub_4010FE+7Bo
; char szTxtTooShort[]
szTxtTooShort        db 'Min 3 Char on Name!!!',0 ; DATA XREF: _ProcDlgMain+A1o
                align 10h

; 数据段

; HWND hDlgMain
hDlgMain        dd 0                        ; DATA XREF: _ProcDlgMain+6w
                                        ; sub_4010FE+6Cr sub_4010FE+85r
; char szUserName[]
szUserName        db 6 dup(0)                ; DATA XREF: _ProcDlgMain+7Co
                                        ; sub_4010FE+Dr
; CHAR szSerial
szSerial        db 0Bh dup(0)                ; DATA XREF: _ProcDlgMain+65o
                                        ; sub_4010FE+32r
uNameLen        dd 0                        ; DATA XREF: _ProcDlgMain+93w
                                        ; sub_4010FE+49r sub_4010FE+57r
uLoopCount        dd 0                        ; DATA XREF: sub_4010FE+6w
                                        ; sub_4010FE+41w sub_4010FE+52r
; HINSTANCE hInstance
hInstance        dd 0                        ; DATA XREF: start+7w start+1Fr
                                        ; _ProcDlgMain+1Ar
                align 200h

                end start
======================================================================

上面提到的Bug在什么地方呢?注意标号loc_401089下的两个GetDlgItemText调用,分别是
取序列号和用户名的,在最后一个参数nMaxCount中给的值都是0FFh,这就意味着如果用户
的输入足够长,在文本框中取得的字符数目最大可以达到255;但另一方面szUserName和
szSerial这两个预留缓冲区都只有寥寥几个到十几个字节长,这就造成这样的情况:一旦
输入的用户名长度超过5或者输入的序列号长度超过10,由GetDlgItemText获得的字符串就
会与其他有用内存单元发生交叠,从而导致有用数据被覆盖之类的错误。在源代码里我把
这两个缓冲区的长度都改成了100h(所谓的“形式修正Bug”),但是大家在尝试注册这个
程序时,还是不要输入超过5字符的用户名或者超过10字符的序列号,以免产生意想不到的
后果。

  注册算法很简单:首先是用户名必须至少3个字符,把用户名串中的字符'z','Z',
'9'保持不变,其他字符都加上1;然后在串的每个字符之后依次插入另一个字符,插入的字
符等于原字符在串中的位置序号加上60h,也就是说第一个字符后插入'a',第二个字符后插
入'b',依次类推。例如:

  用户名:                   PEDIY
  除'z','Z','9'外各字符加1:   QFEJZ
  插入代表顺序的字符:           QaFbEcJdZe ---------序列号

  用户名:                       Z9zz
  序列号:                       Za9bzczd

上传文件内容:Noname3.asm 源代码
       1.rc        资源脚本
       Icon_1.ico  图标


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 370
活跃值: (78)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
2
冲天剑兄最近果然是一发冲天,不可收拾啊。
2006-7-30 20:31
0
雪    币: 47147
活跃值: (20465)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
目标程序转份本地
上传的附件:
2006-7-31 09:21
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
真不错,又学到些东东!不过小弟的汇编还在学习中!喜欢以后有机会讨教一下!
2006-7-31 12:35
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
5
最初由 Ryosuke 发布
冲天剑兄最近果然是一发冲天,不可收拾啊。


呵呵~9494
好好学习学习...冲天剑兄的文章
2006-7-31 16:05
0
雪    币: 433
活跃值: (176)
能力值: ( LV13,RANK:1250 )
在线值:
发帖
回帖
粉丝
6
最初由 Ryosuke 发布
冲天剑兄最近果然是一发冲天,不可收拾啊。


没办法啊,大牛就算不吭声也是众人关注的焦点,象我这样的小鸟,没有大牛的本事,只有多吭几声,期望能引来一点目光哦!
2006-7-31 19:14
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
最初由 冲天剑 发布
下载地址:http://www.crackmes.de/users/disip/creakme_001

使用工具:
 反编译工具:IDA,Resource Hacker
 程序开发包:MASM32
........

传说中的天书哦。。。
2006-8-1 14:22
0
游客
登录 | 注册 方可回帖
返回
//