📄 内存补丁的编写与运用(二).txt
字号:
上次我们给了一个内存补丁的最小系统,它仅仅是修改了被补丁程序的内存,并不能完全控制被补丁程序.然而,说到内存补丁,说道对程序的控制
我们就不能不提一些与调试有关的API函数,我们通过对调试API的应用,可以完全控制我们要补丁的程序,想一想,完全控制我们要破解的程序,多爽!!!
附上例子源码,大家以后可以在它的基础上稍作修改,就可以形成你自己的内存补丁了,:-)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;内存补丁实例(二) Code bY eLaNce@crsky
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
;宏定义
CTEXT MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BREAK_POINT1 equ 0052D014h ;第一个断点,OEP
BREAK_POINT2 equ 00410A08h ;第二个断点
BTEAK_POINT3 equ 00410A27h
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
dbPatched1 db 84h
dbPatched2 db 85h
dbInt3 db 0cch
dbOldByte db 0b8h
szExecFilename db 'CPwdModifyO.exe',0 ;文件名
.data?
align dword
PATCH_POSITION dd ?
dwTemp dd ?
stCT CONTEXT <?>
stDE DEBUG_EVENT <?>
stStartUp STARTUPINFO <>
stProcInfo PROCESS_INFORMATION <>
stProcess PROCESSENTRY32<>
hSnapShot dd ?
;SelectFile db "Select File",0
;fPattern db "*.exe",0,0
;szFileName db 260 dup(0)
.code
Start:
invoke RtlZeroMemory,addr stProcess,sizeof stProcess
mov stProcess.dwSize,sizeof stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0
mov hSnapShot,eax
invoke Process32First,hSnapShot,addr stProcess
.while eax
invoke CompareString,LOCALE_USER_DEFAULT,NORM_IGNORECASE,addr szExecFilename,sizeof szExecFilename,addr stProcess.szExeFile,sizeof szExecFilename
.if eax==2
invoke OpenProcess,PROCESS_TERMINATE,FALSE,stProcess.th32ProcessID
.if eax
mov ebx,eax
invoke TerminateProcess,ebx,-1
invoke CloseHandle,ebx
.endif
.break
.endif
invoke Process32Next,hSnapShot,addr stProcess
.endw
;********************************************************************
; 创建进程
;********************************************************************
invoke GetStartupInfo,addr stStartUp
invoke CreateProcess,offset szExecFilename,NULL,NULL,NULL,NULL,DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS,NULL,NULL,offset stStartUp,offset stProcInfo
.if !eax
invoke MessageBox,NULL,CTEXT("无法装载目标文件,",0dh,"复制本程序到目标程序目录下执行!"),NULL,MB_OK or MB_ICONSTOP
invoke ExitProcess,NULL
.endif
;********************************************************************
; 调试进程
;********************************************************************
.while TRUE
invoke WaitForDebugEvent,addr stDE,INFINITE
.break .if stDE.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT
;********************************************************************
; 如果进程开始,则将入口地址处的代码改为 int 3 断点中断
;********************************************************************
.if stDE.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT
;设置中断点1,断在程序入口处
invoke WriteProcessMemory,stProcInfo.hProcess,BREAK_POINT1,addr dbInt3,1,addr dwTemp
;********************************************************************
; 如果发生断点中断,则恢复断点处代码并进行内存补丁
;********************************************************************
.elseif stDE.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
.if stDE.u.Exception.pExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT
mov stCT.ContextFlags,CONTEXT_FULL
invoke GetThreadContext,stProcInfo.hThread,addr stCT
.if stCT.regEip == BREAK_POINT1 + 1
dec stCT.regEip
;删除中断点1
invoke WriteProcessMemory,stProcInfo.hProcess,BREAK_POINT1,addr dbOldByte,1,addr dwTemp
or stCT.regFlag,100h
invoke SetThreadContext,stProcInfo.hThread,addr stCT
.endif
.elseif stDE.u.Exception.pExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP
mov stCT.ContextFlags,CONTEXT_FULL
invoke GetThreadContext,stProcInfo.hThread,addr stCT
.if stCT.regEip == BREAK_POINT2
;写入补丁代码
invoke WriteProcessMemory,stProcInfo.hProcess,BREAK_POINT2,addr dbPatched1,sizeof dbPatched1,addr dwTemp
invoke WriteProcessMemory,stProcInfo.hProcess,BTEAK_POINT3,addr dbPatched2,sizeof dbPatched2,addr dwTemp
invoke SetThreadContext,stProcInfo.hThread,addr stCT
.else
or stCT.regFlag,100h
invoke SetThreadContext,stProcInfo.hThread,addr stCT
.endif
.endif
.endif
invoke ContinueDebugEvent,stDE.dwProcessId,stDE.dwThreadId,DBG_CONTINUE
.endw
invoke CloseHandle,stProcInfo.hProcess
invoke CloseHandle,stProcInfo.hThread
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end Start
这种内存补丁可以很好的补丁加过可的程序,比我上篇文章种给出的例子好了很多,然而这种补丁同样不完美,也有不小的问题,它每执行一条语句就产生一个单步异常,是它的执行效率非常之低,下一篇文章中我还会再次给出令一种更好的补丁方法.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -