首页
社区
课程
招聘
[原创]SEH Hook
发表于: 2015-5-31 11:13 7841

[原创]SEH Hook

2015-5-31 11:13
7841
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

[课程]Linux pwn 探索篇!

收藏
免费 3
支持
分享
最新回复 (5)
雪    币: 60
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
可不可以 转成 C一份?
2015-5-31 18:58
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
1. VirtualProtect对页属性的修改是针对Page而言的。即使是1字节,也会修改整个Page(典型大小是4KB,此外也有大页面,可能更大)。所以,可能会影响到同Page下的其他API。所以,完善的代码要加上覆盖判断。如果是其他API导致的页面错误,需要想办法过滤。Hook多个API的时候,这个问题尤为突出。除了Hook的时候会重复外,还原的时候,也会一并把同Page里的其他API也还原了。这样,处理多线程也是个问题。

2. 可以考虑用VEH实现。
2015-6-1 03:52
0
雪    币: 90
活跃值: (80)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
这个做法和OD的内存断点是一样的
但是当这个page上有频繁访问的话,速度会变得特别特别慢
2015-6-1 14:11
0
雪    币: 6890
活跃值: (8944)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
5
谢谢指教。把开头的字节修改断点中断应该更好。
2015-6-1 20:45
0
雪    币: 157
活跃值: (416)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
下硬件断点不是更好。不过只能四个地址
2015-6-2 22:33
0
游客
登录 | 注册 方可回帖
返回
//