diy pe教學2 (11千字)

看雪資料發表於2002-08-09

上篇我講述瞭如何修改中游軍棋的求和顯示到右邊的riched框,
這次我教大家如何在上面增加一個按鈕,然後如何捕捉這個按鈕的事件,當點選這個增加的按鈕幹一點我們自己想幹的事情,好廢話少說,突入正題。
首先用觀察軍棋的右邊有四個按鈕,分別是幫助、設定、大廳、退出,好現在我們增加一個按鈕叫歡迎(在我自己做的補丁裡面這個按鈕是作弊,專門用來解散棋局用的,但是限於中游的公平,我不能教大家如何作弊只能教大家如何diy pe了)。首先用資源編輯器(我用的是資源駭客)開啟
junqi.exe觀察到這四個按鈕如下:
104 DIALOGEX 0, 0, 213, 364
STYLE WS_CHILD
CAPTION ""
LANGUAGE LANG_CHINESE, 0x2
FONT 9, "宋體"
{
  CONTROL "", 1008, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 0, 338, 181, 13
  CONTROL "幫助(&H)", 1014, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 13, 170, 35, 15
  CONTROL "設定(&S)", 1013, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 67, 170, 35, 15
  CONTROL "大廳(&P)", 1001, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 13, 190, 35, 15
  CONTROL "退出(&X)", 1000, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 67, 190, 35, 15
  CONTROL "", 1016, "RICHEDIT", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 0, 213, 213, 106 , 0x00000200
  CONTROL "顏色", 1015, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 181, 322, 25, 13
  CONTROL "", 1005, "{8856F961-340A-11D0-A96B-00C04FD705A2}", 0x50010000, 0, 0, 213, 60
  CONTROL "List1", 1006, "SysListView32", LVS_REPORT | LVS_SINGLESEL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 0, 60, 213, 103
  CONTROL "", 1002, COMBOBOX, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_VSCROLL, 0, 322, 120, 166
  CONTROL "", 1003, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 123, 322, 53, 81
  CONTROL "傳送", 1004, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 182, 338, 25, 14
}
好我們現在就增加一個按鈕,增加以後的資源如下:
104 DIALOGEX 0, 0, 213, 364
STYLE WS_CHILD
CAPTION ""
LANGUAGE LANG_CHINESE, 0x2
FONT 9, "宋體", FW_DONTCARE, FALSE, 0
{
  CONTROL "", 1008, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 0, 338, 181, 13
  CONTROL "幫助(&H)", 1014, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 13, 171, 35, 15
  CONTROL "歡迎(&L)", 1011, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 115, 170, 35, 15
  CONTROL "設定(&S)", 1013, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 67, 170, 35, 15
  CONTROL "大廳(&P)", 1001, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 13, 190, 35, 15
  CONTROL "退出(&X)", 1000, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 67, 190, 35, 15
  CONTROL "", 1016, "RICHEDIT", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 0, 213, 213, 106 , 0x00000200
  CONTROL "顏色", 1015, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 181, 322, 25, 13
  CONTROL "", 1005, "{8856F961-340A-11D0-A96B-00C04FD705A2}", 0x50010000, 0, 0, 213, 60
  CONTROL "List1", 1006, "SysListView32", LVS_REPORT | LVS_SINGLESEL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 0, 60, 213, 103
  CONTROL "", 1002, COMBOBOX, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_VSCROLL, 0, 322, 120, 166
  CONTROL "", 1003, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 123, 322, 53, 81
  CONTROL "傳送", 1004, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 182, 338, 25, 14
}
這裡和上面不同的是多了下面這句,
CONTROL "歡迎(&L)", 1011 BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 115, 170, 35, 15
記住增加按鈕要更改其control id,否則有重複的id的話,搞得幾個按鈕的功能會一樣,這是因為windows是靠id來判別點選的是那個按鈕
我這裡把id改為1015,換成16進位制就是3f3,用資源駭客編譯一下(你用別的資源編輯器如c++的,都行),執行一下,看看旁邊多了一個
名叫歡迎的按鈕,點選這個按鈕,怎麼沒有反應,不要急你還沒有給這個按鈕加入事件呢,怎麼會有反應呢?下一步就是給這個按鈕加入
事件,首先我們要了解windows的機制,點選這個按鈕後,windows會sendmessage 一個command訊息給應用程式查api手冊就知道。command
訊息帶有wParam引數,這個引數就是你的按鈕id,那麼我們現在的任務就是找到應用程式判斷訊息的地方。。我們下斷點bpx seedmessage
點選,那個幫助的按鈕,然後仔細觀察程式的走向,你會發現訊息判別在這個地方:
:004391AB B8D8A24400              mov eax, 0044A2D8
:004391B0 E853EDFEFF              call 00427F08
:004391B5 83EC54                  sub esp, 00000054
:004391B8 8365F000                and dword ptr [ebp-10], 00000000
:004391BC 53                      push ebx
:004391BD 8B5D08                  mov ebx, dword ptr [ebp+08]
:004391C0 56                      push esi
:004391C1 57                      push edi
:004391C2 81FB11010000            cmp ebx, 00000111===》比較訊息是否是111(wm_command)
:004391C8 8BF9                    mov edi, ecx
:004391CA 7518                    jne 004391E4
:004391CC FF7510                  push [ebp+10]
:004391CF 8B07                    mov eax, dword ptr [edi]
:004391D1 FF750C                  push [ebp+0C]======>這裡傳遞按鈕的id(也就是wParam引數)點選幫助按鈕,這裡我們可以看到id為3f6(1014)正好是幫助的control id
:004391D4 FF5078                  call [eax+78]
:004391D7 85C0                    test eax, eax
:004391D9 0F8455010000            je 00439334
:004391DF E91D040000              jmp 00439601

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004391CA(C)
|
:004391E4 83FB4E                  cmp ebx, 0000004E


跟蹤進call [eax+78]到下面(現在你就要牢牢的抓住這個3f6看看程式是如何判斷和傳遞3f6的id的)我這裡call 【eax+78】是到達
:00439747 55                      push ebp
:00439748 8BEC                    mov ebp, esp
:0043974A 83EC2C                  sub esp, 0000002C
:0043974D 8B4508                  mov eax, dword ptr [ebp+08]
:00439750 53                      push ebx
:00439751 56                      push esi
:00439752 57                      push edi
:00439753 0FB7F8                  movzx edi, ax
:00439756 33DB                    xor ebx, ebx
:00439758 8BF1                    mov esi, ecx
:0043975A C1E810                  shr eax, 10
:0043975D 395D0C                  cmp dword ptr [ebp+0C], ebx
:00439760 894508                  mov dword ptr [ebp+08], eax
:00439763 753A                    jne 0043979F
:00439765 3BFB                    cmp edi, ebx
:00439767 7466                    je 004397CF
:00439769 8D4DD4                  lea ecx, dword ptr [ebp-2C]
:0043976C E8ACFFFFFF              call 0043971D
:00439771 8B06                    mov eax, dword ptr [esi]
:00439773 8D4DD4                  lea ecx, dword ptr [ebp-2C]
:00439776 53                      push ebx
:00439777 51                      push ecx
:00439778 6AFF                    push FFFFFFFF
:0043977A 57                      push edi
:0043977B 8BCE                    mov ecx, esi
:0043977D 897DD8                  mov dword ptr [ebp-28], edi
:00439780 FF500C                  call [eax+0C]
:00439783 395DFC                  cmp dword ptr [ebp-04], ebx
:00439786 743E                    je 004397C6
:00439788 895D08                  mov dword ptr [ebp+08], ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004397CD(C)
|
:0043978B 8B06                    mov eax, dword ptr [esi]
:0043978D 53                      push ebx
:0043978E 53                      push ebx
:0043978F 8BCE                    mov ecx, esi
:00439791 FF7508                  push [ebp+08]
:00439794 57                      push edi
:00439795 FF500C                  call [eax+0C]==》這裡就會call那個幫助的ie哦好我們再這個call裡面去一趟

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004397C9(U), :004397D1(U)
|
:00439798 5F                      pop edi
:00439799 5E                      pop esi
:0043979A 5B                      pop ebx
:0043979B C9                      leave
:0043979C C20800                  ret 0008

