⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 artic.asm

📁 一个增加记事本软件功能的教程
💻 ASM
📖 第 1 页 / 共 3 页
字号:
    gdi32.dll           SetBkColor          14065
    
    
    
;=========================================步骤5  修改记事本代码======================================

;====================增加对话框的颜色,下划线,删除线选项.====================

    用OD打开记事本,查找调用ChooseFont,来到以下代码.
    
0100308A  |.  C785 B4FDFFFF 410>MOV     [LOCAL.147], 01000041                         ; cf.Flags;
01003094  |.  89B5 B8FDFFFF     MOV     [LOCAL.146], ESI                              ; |cf.rgbColors
0100309A  |.  89B5 BCFDFFFF     MOV     [LOCAL.145], ESI                              ; |cf.lCustData
010030A0  |.  89B5 C0FDFFFF     MOV     [LOCAL.144], ESI                              ; |cf.lpfnHook
010030A6  |.  89B5 C4FDFFFF     MOV     [LOCAL.143], ESI                              ; |cf.lpTemplateName
010030AC  |.  89B5 C8FDFFFF     MOV     [LOCAL.142], ESI                              ; |cf.hInstance
010030B2  |.  89B5 CCFDFFFF     MOV     [LOCAL.141], ESI                              ; |cf.lpszStyle
010030B8  |.  66:C785 D0FDFFFF >MOV     WORD PTR SS:[EBP-230], 2000                   ; |cf.nFontType
010030C1  |.  89B5 D4FDFFFF     MOV     [LOCAL.139], ESI                              ; |cf.nSizeMin
010030C7  |.  89B5 D8FDFFFF     MOV     [LOCAL.138], ESI                              ; |cf.nSizeMax
010030CD  |.  FF15 90110001     CALL    DWORD PTR DS:[<&USER32.ReleaseDC>]            ;
010030D3  |.  8D85 A0FDFFFF     LEA     EAX, [LOCAL.152]                              ; 
010030D9  |.  50                PUSH    EAX                                           ; &cf参数入栈
010030DA  |.  FF15 D0120001     CALL    DWORD PTR DS:[<&comdlg32.ChooseFontW>]        ; \ChooseFont(&cf)
;................
;................


    将pCHOOSEFONT的各成员分析出来,可知,Flags成员在SS:[EBP-24C],因此这里只需要将0100308A改为

;更改后的0100308A

0100308A      C785 B4FDFFFF 410>MOV     DWORD PTR SS:[EBP-24C], 01000141              ; 0100041|100
               
                                                                                      ; 变成0100141
    保存更改到文件,运行更改后的文件,此时出现了颜色等效果选项,但是现在还不能起作用.        
    
    
                 
                                                                                                      
;====================保存选择的颜色到clText(RVA==AF94)========================

010030E0  |.  85C0              TEST    EAX, EAX
010030E2  |.  0F84 7F020000     JE      01003367
0101301F    FF35 84AB0001      PUSH    DWORD PTR DS:[100AB84]                         ; 更新这一句跳到自己的保存代码



;0101301F更改为010030E8,多余字节用NOP填充
010030E8    - E9 32FF0000       JMP     01013000                                      ; 上一句更改后的代码
010030ED      90                NOP                                                   ; 多余字节用NOP填充

010030EE  |.  8B1D 8C110001     MOV     EBX, DWORD PTR DS:[<&USER32.SetCursor>]       ; 自己的代码最后必须跳回此处.
;................
;................



;010030E8跳到此处,自己的代码

01013000    FF35 84AB0001       PUSH    DWORD PTR DS:[100AB84]                        ; 还原0101301F被修改后的代码
01013006    A3 FCAF0001         MOV     DWORD PTR DS:[100AFFC], EAX                   ; 保存EAX现场
0101300B    8B4424 28           MOV     EAX, DWORD PTR SS:[ESP+28]                    ; EAX=pCHOOSEFONT.rgbColor
                                                                                      ; 保存选择的颜色到EAX
0101300F    A3 94AF0001         MOV     DWORD PTR DS:[100AF94], EAX                   ; 保存到crText(RVA==AF94)
01013014    A1 FCAF0001         MOV     EAX, DWORD PTR DS:[100AFFC]                   ; 还原EAX 
01013019  - E9 D000FFFF         JMP     010030EE                                      ; 跳回原程序处




;====================在中处理"背景色"菜单(==1C)的WM_COMMAND(==111)消息======================

;首先用RegisterClass(Ex)函数定位WndProc(主窗口的消息处理函数)

    RegisterClassEx只有一个参数WNDCLASSEX,此结构体定义如下

