李沉舟 发表于 2018-2-14 11:16

悬赏区的CrackMe分析

原帖地址:https://www.52hb.com/thread-36070-1-1.html

因为是用流量共享手机开热点上网的,图不是很方便发。各位凑合一下吧。


----------------------------------------------------------------------------------------------------------------------------------------------------------------

话说这好像是小生第一次逛悬赏区,悬赏CrackMe真的是清流啊。大汗。闲来无事,来调戏一下这个小CrackMe。这个CrackMe在启动的时候就有一个注册验证,分析如下:0041FD3B    55            push    ebp
0041FD3C    8BEC            mov   ebp, esp
0041FD3E    81EC 44000000   sub   esp, 0x44
0041FD44    C745 FC 0000000>mov   dword ptr ss:, 0x0
0041FD4B    C745 F8 0000000>mov   dword ptr ss:, 0x0
0041FD52    C745 F4 0000000>mov   dword ptr ss:, 0x0
0041FD59    C745 F0 0000000>mov   dword ptr ss:, 0x0
0041FD60    6A FF         push    -0x1
0041FD62    6A 08         push    0x8
0041FD64    68 14000116   push    0x16010014
0041FD69    68 01000152   push    0x52010001
0041FD6E    E8 EC040000   call    Cm.0042025F
0041FD73    83C4 10         add   esp, 0x10
0041FD76    8945 EC         mov   dword ptr ss:, eax
0041FD79    8D45 EC         lea   eax, dword ptr ss:
0041FD7C    50            push    eax
0041FD7D    E8 3CFFFFFF   call    Cm.0041FCBE                      ; 这里调用了一个易未知支持库函数,得到的文本从十六进制转换,保存结果,记为k
0041FD82    8945 E4         mov   dword ptr ss:, eax   ; 我这里得到的结果一直是0,不知道各位的呢?
0041FD85    8955 E8         mov   dword ptr ss:, edx
0041FD88    8B5D EC         mov   ebx, dword ptr ss:
0041FD8B    85DB            test    ebx, ebx
0041FD8D    74 09         je      short Cm.0041FD98
0041FD8F    53            push    ebx
0041FD90    E8 A6040000   call    Cm.0042023B
0041FD95    83C4 04         add   esp, 0x4
0041FD98    DF6D E4         fild    qword ptr ss:
0041FD9B    DD5D DC         fstp    qword ptr ss:
0041FD9E    DD45 DC         fld   qword ptr ss:
0041FDA1    DC05 00C34000   fadd    qword ptr ds:          ; k += *(double *)0x40C300
0041FDA7    DD5D D4         fstp    qword ptr ss:          ; 保存结果
0041FDAA    DD45 D4         fld   qword ptr ss:          ; 装载结果
0041FDAD    DC25 08C34000   fsub    qword ptr ds:          ; -= *(double *)0x40C308
0041FDB3    DD5D CC         fstp    qword ptr ss:          ; 保存
0041FDB6    DD45 CC         fld   qword ptr ss:          ; 装载
0041FDB9    DC05 10C34000   fadd    qword ptr ds:          ; += *(double *)0x40C310
0041FDBF    DD5D C4         fstp    qword ptr ss:          ; 出
0041FDC2    DD45 C4         fld   qword ptr ss:          ; 入
0041FDC5    DC25 18C34000   fsub    qword ptr ds:          ; -= *(double *)0x40C318
0041FDCB    DD5D BC         fstp    qword ptr ss:          ; 出
0041FDCE    DD45 BC         fld   qword ptr ss:          ; 入
0041FDD1    E8 74F9FFFF   call    Cm.0041F74A                      ; 运算结果转换为int64(返回值由EAX:EDX传递)
0041FDD6    8945 FC         mov   dword ptr ss:, eax      ; 取低32位保存进,记为f
0041FDD9    B8 20C34000   mov   eax, Cm.0040C320               ; ASCII "acbd"
0041FDDE    8945 EC         mov   dword ptr ss:, eax
0041FDE1    8D45 EC         lea   eax, dword ptr ss:
0041FDE4    50            push    eax
0041FDE5    E8 D4FEFFFF   call    Cm.0041FCBE                      ; 十六进制转换得到 EAX - > 0xABCD
0041FDEA    8945 E4         mov   dword ptr ss:, eax   ; = 0xABCD
0041FDED    8955 E8         mov   dword ptr ss:, edx   ; 这里ABCD的高32位就是0
0041FDF0    8B5D EC         mov   ebx, dword ptr ss:
0041FDF3    85DB            test    ebx, ebx
0041FDF5    74 09         je      short Cm.0041FE00
0041FDF7    53            push    ebx
0041FDF8    E8 3E040000   call    Cm.0042023B                      ; 释放内存
0041FDFD    83C4 04         add   esp, 0x4
0041FE00    8B45 E4         mov   eax, dword ptr ss:   ; ntdll.7C93532A
0041FE03    8945 F8         mov   dword ptr ss:, eax      ; = EAX(0xABCD)
0041FE06    DB45 FC         fild    dword ptr ss:         ; 入0xABCD
0041FE09    DD5D E8         fstp    qword ptr ss:          ; 出double
0041FE0C    DD45 E8         fld   qword ptr ss:          ; 压入f
0041FE0F    DB45 F8         fild    dword ptr ss:         ; 压入0xABCD
0041FE12    DD5D E0         fstp    qword ptr ss:          ; 出double,
0041FE15    DC4D E0         fmul    qword ptr ss:          ; f *= 0xABCD
0041FE18    DD5D D8         fstp    qword ptr ss:          ; 结果出
0041FE1B    DD45 D8         fld   qword ptr ss:          ; 再入
0041FE1E    E8 27F9FFFF   call    Cm.0041F74A                      ; 结果转为int64
0041FE23    8945 F4         mov   dword ptr ss:, eax      ; 保存低32位,这是真正的注册码。记为x
0041FE26    68 00000000   push    0x0
0041FE2B    BB 04010000   mov   ebx, 0x104
0041FE30    E8 1E040000   call    Cm.00420253
0041FE35    83C4 04         add   esp, 0x4
0041FE38    8945 EC         mov   dword ptr ss:, eax
0041FE3B    68 78C34000   push    Cm.0040C378                      ; ASCII "\lzq.ini"
0041FE40    FF75 EC         push    dword ptr ss:
0041FE43    B9 02000000   mov   ecx, 0x2
0041FE48    E8 15FEFFFF   call    Cm.0041FC62
0041FE4D    83C4 08         add   esp, 0x8
0041FE50    8945 E8         mov   dword ptr ss:, eax
0041FE53    8B5D EC         mov   ebx, dword ptr ss:
0041FE56    85DB            test    ebx, ebx
0041FE58    74 09         je      short Cm.0041FE63
0041FE5A    53            push    ebx
0041FE5B    E8 DB030000   call    Cm.0042023B
0041FE60    83C4 04         add   esp, 0x4
0041FE63    6A 00         push    0x0
0041FE65    6A 00         push    0x0
0041FE67    6A 00         push    0x0
0041FE69    68 04000080   push    0x80000004
0041FE6E    6A 00         push    0x0
0041FE70    68 81C34000   push    Cm.0040C381                      ; ASCII "cmm"
0041FE75    68 04000080   push    0x80000004
0041FE7A    6A 00         push    0x0
0041FE7C    68 85C34000   push    Cm.0040C385                      ; ASCII "lzq"
0041FE81    68 04000080   push    0x80000004
0041FE86    6A 00         push    0x0
0041FE88    8B45 E8         mov   eax, dword ptr ss:
0041FE8B    85C0            test    eax, eax
0041FE8D    75 05         jnz   short Cm.0041FE94
0041FE8F    B8 89C34000   mov   eax, Cm.0040C389
0041FE94    50            push    eax
0041FE95    68 04000000   push    0x4
0041FE9A    BB C8080000   mov   ebx, 0x8C8
0041FE9F    E8 AF030000   call    Cm.00420253                      ; 读取运行目录下的lzq.ini,并判断节中的cmm项是否为x
如果那个未知库函数的返回结果和我一样为0的话,那么,KeyFile就是lzq.ini,放到程序目录下面就OK了。
Lzq.ini内容如下:
cmm = 648285852

