📄 artic.asm
字号:
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 + -