大理寺少卿 发表于 2024-12-26 22:13:55

Win32汇编学习笔记05.补课

定位关键点3种方法:过程函数       api      字符串

但是不确定用要哪一种方法,可以3种方法都用一下,因为在不同的程序,实用的方法是不一样的

### 窗口程序看控件信息

#### 1.通过OD去看

!(./notesimg/1653476883125-44a681ca-9e21-47d5-a118-c97d72156407.png)

#### 还可以用   spy ++ 查看

!(./notesimg/1653477121644-cdca04a6-11ff-4133-9046-8ab47cebacdf.png)

还可以用vs2019 ,打开软件,找到对应控件直接看属性

!(./notesimg/1653477223742-6db700d5-bace-4229-82ef-958d4099c032.png)

一般拿句柄没用,因为按钮是响应 WM_COMMAND 消息,因此需要知道控件id

可以修改控件属性的软件:    eXeScope       Restorato

OD 没有查看资源的功能

OD没有通过控件ID下断点功能 ,可在在 WM_COMMAND 消息 下条件断点

### COM注册机

1. 第一件事情就是定位关键点

关键点一般还是看它弹得什么窗扣,然后通过窗口上的字符串取OD查找字符串,找到字符串后下断点,运行程序,看看有没有断下来

1. 寻找关键分支

找到关键点后,找到函数开头,然后看一下所有条件跳转,因为肯定存在校验后的失败和成功跳转,在所有跳转下断点后,重新运行软件,看看失败后执行那些分支执行了跳转,没执行的 就说明不是

1. 查看关键分支最近的call ,因此这个 调用校验算法 一般是通过调用函数 实现的

可以通过删除该段代码,看看程序是否提示失败,如果没有就说明该出是调用校验算法,验证完就撤销修改

1. 校验算法一般移位和算术运算用的很多

找到关键代码复制出来,然后去分析算法,分析算法主中函数的功能传入和传出,即参数和返回值,猜出其大概作用,然后用自己的代码去替换

```
xor   esi, esi
mov   dword ptr , esi
L002:
mov   ebp, dword ptr
or      ecx, FFFFFFFF
mov   edi, ebp
xor   eax, eax
repne   scas byte ptr es:
not   ecx
dec   ecx
mov   eax, esi
xor   edx, edx
mov   edi, ebp
div   ecx
mov   ecx, dword ptr
mov   eax, esi
movsx   ebx, byte ptr
xor   edx, edx
div   ecx
movsx   eax, byte ptr
lea   edx, dword ptr
lea   eax, dword ptr
mov   edx, esi
imul    edx, esi
imul    edx, esi
imul    edx, ecx
add   ebx, eax
or      ecx, FFFFFFFF
xor   eax, eax
add   ebx, edx
repne   scas byte ptr es:
not   ecx
dec   ecx
mov   eax, ebx
xor   edx, edx
div   ecx
lea   ecx, dword ptr
mov   al, byte ptr
push    eax
call    0042F29A
test    esi, esi
je L050
mov   eax, esi
xor   edx, edx
mov   ecx, 3
div   ecx
test    edx, edx
jnz L050
push    004640F8
lea   ecx, dword ptr
call    0042F273
L050:
inc   esi
cmp   esi, 9
jb L002
```

!(./notesimg/1653483410205-8cfd1b19-ffc3-44c8-9083-2bc4ecc03106.png)

说明存在一个全局的字符传 "0123456789"

!(./notesimg/1653484811453-41024af6-723b-42c0-89c2-6a4a6c83717c.png)

这几个寄存器是直接赋值,所以没有保存什么特殊的值,分析时可以不用管

跟我们输入字符串长度一样,所以猜测可能会是字符串长度

!(./notesimg/1653483639909-d421c6ed-1fd5-4eeb-8df0-db27305cb3b8.png)

!(./notesimg/1653483761254-52eac375-9049-47e6-a6b9-002f3772b009.png)

有点像是取字符串