call [eax+0C]會到達下面
:0043E4D6 B85CA34400              mov eax, 0044A35C
:0043E4DB E8289AFEFF              call 00427F08
:0043E4E0 51                      push ecx
:0043E4E1 51                      push ecx
:0043E4E2 57                      push edi
:0043E4E3 8BF9                    mov edi, ecx
:0043E4E5 FF7514                  push [ebp+14]
:0043E4E8 FF7510                  push [ebp+10]
:0043E4EB FF750C                  push [ebp+0C]
:0043E4EE FF7508                  push [ebp+08]==>這裡又看到老朋友3f6了
:0043E4F1 E8D0CAFFFF              call 0043AFC6==》看來進這個call吧
:0043E4F6 85C0                    test eax, eax
:0043E4F8 7405                    je 0043E4FF

call 0043AFC6 裡面繼續跟蹤,會發現比較訊息的id是在下面這段
:0043B09B FF7508                  push [ebp+08]==》這裡能看到老朋友3f6
:0043B09E FF750C                  push [ebp+0C]
:0043B0A1 53                      push ebx
:0043B0A2 FF7604                  push [esi+04]
:0043B0A5 E87DE0FFFF              call 00439127
:0043B0AA 85C0                    test eax, eax
:0043B0AC 7504                    jne 0043B0B2

call 00439127裡面如下
:00439127 55                      push ebp
:00439128 8BEC                    mov ebp, esp
:0043912A 53                      push ebx
:0043912B 8B5D08                  mov ebx, dword ptr [ebp+08]
:0043912E 8B450C                  mov eax, dword ptr [ebp+0C]
:00439131 8B5510                  mov edx, dword ptr [ebp+10]
:00439134 8B4D14                  mov ecx, dword ptr [ebp+14]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00439144(U)
|
:00439137 837B1000                cmp dword ptr [ebx+10], 00000000
:0043913B 741D                    je 0043915A
:0043913D 3B03                    cmp eax, dword ptr [ebx]
:0043913F 7405                    je 00439146

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00439149(C), :0043914E(C), :00439153(C)
|
:00439141 83C318                  add ebx, 00000018
:00439144 EBF1                    jmp 00439137

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043913F(C)
|
:00439146 3B5304                  cmp edx, dword ptr [ebx+04]
:00439149 75F6                    jne 00439141
:0043914B 3B4B08                  cmp ecx, dword ptr [ebx+08]=》cx是老朋友3f6
這裡就是比較id的地方了,你能看到ebx+08是3e9(退出)等按鈕的比較
:0043914E 72F1                    jb 00439141
:00439150 3B4B0C                  cmp ecx, dword ptr [ebx+0C]
:00439153 77EC                    ja 00439141
:00439155 895D08                  mov dword ptr [ebp+08], ebx
:00439158 EB05                    jmp 0043915F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043913B(C)
|
:0043915A 33C0                    xor eax, eax
:0043915C 894508                  mov dword ptr [ebp+08], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00439158(U)
|
:0043915F 8B4508                  mov eax, dword ptr [ebp+08]
:00439162 5B                      pop ebx
:00439163 5D                      pop ebp
:00439164 C21000                  ret 0010

好了知道比較的地方就可以更改了,首先找一段空白的地址,放自己的程式碼,然後修改上面的比較程式碼jmp 到自己程式碼地址,加入我們自己的id比較3f3

cmp ecx,3f3
jz 自己想幹的事情的地方,你可以參照我上篇文章,做個在riched輸出文字的程式碼段
下面就是恢復原程式的動作
然後跳回原程式

需要注意的事項:不要把堆疊搞亂了,否則你看到的就是非法操作了。而不是你想看到的東西:)
這樣你可以加好多個按鈕,每個按鈕做不同的事情。把程式玩弄於鼓掌之間,達到了diy pe的目的
如果感覺我的diy pe還可以的話,我就再寫篇diy pe之三,寫教學很累,比看程式,和寫程式都累,勞動需要得到肯定,謝謝大家支援!

                        你的朋友:pll621

相關文章