typedef struct {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX
    
    
    一共12个成员,其中第3个成员就是窗口的消息处理函数.在堆栈中它们的顺序是反的,应该倒着数,也就是第10个成员
    在OD中用 RegisterClassEx 函数找到以下初始化 WNDCLASSEX 结构体的代码
    
    
        
;RegisterClassEx注册窗口类

010044E2  |.  C745 D0 30000000  MOV     [LOCAL.12], 30                          ; |成员cbSize=30
010044E9  |.  FF15 1C120001     CALL    DWORD PTR DS:[<&USER32.GetSystemMetrics>; \GetSystemMetrics
010044EF  |.  F7D8              NEG     EAX
010044F1  |.  1BC0              SBB     EAX, EAX
010044F3  |.  05 017F0000       ADD     EAX, 7F01
010044F8  |.  50                PUSH    EAX                                     ; /RsrcName=EAX
010044F9  |.  33FF              XOR     EDI, EDI                                ; |
010044FB  |.  57                PUSH    EDI                                     ; |hInst=NULL
010044FC  |.  FF15 D8110001     CALL    DWORD PTR DS:[<&USER32.LoadCursorW>]    ; \EAX=LoadCursorW(NULL,RsrcName);
01004502  |.  6A 02             PUSH    2                                       ; /RsrcName = 2.
01004504  |.  56                PUSH    ESI                                     ; |hInst
01004505  |.  8945 EC           MOV     [LOCAL.5], EAX                          ; |hCursor=EAX;
01004508  |.  FF15 EC110001     CALL    DWORD PTR DS:[<&USER32.LoadIconW>]      ; \EAX=LoadIconW(hInst,RsrcName);
0100450E  |.  57                PUSH    EDI                                     ; /Options => LR_DEFAULTCOLOR
0100450F  |.  6A 10             PUSH    10                                      ; |Height = 10 (16.)
01004511  |.  6A 10             PUSH    10                                      ; |Width = 10 (16.)
01004513  |.  6A 01             PUSH    1                                       ; |Type = IMAGE_ICON
01004515  |.  6A 02             PUSH    2                                       ; |ResourceName = 2
01004517  |.  56                PUSH    ESI                                     ; |hInst
01004518  |.  8945 E8           MOV     [LOCAL.6], EAX                          ; |成员hIcon(大图标)
0100451B  |.  FF15 D4110001     CALL    DWORD PTR DS:[<&USER32.LoadImageW>]     ; \LoadImageW
01004521  |.  8945 FC           MOV     [LOCAL.1], EAX                          ; 成员hIconSm(小图标)
01004524  |.  8D45 D0           LEA     EAX, [LOCAL.12]
01004527  |.  50                PUSH    EAX                                     ; /参数pWndClassEx入栈
01004528  |.  C745 F4 01000000  MOV     [LOCAL.3], 1                            ; 成员lpszMenuName;
0100452F  |.  8975 E4           MOV     [LOCAL.7], ESI                          ; |hInstance=hInst;
01004532  |.  C745 F8 20900001  MOV     [LOCAL.2], 01009020                     ; 成员lpszClassName="Notepad"
01004539  |.  C745 D8 29340001  MOV     [LOCAL.10], 01003429                    ; |lpfnWndProc=01003429
                                                                                ; 窗口处理函数01003429
01004540  |.  C745 F0 06000000  MOV     [LOCAL.4], 6                            ; 成员hbrBackground
01004547  |.  897D D4           MOV     [LOCAL.11], EDI                         ; 成员style
0100454A  |.  897D DC           MOV     [LOCAL.9], EDI                          ; 成员cbClsExtra;
0100454D  |.  897D E0           MOV     [LOCAL.8], EDI                          ; |成员cbWndExtra;
01004550  |.  FF15 D0110001     CALL    DWORD PTR DS:[<&USER32.RegisterClassExW>; \RegisterClassExW
;................
;................



    由以上代码分析可知WNDPROC=01003429,来到函数WNDPROC
    
;WNDPROC

01003429      8BFF              MOV     EDI, EDI                                ;
0100342B  /.  55                PUSH    EBP                                     ; ESP-4
0100342C  |.  8BEC              MOV     EBP, ESP                                ; EBP=ESP
0100342E  |.  51                PUSH    ECX                                     ; ESP-4
0100342F  |.  51                PUSH    ECX                                     ; ESP-4
01003430  |.  56                PUSH    ESI                                     ; ESP-4
01003431  |.  8B75 0C           MOV     ESI, DWORD PTR SS:[EBP+C]               ; ESI=message
01003434  |.  83FE 1C           CMP     ESI, 1C                                 
01003437  |.  57                PUSH    EDI                                     ; ESP-4
01003438  |.  6A 08             PUSH    8
0100343A  |.  5A                POP     EDX                                     ; EDX=8;
0100343B  |.  0F87 41020000     JA      01003682                                ; if(message>1C) goto 01003682
;................                                                               ; WM_COMAND==111>1C所以到01003682
;................                                                               
                                                              
                                                                                
    理一下堆栈,[EBP]=原EBP,[EBP+4]=返回地址,[EBP+8]=hWnd,[EBP+C]=message,[EBP+10]=wParam,[EBP+14]=lParam



;0100343B跳到此处

01003682  |> \8B7D 14           MOV     EDI, DWORD PTR SS:[EBP+14]              ; EDI=lParam        
01003685  |.  8BC6              MOV     EAX, ESI                                ; EAX=message
01003687  |.  2D 11010000       SUB     EAX, 111                                ; EAX-=111(=WM_COMMAND)
0100368C  |.  0F84 35020000     JE      010038C7                                ; if(eax==WM_COMMAND) goto 010038C7
;................                                                               ; 到WM_COMMAND的处理过程
;................    
               
            
                                                                           
;0100368C跳到此处

010038C7  |> \3B3D 38980001     CMP     EDI, DWORD PTR DS:[1009838]             ; 
010038CD  |.  75 4C             JNZ     SHORT 0100391B                          ;
;................
;................


    这里遇到一个条件转移,但是我们并不清楚,1009838里放着什么,如果点击了"背景色"菜单,这里是跳不是不跳呢?不清楚,所以我们必须弄清楚,这里DWORD PTR DS:[1009838],但是因为 EDI=lParam,在WM_COMMAND中,对于菜单,lParam==0,对于控件,lParam=控件窗口句柄.因此DWORD PTR DS:[1009838]最有可能是一个句柄,在记事本程序中,要在代码中使用句柄的也许只有编辑框和主窗口了.而且,在主窗口的消息处理函数中,很少用lParm与hWnd比较的(几乎没有).所以这里假设它为编辑框的句柄.
    
    为了确定,用CreateWindowEX函数找到创建编辑框的代码,有两个,其中一个包含了对地址DWORD PTR DS:[1009838]的访问如下

;................
;................
01004771  |.  FF15 E0110001     CALL    DWORD PTR DS:[<&USER32.CreateWindowExW>>; \CreateWindowExW
01004777  |.  3BC3              CMP     EAX, EBX
01004779      A3 38980001       MOV     DWORD PTR DS:[1009838], EAX             ;  1009838=hEdit
;................
;................



    很容易看出来,DWORD PTR DS:[1009838]保存的就是编辑框句柄hEdit(也可用查找的方法找到DWORD PTR DS:[1009838])的保存的什么.
    回到010038C7继续分析,由于对于菜单,lParam为0,即EDI=0,所以EDI!=hEdit,程序将跳到0100391B继续执行.

010038C7  |> \3B3D 38980001     CMP     EDI, DWORD PTR DS:[1009838]             ; lParam!=hEdit
010038CD  |.  75 4C             JNZ     SHORT 0100391B                          ; 点击"背景色"菜单,此处必跳
;................
;................



;010038CD跳到此处

0100391B  |> \57                PUSH    EDI                                     ; /Arg3=lParam
0100391C  |.  FF75 10           PUSH    DWORD PTR SS:[EBP+10]                   ; |Arg2=wParam
0100391F  |.  FF75 08           PUSH    DWORD PTR SS:[EBP+8]                    ; |Arg1=hWnd
01003922  |.  E8 60F2FFFF       CALL    01002B87                                ; \非编辑框的WM_COMMAND消息的处理函数
;................
;................



;01003922处调用此处,非编辑框的WM_COMMAND消息的处理函数01002B87(hWnd,wParam,lParam)

01002B87  /$  8BFF              MOV     EDI, EDI
01002B89  |.  55                PUSH    EBP                                     ; ESP-4
01002B8A  |.  8BEC              MOV     EBP, ESP                                ; EBP=ESP
                                                                                ; [EBP+4]=返回地址,[EBP+8]=hWnd
                                                                                ; [EBP+C]=wParam,[EBP+10]=lParam
01002B8C  |.  81EC 60020000     SUB     ESP, 260                                ; ESP-260;
01002B92  |.  A1 04960001       MOV     EAX, DWORD PTR DS:[1009604]             ;   
01002B97  |.  8B55 08           MOV     EDX, DWORD PTR SS:[EBP+8]               ; EDX=hWnd
01002B9A  |.  53                PUSH    EBX                                     ; ESP-4
01002B9B  |.  56                PUSH    ESI                                     ; ESP-4
01002B9C  |.  57                PUSH    EDI                                     ; ESP-4
01002B9D  |.  8945 FC           MOV     DWORD PTR SS:[EBP-4], EAX               ; localVar1=EAX
01002BA0  |.  33F6              XOR     ESI, ESI                    
01002BA2  |.  33C0              XOR     EAX, EAX                                ; EAX=ESI=0;
01002BA4  |.  66:89B5 F4FDFFFF  MOV     WORD PTR SS:[EBP-20C], SI               ; localVar83=0
01002BAB  |.  B9 81000000       MOV     ECX, 81                                 ; ECX=81;
01002BB0  |.  8DBD F6FDFFFF     LEA     EDI, DWORD PTR SS:[EBP-20A]             ; EDI=&localVar82
01002BB6  |.  F3:AB             REP     STOSD                                   
01002BB8  |.  66:AB             STOSW

01002BBA  |.  0FB77D 0C         MOVZX   EDI, WORD PTR SS:[EBP+C]                ; EDI=wParam 取得控件/菜单ID到EDI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -