(譯) 記憶體補丁的製作例項-修改WDASM

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

(譯) 記憶體補丁的製作例項-修改WDASM   

VB32Dasm - by Lord Rhesus - Assembler-Source
Posted by: AntiCrack on Apr 07, 2002 - 03:27 PM

這個演示程式,試圖告訴你應該如何編寫一個呼叫程式,使用它來解決在另一個可執行程式中存在的問題。舉個例子,怎樣在WDASM 8.93中使用一個補丁,使它可以允許參照VB字串(以前不行)。對於這個功能,補丁呼叫程式好過直接修改WDASM 8.93。如果那樣,當WDASM呼叫非VB編譯的程式是會有問題。

呼叫補丁子程式中,只需要簡單定義新舊位元組,去修補目標程式中的資料段內容,格式如下:

呼叫指令 函式名稱    記憶體地址,      新內容指標,  舊內容指標, 修改的位元組數
invoke   PatchBytes, address in mem, new bytes,  old bytes,  number of bytes

程式中重複地如此呼叫去修改一系列位元組

這個補丁程式已經在使用瞭如下的壓縮/保護外殼的程式中測試過:
UPX 1.01 by Markus Oberhumer & Laszlo Molnar (我推薦的壓縮程式)
Petite 2.2 by Ian Luck (不錯,但壓縮速度慢)
PECompact 1.40b6 by Jeremy Collake (壓縮比不錯) 

在asprotect 1.00的演示版本中出現問題,因為它顯示一個提示框,提示你的程式被asprotect 1.00演示版保護。為了允許被asprotect演示版保護的程式可以使用我們的補丁,需要放一個資訊框在初始化記憶體補丁的子程式前(如後面的演示中被註釋的部分),在程式被裝入記憶體後,讓使用者按OK鍵。

注意,可能你還要在使用了註冊版asprotect如此處理,因為它使用了反跟蹤指令碼。不過我沒有測試過那些版本。

所有榮耀應該歸於r!sc,許多好的想法來自於他的補丁程式。任何抱怨和建議應該給予我。我還在學習 Win32asm,因此我的彙編技術並不很好。

Lord Rhesus
email: lordrhesus@yahoo.co.uk 

;以下是作者提供的彙編原始碼
.386
.model flat, stdcall
option casemap:none
include masm32includewindows.inc
include masm32includekernel32.inc
include masm32includeuser32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib

PatchBytes  proto :DWORD, :DWORD, :DWORD, :DWORD  ;補丁子程式原型定義

;資料段
.data
;MsgWaitTitle      db "Waiting",0                   ;這僅僅為了演示
;MsgWaitText       db "Click OK when program loaded",0 ;為了避免 asprotect 演示版產生的問題。如果你的程式有此問題,請允許此行被編譯(去掉前面的‘;’號)

Msgerror          db "Error!",0
Msgcperror        db "File W32dsm89.exe not found!", 0dh, 0ah, "(確定呼叫程式與WDASM在同一目錄)",0
Msgwperror        db "Error Writing to Memory!",0dh, 0ah, "(如果WDASM已被呼叫,則關閉它!)",0
Msgwrongver       db "Wrong Application or WDASM Changed!",0dh, 0ah, "(關閉被開啟的應用程式!)",0
ProgName          db "W32dsm89.exe",0
OldBytes_1        db 40, 246, 0              ;28,F6 (以ASCII碼顯示的位元組)
NewBytes_1        db 152, 244,0              ;98,F4
OldBytes_2        db "W32",0                 ;在提示條上待修改的字元
NewBytes_2        db "VB ",0                 ;在提示條上改後的字元
processInfo PROCESS_INFORMATION <>
startInfo   STARTUPINFO <>
counter           DWORD ?                  ;在補丁子程式PatchBytes中使用的計數器
readres           LPSTR ?                    ;讀出的被儲存的結果

程式碼段
.code
start:

invoke CreateProcessA, addr ProgName, NULL, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, addr startInfo, addr processInfo  ;建立W32dsm89.exe程式
        test eax, eax
        jz  MsgFileNotFound
        invoke ResumeThread, dword ptr [processInfo + 4]

   ;invoke MessageBox, NULL,addr MsgWaitText, addr MsgWaitTitle, MB_OK 
;避免 asprotect 演示版中出現的問題,如果你被補丁的程式使用了asprotect 演示版保護,請允許這一行程式被編譯(去掉前面的‘;’號)

  invoke PatchBytes, 0041756ch, addr NewBytes_1, addr OldBytes_1, 2h
     invoke PatchBytes, 004bc4fDh, addr NewBytes_2, addr OldBytes_2, 3h
        
ExitLoader:
        invoke CloseHandle, dword ptr [processInfo]
        invoke CloseHandle, dword ptr [processInfo + 4]
        invoke ExitProcess, NULL
;
;########### 錯誤資訊提示 開始#######--ERROR-MESSAGES-START--########
MsgWrongVersion:
        lea eax, Msgwrongver
        jmp DisplayMsg
MsgFileNotFound:
        lea eax, Msgcperror
        jmp DisplayMsg
MsgMemWriteError:
        lea eax, Msgwperror
DisplayMsg:
        invoke MessageBoxA, NULL, eax, addr Msgerror, NULL
        jmp ExitLoader
;######## 錯誤資訊提示 開始####--ERROR-MESSAGES-CLOSE--##

;#### 補丁子程式開始 #####--PATCHBYTES-PROCEDURE-START--######
PatchBytes proc MemLoc:DWORD, NewBytes:DWORD, OldBytes:DWORD, NoBytes:DWORD
GetPatchBytes:
        xor ebx, ebx
        mov ebx, dword ptr [NoBytes]  ; 在ebx中放入待修改的位元組數
        mov edi, dword ptr [OldBytes] ;待修改的位元組
        mov counter, 0h               ; 重置計數器
CheckBytesPresent:
        inc counter
        cmp counter, 8000            ;是否達到了最大迴圈等待次數(可以增加,為了等待被呼叫的程式完全被解碼)
        jz MsgWrongVersion
        
        invoke ReadProcessMemory, dword ptr [processInfo], dword ptr [MemLoc], addr readres, ebx, NULL   ;讀記憶體程式
        pusha
        lea esi, readres
        mov ecx, ebx                 ;ebx中儲存著待比較的位元組數
        repe cmpsb         ;重複比較,檢查記憶體是否出現應該被修改的相關位元組
        popa
        jnz CheckBytesPresent        ;如果不相等就跳轉  並且再次檢查
        mov eax, dword ptr [NewBytes]
        invoke WriteProcessMemory, dword ptr [processInfo], dword ptr [MemLoc], eax, ebx, NULL    ;呼叫寫程式,修改相應的位元組
        test eax, eax
        jz MsgMemWriteError ;不成功則提示錯誤資訊
        ret
PatchBytes endp
;### # 補丁子程式結束 ###--PATCHBYTES-PROCEDURE-CLOSE--#####

end start
;全部程式結束

相關文章