豪傑3000最大化按鈕無效

看雪資料發表於2015-11-15

豪傑3000最大化按鈕無效

作者:nbw[NE365][DFCG]

QQ : 343538175

http://nboy.cnwlt.com 很希望和Pe Diy愛好者交流或合作



上次我們談了如何把豪傑的螢幕資訊修改,這次讓豪傑3000的最大化按鈕無效。

下面談一下原理。利用SetWindowlongA和GetWindowLongA,把豪傑窗體的屬性改掉,讓其無最大化按鈕無效。故此,找個地方把這兩個函式插到程式的載入過程便可以了。我們首先需要研究的是這兩個函式的使用,和給這兩個函式找個地方。經過研究,比較麻煩的是函式的引數需要視窗控制程式碼,好,那先談談這個吧。

豪傑3000的視窗比較特別,含有多個子視窗,我們需要找的是其主視窗的控制程式碼。根據pll621老大處理w32asm的時候的說法,GetWindowRect需要視窗控制程式碼,於是就可以借用一下那個引數。於是乎,我開啟Trw,bpx GetWindowRect ,找豪傑開啟。靠!不僅頻繁被中斷,而且最後發現豪傑的載入沒有呼叫這個函式,於是以失敗告終。於是我也不想借了,還是用FindWindow函式查詢吧,wowocock老大也同意這麼辦。開啟Pedit,給豪傑載入這個函式,但是提示沒有此函式。查了查MSDN也沒什麼結果,看來小弟水平太次,辦不了啊!哪位老大要知道還請告之一二。

看來還是要從別的函式那裡借來hwnd用用。我知道MessageBoxA的第一個引數可以是hwnd,當然也可以不是。還是看看吧,用w32Dasm開啟SthSDVD.exe,查詢呼叫MessageBoxA的地方,對所有地方的第一個引數研究以下,當然要看有“條件”的了。挑選如下:

:00424806 8B0DB4094900 mov ecx, dword ptr [004909B4]

:00425083 A1B4094900 mov eax, dword ptr [004909B4]

:00426C53 8B842414010000 mov eax, dword ptr [esp+00000114] ;最好把這種轉換成具體的記憶體地址

:004297EA 8B442414 mov eax, dword ptr [esp+14]

:00418C20 A1600B4900 mov eax, dword ptr [00490B60]

:00418D7A A1600B4900 mov eax, dword ptr [00490B60]

:00424806 8B0DB4094900 mov ecx, dword ptr [004909B4]

:00425083 A1B4094900 mov eax, dword ptr [004909B4]

向[004909B4],[00490B60],[004909B4]都極有可能是我們要找的存放hwnd的地方。具體哪個是怎麼判定呢?

開啟豪傑,用視窗控制程式碼察看工具看豪傑的主視窗hwnd=4d8h(當然每次都不一樣),不要關閉豪傑,用winhex開啟SthSDVD.exe的主記憶體空間,檢視上面那一砣地址,發現[4909b4]處是4d8h,所以[4909b4]是主視窗控制程式碼的存放地點。搞了半天,總算把它揪了出來!

根據我們改造的功能,必須讓豪傑載入的時候就呼叫我們的函式,比較簡單的方式就是把豪傑的入口地址改到我們的程式存放地點,就好象一般的PE病毒一樣。但是要注意,[4909b4](也就是控制程式碼)在程式開始載入的時候並沒有被正確裝載,所以在[4909b4]被正確裝載以前我們不可使用之。那我們看看在什麼時候[4909b4]被正確裝載。你可以用TRW載入豪傑,d 4909b4 ,然後一步一步除錯。我這裡圖方便,

使用bpm 4909b4 命令, 然後載入豪傑,中斷在:

0167:0041d0a0 call user32!createwindowexa

0167:0041d0a6 mov [4909b4],eax

上面便是程式確定控制程式碼的地方。原來createwindowexa是用來返回視窗控制程式碼的啊,慚愧,Win32學好些豈不…...

函式需要的引數搞定了,然後給我們新增程式碼找地方。我用自己寫的“視窗剩餘空間檢視器”分析SthSDVD.exe,部分結果如下:

名稱 RVA OA 尺寸D 可寫否

.text 00038926 00037d26 218 否

看來我們要跳到00438926(VA),那裡有218位元組的空間等著我們開發,先跳過去再說,用Hiew開啟SthSDVD.exe,將:

0167:0041d0a0 call user32!createwindowexa

0167:0041d0a6 mov [4909b4],eax

:0041D0AB 8BD8 mov ebx, eax

改為:

* Reference To: USER32.CreateWindowExA, Ord:0055h

|

:0041D0A0 FF15B07C4B00 Call dword ptr [004B7CB0]



:0041D0A6 E97BB80100 jmp 00438926 ;跳轉到新程式碼的地方,eax是主視窗控制程式碼



:0041D0AB 8BD8 mov ebx, eax

下面研究以下把GetWindowLong和SetWindowLong新增到438926的地方。這2個函式的具體使用例項如下:

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long



Const GWL_STYLE = (-16)

Const WS_CAPTION = &HC00000

Const WS_MAXIMIZEBOX = &H10000

Const WS_SYSMENU = &H80000



Private Sub Form_Load()

Dim lhwnd As Long

lwnd = GetWindowLong(Me.hwnd, GWL_STYLE) ;這裡的me.hwnd相當於我們的主窗體控制程式碼

lwnd = lwnd And Not (WS_MAXIMIZEBOX)

lwnd = SetWindowLong(Me.hwnd, GWL_STYLE, lwnd)

End Sub

看完以後就可以把這兩個函式新增到 :00438926,這裡要注意的是一定要保證堆疊的平衡和引數的正確傳遞,大家都是高手,我也不羅嗦了,具體如下:

:00438926 A3B4094900 mov dword ptr [004909B4], eax ;這是原來程式中需要做的

:0043892B 60 pushad ;儲存原來的執行環境

:0043892C 50 push eax ;hwnd入棧,後面有用

:0043892D 33DB xor ebx, ebx

:0043892F 83EB10 sub ebx, 00000010 ;ebx=GWL_STYLE

:00438932 53 push ebx

:00438933 50 push eax ;push hwnd



* Reference To: USER32.GetWindowLongA, Ord:013Ah

|

:00438934 FF15747B4B00 Call dword ptr [004B7B74]

:0043893A 5B pop ebx ;ebx=hwnd,請注意來自:0043892C的入棧

:0043893B B900000100 mov ecx, 00010000

:00438940 F7D1 not ecx

:00438942 23C1 and eax, ecx

:00438944 50 push eax

:00438945 33C0 xor eax, eax

:00438947 83E810 sub eax, 00000010 ;lwnd

:0043894A 50 push eax

:0043894B 53 push ebx ;hwnd



* Reference To: USER32.SetWindowLongA, Ord:021Ah

|

:0043894C FF15707B4B00 Call dword ptr [004B7B70]

:00438952 61 popad ;恢復原來程式的執行環境

:00438953 E95347FEFF jmp 0041D0AB ;返回原來程式

最後提醒一下在寫記憶體地址的時候要注意區分VA,RVA和檔案偏移地址。


相關文章