天天看點

一次PEDIY---修改Windows自帶的calc.exe (OD Switch大法)

作者:stalker

【文章标題】: 一次PEDIY---修改Windows自帶的calc.exe

【文章作者】: stalker

【軟體名稱】: calc.exe

【下載下傳位址】: \windows\system32\calc.exe

【使用工具】: OD

【操作平台】: Windows XP Sp2

【作者聲明】: 隻是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!

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

【詳細過程】

  本人對PEDIY比較感興趣,最近瞄上了calc.exe,于是diy之

  我的想法是,在計算之後,按下=号鍵,首先顯示我的ID,然後再顯示計算結果

  首先我們要找到消息處理函數,這樣才能找到按下=号鍵之後執行的代碼

  怎麼找呢?首先我想到的是下202消息斷點,在OD中運作calc.exe

  點"W"

  可以看到如圖所示的資訊

一次PEDIY---修改Windows自帶的calc.exe (OD Switch大法)

  可以看到WinProc處是空的,此時直接下消息斷點的話會下在ClsProc上,OD将會報錯

  這個方法不行,就換個思路吧

  我們可以看到,在ID一欄,=号的ID值為70H

  我們知道程式在收到WM_COMMAND之後将會判斷ID,這樣應該存在一個分支結構

  于是在OD中點右鍵--查找--所有分支,可以看到如下資訊

一次PEDIY---修改Windows自帶的calc.exe (OD Switch大法)

  70H就位于50H-13DH内

  在此處輕按兩下,然後往下查找

  01003348   >  A1 E84E0101   mov     eax, dword ptr [1014EE8]         ;  Case 70 of switch 01002F67

  上面就是=号鍵被按下之後将會跳來的地方,我們就可以在這個地方跳走,然後執行我們的代碼,再跳回去執行原來的代碼

  現在要做的就是随便找一個地方,寫入我們想執行的代碼

  我找的地方位于010136C0

010136C0   > \60            pushad
  010136C1   .  68 6C6C0000   push    6C6C                             ;  此處壓入的是
  010136C6   .  68 33322E64   push    642E3233                         ;  user32.dll的ASCII碼
  010136CB   .  68 75736572   push    72657375                         ;  也可以找個地方直接寫字元串
  010136D0   .  8BC4          mov     eax, esp
  010136D2   .  50            push    eax                              ; /FileName
  010136D3   .  FF15 24100001 call    dword ptr [<&KERNEL32.LoadLibrar>; \LoadLibraryA
  010136D9   .  68 646F7700   push    776F64                           ;  
  010136DE   .  68 6457696E   push    6E695764                         ;  
  010136E3   .  68 726F756E   push    6E756F72                         ;  
  010136E8   .  68 6F726567   push    6765726F
  010136ED   .  68 47657446   push    46746547                         ;  GetForeGroundWindow的ASCII碼
  010136F2   .  8BDC          mov     ebx, esp
  010136F4   .  53            push    ebx                              ; /ProcNameOrOrdinal
  010136F5   .  50            push    eax                              ; |hModule
  010136F6   .  FF15 28100001 call    dword ptr [<&KERNEL32.GetProcAdd>; \GetProcAddress
  010136FC   .  FFD0          call    eax                              ;  調用GetForegroundWindow
  010136FE   .  50            push    eax                              ;  儲存handle,因為後面重新整理的時候還要使用
  010136FF   .  68 93010000   push    193                              ; /ControlID = 193 (403.)
  01013704   .  50            push    eax                              ; |hWnd
  01013705   .  FF15 70110001 call    dword ptr [<&USER32.GetDlgItem>] ; \GetDlgItem
  0101370B   .  6A 65         push    65
  0101370D   .  68 67006B00   push    6B0067
  01013712   .  68 61006E00   push    6E0061
  01013717   .  68 7A006800   push    68007A                           ;  我的名字的UNICODE碼
  0101371C   .  8BDC          mov     ebx, esp
  0101371E   .  53            push    ebx                              ; /Text
  0101371F   .  50            push    eax                              ; |hWnd
  01013720   .  FF15 10110001 call    dword ptr [<&USER32.SetWindowTex>; \SetWindowTextW
  01013726   .  83C4 10       add     esp, 10
  01013729   .  58            pop     eax                              ;  彈出主Window的handle
  0101372A   .  50            push    eax                              ; /hWnd => 0068007A
  0101372B   .  FF15 34110001 call    dword ptr [<&USER32.UpdateWindow>; \UpdateWindow
  01013731   .  68 E8030000   push    3E8                              ; /Timeout = 1000. ms
  01013736   .  FF15 40100001 call    dword ptr [<&KERNEL32.Sleep>]    ; \Sleep
  0101373C   .  83C4 20       add     esp, 20
  0101373F   .  61            popad
  01013740   .  A1 E84E0101   mov     eax, dword ptr [1014EE8]
  01013745   .^ E9 03FCFEFF   jmp     0100334D      

  在上面的過程中我使用了GetForegroundWindow來獲得主Window的句柄,因為程式目前正在被我們操作

  是以應當是處于Topmost的(當然也不排除有特殊情況,主要是我沒有找到更好的辦法來獲得這個handle,那位兄弟有更好的

  辦法,希望能夠告訴我)。

  之是以在SetWindowText之後要重新整理視窗是因為sleep的時候視窗不會重新整理

  盡管我們是在調用sleep之前就執行的SetWindowText,程式執行速度很快,還沒有重新整理Window就sleep了

  是以我們要主動重新整理一次Window(感謝天殺大哥對我的提示)

  好了,整個過程差不多就是這樣拉,現在運算之後按下=号鍵,就會先顯示我的名字,然後再顯示計算結果拉