!(./notesimg/1653483870273-ea4431eb-7a8b-4b4e-ad0b-3aef2551552b.png)

取用户名

!(./notesimg/1653484128249-3c371f9d-d835-4ace-9194-a352aa83c617.png)

观察call执行前后的变化,发现他在拼接字符

!(./notesimg/1653484271492-9ead1276-5811-4d2b-bd2e-f99c5c885e82.png)

观察此处 call 发现他在拼接 '-'

!(./notesimg/1653485223935-01e2eab6-3203-45d4-b531-0eb594ebf4eb.png)

把执行后的结果拿去测试,看看是否成功没,如果成功后面就不需要看了,说明上面就是生成注册码的算法

```
.386
.model flat, stdcall;32 bit memory model
option casemap :none;case sensitive

include Register.inc

.data
    g_szUserName db 128 dup(0)

   
    g_szNumberdb "0123456789", 0       ;常量字符串
    g_szSerNumb db "6769-", 32 dup(0)    ;注册码
    g_ch      db 2 dup(0)            ;拼接的字符
    g_szGang    db "-", 0                ;拼接的字符
    g_dwCnt   dd 0                     ;用户名长度
.code

start:

        invoke GetModuleHandle,NULL
        mov                hInstance,eax

    invoke InitCommonControls
        invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
        invoke ExitProcess,0

;########################################################################


Make proc uses esi ecx edi ebxhWin:HWND
    LOCAL @dwCnt:DWORD

invoke GetDlgItemText, hWin, EDT_USERNAME, offset g_szUserName, size g_szUserName
   
mov g_dwCnt, eax   ;将字符串长度给 g_dwCnt

;算法解析开始
push ebp   ;因为改变了 edp,所以需要先入栈

xor   esi, esi
L002:
lea   ebp, g_szNumber   ;获取字符串地址
or      ecx, 0FFFFFFFFh
mov   edi, ebp
xor   eax, eax
repne   scas byte ptr es:
not   ecx
dec   ecx
mov   eax, esi
xor   edx, edx
mov   edi, ebp
div   ecx
mov   ecx, g_dwCnt    ;这里换全局变量是因为 ebp的值发生了改变
mov   eax, esi
movsx   ebx, byte ptr
xor   edx, edx
div   ecx
movsx   eax, byte ptr
lea   edx, dword ptr
lea   eax, dword ptr
mov   edx, esi
imul    edx, esi
imul    edx, esi
imul    edx, ecx
add   ebx, eax
or      ecx, 0FFFFFFFFh
xor   eax, eax
add   ebx, edx
repne   scas byte ptr es:
not   ecx
dec   ecx
mov   eax, ebx
xor   edx, edx
div   ecx
mov   al, byte ptr
mov   g_ch,al                                       ;将 al转成字符串
invoke crt_strcat, offset g_szSerNumb, offset g_ch    ;字符拼接
test    esi, esi
je L050
mov   eax, esi
xor   edx, edx
mov   ecx, 3
div   ecx
test    edx, edx
jnz L050
invoke crt_strcat, offset g_szSerNumb, offset g_szGang;拼接字符串
L050:
inc   esi
cmp   esi, 9
jb L002
pop ebp    ;出栈

    ;显示到界面
    invoke SetDlgItemText,hWin, EDT_SERNUMBER, offset g_szSerNumb

    ret

Make endp


DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

        mov                eax,uMsg
        .if eax==WM_INITDIALOG

        .elseif eax==WM_COMMAND
          mov eax, wParam
          .if ax == BTN_MAKE
                invoke Make, hWin
          .endif

        .elseif eax==WM_CLOSE
                invoke EndDialog,hWin,0
        .else
                mov                eax,FALSE
                ret
        .endif
        mov                eax,TRUE
        ret

DlgProc endp

end start

```

注册成功删除 注册表重新注册   搜索   4Developers
页: [1]
查看完整版本: Win32汇编学习笔记05.补课