作者: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"
可以看到如圖所示的資訊
可以看到WinProc處是空的,此時直接下消息斷點的話會下在ClsProc上,OD将會報錯
這個方法不行,就換個思路吧
我們可以看到,在ID一欄,=号的ID值為70H
我們知道程式在收到WM_COMMAND之後将會判斷ID,這樣應該存在一個分支結構
于是在OD中點右鍵--查找--所有分支,可以看到如下資訊
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(感謝天殺大哥對我的提示)
好了,整個過程差不多就是這樣拉,現在運算之後按下=号鍵,就會先顯示我的名字,然後再顯示計算結果拉