;爆破的话,Very Easy.
0041FF22   /0F84 CB000000   je      Cm.0041FFF3

0041FF08    0f94c0          sete    al
0041FF0B    8945 E8         mov   dword ptr ss:, eax
然后是灰色按钮分析,对于楼主所说易语言的窗体格式编译后的保存形式,我没有研究,也觉得没必要研究,汗。我一般如果补丁的话,就是自己写Loader,在一些恶心的地方,比如CreateWindow上面做文章,慢慢玩,不急嘛~~~在CreateWindowExA上面写断点。若干次中断后。0012FA50   100AE189/CALL 到 CreateWindowExA 来自 krnln.100AE183
0012FA54   00000000|ExtStyle = 0
0012FA58   100E2B30|Class = "BUTTON"
0012FA5C   00B23F90|WindowName = "注册"
0012FA60   4C012F00|Style = WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS|WS_DISABLED|2F00
0012FA64   00000020|X = 20 (32.)
0012FA68   00000050|Y = 50 (80.)
0012FA6C   00000038|Width = 38 (56.)
0012FA70   00000020|Height = 20 (32.)
0012FA74   00040912|hParent = 00040912 ('未注册 By:kkbblzq',class='Afx:10000000:b:10011:1900015:0')
0012FA78   000000A0|hMenu = 000000A0 (window)
0012FA7C   10000000|hInst = 10000000
0012FA80   00000000\lParam = NULL
类名是Windows预定义的BUTTON错不了的,而且风格里面,有个WS_DISABLED。修改的办法很简单。转到0x12FA60,也就是那个风格参数的地方,从4C012F00改为44012F00。然后去掉断点,F9运行起来。不过在此之前,还得把我们的lzq.ini删掉。不出意外,按钮已经激活了。0041F9AB    55            push    ebp
0041F9AC    8BEC            mov   ebp, esp
0041F9AE    81EC 40000000   sub   esp, 0x40
0041F9B4    C745 FC 0000000>mov   dword ptr ss:, 0x0
0041F9BB    C745 F8 0000000>mov   dword ptr ss:, 0x0
0041F9C2    C745 F4 0000000>mov   dword ptr ss:, 0x0
0041F9C9    6A FF         push    -0x1
0041F9CB    6A 08         push    0x8
0041F9CD    68 14000116   push    0x16010014
0041F9D2    68 01000152   push    0x52010001
0041F9D7    E8 83080000   call    Cm.0042025F                      ; 取A码
0041F9DC    83C4 10         add   esp, 0x10
0041F9DF    8945 F0         mov   dword ptr ss:, eax   ; = A码
0041F9E2    8D45 F0         lea   eax, dword ptr ss:
0041F9E5    50            push    eax
0041F9E6    E8 D3020000   call    Cm.0041FCBE                      ; A码从十六进制转int
0041F9EB    8945 E8         mov   dword ptr ss:, eax   ; = intA码
0041F9EE    8955 EC         mov   dword ptr ss:, edx   ; = 高16位
0041F9F1    8B5D F0         mov   ebx, dword ptr ss:
0041F9F4    85DB            test    ebx, ebx                         ; krnln.100E33E4
0041F9F6    74 09         je      short Cm.0041FA01
0041F9F8    53            push    ebx                              ; krnln.100E33E4
0041F9F9    E8 3D080000   call    Cm.0042023B                      ; 释放内存
0041F9FE    83C4 04         add   esp, 0x4
0041FA01    DF6D E8         fild    qword ptr ss:          ; 入A码
0041FA04    DD5D E0         fstp    qword ptr ss:          ; 出0041FA07    DD45 E0         fld   qword ptr ss:
0041FA0A    DC05 00C34000   fadd    qword ptr ds:          ; += *(double *)0x40C300
0041FA10    DD5D D8         fstp    qword ptr ss:          ; 出
0041FA13    DD45 D8         fld   qword ptr ss:          ; 入
0041FA16    DC25 08C34000   fsub    qword ptr ds:          ; -= *(double *)0x40C300
0041FA1C    DD5D D0         fstp    qword ptr ss:          ; 出
0041FA1F    DD45 D0         fld   qword ptr ss:          ; 入
0041FA22    DC05 10C34000   fadd    qword ptr ds:          ; += *(double *)0x40C310
0041FA28    DD5D C8         fstp    qword ptr ss:          ; 出
0041FA2B    DD45 C8         fld   qword ptr ss:          ; 入
0041FA2E    DC25 18C34000   fsub    qword ptr ds:          ; -= *(double *)0x40C318
0041FA34    DD5D C0         fstp    qword ptr ss:          ; 出
0041FA37    DD45 C0         fld   qword ptr ss:          ; 入
0041FA3A    E8 0BFDFFFF   call    Cm.0041F74A                      ; 转int64,只要低32位
0041FA3F    8945 FC         mov   dword ptr ss:, eax      ; 结果记为k
0041FA42    B8 20C34000   mov   eax, Cm.0040C320               ; ASCII "acbd"
0041FA47    8945 F0         mov   dword ptr ss:, eax
0041FA4A    8D45 F0         lea   eax, dword ptr ss:
0041FA4D    50            push    eax                              ; "ABCD"从十六转十
0041FA4E    E8 6B020000   call    Cm.0041FCBE                      ; EAX - > 0xABCD
0041FA53    8945 E8         mov   dword ptr ss:, eax   ; 保存
0041FA56    8955 EC         mov   dword ptr ss:, edx
0041FA59    8B5D F0         mov   ebx, dword ptr ss:
0041FA5C    85DB            test    ebx, ebx                         ; krnln.100E33E4
0041FA5E    74 09         je      short Cm.0041FA69
0041FA60    53            push    ebx                              ; krnln.100E33E4
0041FA61    E8 D5070000   call    Cm.0042023B                      ; 释放内存
0041FA66    83C4 04         add   esp, 0x4
0041FA69    8B45 E8         mov   eax, dword ptr ss:
0041FA6C    8945 F8         mov   dword ptr ss:, eax      ; = 0xABCD
0041FA6F    DB45 FC         fild    dword ptr ss:         ; 入k
0041FA72    DD5D EC         fstp    qword ptr ss:          ; 出
0041FA75    DD45 EC         fld   qword ptr ss:          ; 入
0041FA78    DB45 F8         fild    dword ptr ss:         ; 入0xABCD
0041FA7B    DD5D E4         fstp    qword ptr ss:          ; 出
0041FA7E    DC4D E4         fmul    qword ptr ss:          ; 0xABCD * k
0041FA81    DD5D DC         fstp    qword ptr ss:          ; 结果出
0041FA84    DD45 DC         fld   qword ptr ss:          ; 入
0041FA87    E8 BEFCFFFF   call    Cm.0041F74A                      ; 转为int64
0041FA8C    8945 F4         mov   dword ptr ss:, eax      ; 只要低32位
0041FA8F    68 01030080   push    0x80000301
0041FA94    6A 00         push    0x0
0041FA96    FF75 F4         push    dword ptr ss:
0041FA99    68 01000000   push    0x1
0041FA9E    BB 68010000   mov   ebx, 0x168
0041FAA3    E8 AB070000   call    Cm.00420253                      ; 到文本(十进制)
0041FAA8    83C4 10         add   esp, 0x10
0041FAAB    8945 F0         mov   dword ptr ss:, eax
0041FAAE    6A FF         push    -0x1
0041FAB0    6A 08         push    0x8
0041FAB2    68 03000116   push    0x16010003
0041FAB7    68 01000152   push    0x52010001
0041FABC    E8 9E070000   call    Cm.0042025F                      ; 取注册码
0041FAC1    83C4 10         add   esp, 0x10
0041FAC4    8945 EC         mov   dword ptr ss:, eax
0041FAC7    8B45 F0         mov   eax, dword ptr ss:
0041FACA    50            push    eax
0041FACB    FF75 EC         push    dword ptr ss:
0041FACE    E8 3BFEFFFF   call    Cm.0041F90E                      ; 比较
算法都是一样的,只是用前面提到的未知支持库函数替换了A码。来一发注册机吧。我都不好意思说这是算法分析了,因为这种类型的注册验证。。。。。。直接把反汇编代码抠出来用就好了,毫无技术含量可言。Code = f(user)
if (Code == 用户输入)
.686
.model        flat,stdcall
option        casemap:none

