SEH Hook。
就是用异常处理来达到Hook的目的。
把XXX API函数入口1字节 属性改为PAGE_NOACCESS
处理抛出的异常就可以了。
ps:本来想切换SEH Handler函数的栈来实现读取参数,但是还原备份的时候,保存原始esp的变量莫名其妙的被改写了
:
http://bbs.pediy.com/showthread.php?t=201062
.386
.model flat,stdcall
option casemap:none
include user32.inc
include kernel32.inc
include windows.inc
include msvcrt.inc
includelib msvcrt.lib
includelib user32.lib
includelib kernel32.lib
;############################################################################################
;data segment
;############################################################################################
.data
szMsg db '异常发生位置:%08x 异常代码:%08x,标志:%08x',0dh,0ah
szTitle db '成功处理啦异常',0dh,0ah,0
szHello db 'Hello world!',0dh,0ah,0
szUser32 db 'user32.dll',0
szMessageBoxA db 'MessageBoxA',0
.data?
pMessageBoxA dd ?
;############################################################################################
;code segment
;############################################################################################
.code
;===============
;异常处理子程序
;===============
_Handler proc C _lpRecord,_SEH,_lpContext,_lpDispCotext
LOCAL @szBuffer[256]:byte
LOCAL old:dword
LOCAL o_esp,o_ebp,caller:dword
pushad
mov esi,_lpRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
invoke crt_printf,addr szMsg,[edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlags
mov eax,_SEH
mov ebx,[eax+8] ;取出参数
cmp ebx,pMessageBoxA
jz hookMsg
cmp ebx,0ff55h
jz fixHook
jmp ret_
hookMsg:
mov eax,[edi].regEsp
mov eax,[eax+8]
invoke crt_printf,eax
invoke VirtualProtect,[edi].regEip,1,PAGE_EXECUTE_READWRITE,addr old
mov ecx,[edi].regEip
add ecx,2
invoke VirtualProtect,ecx,1,PAGE_NOACCESS,addr old
mov eax,_SEH
mov dword ptr[eax+8],0ff55h ;标记呢
jmp ret_
fixHook:
;修复Hook
invoke VirtualProtect,pMessageBoxA,1,PAGE_NOACCESS,addr old
invoke VirtualProtect,[edi].regEip,1,PAGE_EXECUTE_READWRITE,addr old
mov eax,_SEH
mov ebx,pMessageBoxA
mov dword ptr[eax+8],ebx ;标记呢
ret_:
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_Handler endp
Hook proc
LOCAL hModule,old:DWORD
invoke GetModuleHandle,addr szUser32
mov hModule,eax
invoke GetProcAddress,hModule,offset szMessageBoxA
mov pMessageBoxA,eax
invoke VirtualProtect,pMessageBoxA,1,PAGE_NOACCESS,addr old
ret
Hook endp
start:
;构造EXCEPTION_REGISTRATION 结构 registration
assume fs:nothing
invoke Hook
push pMessageBoxA ;自定义参数
push offset _Handler
push fs:[0]
mov fs:[0],esp ;挂入链表
mov eax,100
push eax
invoke MessageBox,NULL,addr szHello,NULL,MB_OK
invoke MessageBox,NULL,addr szHello,NULL,MB_OK
pop eax
_safe:
;恢复SEH链表
;invoke MessageBox,NULL,addr szTitle,NULL,MB_OK
pop fs:[0]
pop eax
invoke ExitProcess,0
end start
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法