include                windows.inc
include                kernel32.inc
include                user32.inc
includelib        kernel32.lib
includelib        user32.lib

.data
Key1                db        00h,0E0h,45h,0D1h,05h,5Eh,63h,42h
Key2                db        00,00,80h,0B0h,28h,41h,0CEh,41h
Key3                db        00,00,0E2h,0EAh,0C4h,08h,2Fh,42h
Key4                db        00,00,00,00,80h,0B9h,0C2h,40h
Key5                dd        0ACBDh
ACode                dq        2341h                                ;你的A码
Buf                dq        0
Set                dw        0
Old                dw        0


szText                db        '注册码是:%d',0
szTitle                db        'OK!',0
szBuf                db        255        dup(0)
.code
_START:
        fild        ACode
        fstp        ACode
        fld        ACode
        fadd        qword ptr Key1
        fstp        Buf
        fld        Buf
        fsub        qword ptr Key2
        fstp        Buf
        fld        Buf
        fadd        qword ptr Key3
        fstp        Buf
        fld        Buf
        fsub        qword ptr Key4
        fstp        Buf
        fld        Buf
       
        fstcw        Old
        mov        ax,Old
        or        ax,0Ch
        mov        Set,ax
        fldcw        Set
        fistp        Buf
        fldcw        Old
        mov        dword ptr Buf,0
        fild        dword ptr Buf
       
        fstp        Buf
        fld        Buf
        fild        Key5
        fstp        qword ptr Key1
        fmul        qword ptr Key1
       
        fstcw        Old
        mov        ax,Old
        or        ax,0Ch
        mov        Set,ax
        fldcw        Set
        fistp        Buf
        fldcw        Old
        mov        dword ptr Buf,0
       
        invoke        wsprintf,offset szBuf,offset szText,Buf
        invoke        MessageBox,0,offset szBuf,offset szTitle,MB_ICONINFORMATION
       
        invoke        ExitProcess,0
end        _START

syzh802618 发表于 2018-2-15 05:45

感谢楼主分享

过林黑马 发表于 2018-2-21 18:12

厉害了,过年来赶紧来学习一下。

过林黑马 发表于 2018-2-22 18:24

@李沉舟楼主,这里还有个问题。你的激活按钮,是修改了堆栈吧,只能运行一次。我之前看到的小生我怕怕的成品逆向,打开直接看到按钮是激活了的。这是怎么做到的,不知道楼主能否指点一下

李沉舟 发表于 2018-2-23 09:32

过林黑马 发表于 2018-2-22 18:24
@李沉舟楼主,这里还有个问题。你的激活按钮,是修改了堆栈吧,只能运行一次。我之前看到的小生我怕怕的 ...


在内存里面找“按钮2”,往后面找07,改05即可激活。

过林黑马 发表于 2018-2-23 21:38

李沉舟 发表于 2018-2-23 09:32
在内存里面找“按钮2”,往后面找07,改05即可激活。

你的怎么都能查看到按钮2,还有能看到注册这些中文,我查找都是没有的

李沉舟 发表于 2018-2-23 22:01

过林黑马 发表于 2018-2-23 21:38
你的怎么都能查看到按钮2,还有能看到注册这些中文,我查找都是没有的

点一下上面的M,或者按atl+m,ctrl+b,勾选查找整个块


过林黑马 发表于 2018-2-23 22:58

李沉舟 发表于 2018-2-23 22:01
点一下上面的M,或者按atl+m,ctrl+b,勾选查找整个块

找到了,但是不能保存的,这个内存修改。我保存的时候只能保存为mem文件

过林黑马 发表于 2018-2-24 19:31

过林黑马 发表于 2018-2-23 22:58
找到了,但是不能保存的,这个内存修改。我保存的时候只能保存为mem文件

终于搞定了,原来这是要在内存找地址,然后返回数据窗口修改才可以保存。哈哈

现在学习ing 发表于 2018-2-24 20:12

思考了许久   感觉难   
页: [1] 2
查看完整版本: 悬赏区的CrackMe分析