昨天才发现不是原创,这种方案是VEH HOOK的一种实现方案。VEH HOOK很久很久以前都被广泛使用了。只是自己没听说过。好悲哀呀。。。。
如果VEH HOOK在内核态处理异常获取函数参数会变成什么样子呢?
代码模拟:
程序输出
本人编码能力比较弱所以只能靠windbg大哥哥了去吧皮卡丘,皮卡皮卡皮卡
以下为Windows7 x64 sp1的简单逆向。
接下来就是感兴趣的童鞋开始简单粗暴的验证了。
系统提供服务接口,以dll形式提供,如创建文件CreateFile存在于kernel32.dll,访问网络WSAConnect存在于Ws2_32.dll。API是函数,所在页属性为
*
*
可读和执行
*
*
。
系统提供服务接口,以dll形式提供,如创建文件CreateFile存在于kernel32.dll,访问网络WSAConnect存在于Ws2_32.dll。API是函数,所在页属性为
*
*
可读和执行
*
*
。
如果把API所在页的
*
*
内存页属性改为不可以执行
*
*
,执行API时候就会产生异常,若是能捕获该异常在异常处理程序中就可以获取异常发生的地址,通过地址可以反查询调用的API信息,在从异常中获取参数。同时将该异常所在页的属性改为
*
*
可以执行
*
*
,将调用地址所在的页设置成
*
*
不可以执行
*
*
。这样当API执行完之后返回到调用地址时又产生异常,此时在异常处理程序中获取API的返回值。重复以上操作就可以了。
```。
利用Exception 来实现Hook Api。在Exception处理程序里获得参数和返回值。
如果把API所在页的
*
*
内存页属性改为不可以执行
*
*
,执行API时候就会产生异常,若是能捕获该异常在异常处理程序中就可以获取异常发生的地址,通过地址可以反查询调用的API信息,在从异常中获取参数。同时将该异常所在页的属性改为
*
*
可以执行
*
*
,将调用地址所在的页设置成
*
*
不可以执行
*
*
。这样当API执行完之后返回到调用地址时又产生异常,此时在异常处理程序中获取API的返回值。重复以上操作就可以了。
```。
利用Exception 来实现Hook Api。在Exception处理程序里获得参数和返回值。
PVOID HeapMemory
=
NULL;
PVOID MainFunctionAddress
=
NULL;
int
RunFunction(
int
*
a,
int
*
b){
*
a
=
*
a
+
1
;
*
b
=
*
b
+
1
;
return
*
a
+
*
b;
}
VOID main(
int
argc, char
*
argv[])
{
MainFunctionAddress
=
GetDbgFunctionPointerAddress(main);
/
/
申请内存属性为读写权限
HeapMemory
=
VirtualAlloc(NULL, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
int
a
=
1
, b
=
11
;
LPVOID Address
=
(LPVOID)RunFunction;
Address
=
GetDbgFunctionPointerAddress(RunFunction);
/
/
将RunFunction的内容复制到HeapMemory。
RtlCopyMemory(HeapMemory, Address,
0x3b
);
ZxDebug((
"HeapMemory = %p MainFunctionAddress=%p \n"
, HeapMemory, MainFunctionAddress));
__try
{
/
/
执行HeapMemory,asmcall jmp r8
/
/
内存属性为读写,执行函数会产生异常
for
(
int
i
=
0
; i <
3
; i
+
+
)
asmcall((PVOID)&a, (PVOID)&b, HeapMemory);
}__except(FilterException(GetExceptionCode(), GetExceptionInformation()))
{
ZxDebug((__FUNCTION__
"():: EXCEPTION_EXECUTE_HANDLE\n"
));
}
ZxDebug((__FUNCTION__
"():: a = %d b = %d\n"
, a, b));
}
int
FilterException(ULONG ExceptionCode, _EXCEPTION_POINTERS
*
Exception)
{
MEMORY_BASIC_INFORMATION Mbi
=
{};
SIZE_T Size
=
VirtualQuery(Exception
-
>ExceptionRecord
-
>ExceptionAddress, &Mbi, sizeof(MEMORY_BASIC_INFORMATION));
DWORD flOldProtect
=
0
;
ZxDebug((__FUNCTION__
"():: ExceptionAddress:%p \n"
, Exception
-
>ExceptionRecord
-
>ExceptionAddress));
if
(Exception
-
>ExceptionRecord
-
>ExceptionAddress
=
=
HeapMemory)
{
assert
(ExceptionCode
=
=
STATUS_ACCESS_VIOLATION && Mbi.Protect
=
=
PAGE_READWRITE);
assert
(Exception
-
>ExceptionRecord
-
>ExceptionAddress
=
=
HeapMemory);
PVOID NextRip
=
(PVOID)(
*
(ULONG_PTR
*
)Exception
-
>ContextRecord
-
>Rsp);
int
a
=
*
(
int
*
)Exception
-
>ContextRecord
-
>Rcx;
int
b
=
*
(
int
*
)Exception
-
>ContextRecord
-
>Rdx;
ZxDebug((__FUNCTION__
"():: RunFunction(a = %d b= %d) NextRip=%p\n"
, a, b, NextRip));
/
/
将HeapMemory内存属性改为可执行。将Main函数改为不可执行
VirtualProtect(HeapMemory, PAGE_SIZE, PAGE_EXECUTE_READ,&flOldProtect);
VirtualProtect((PVOID)MainFunctionAddress, PAGE_SIZE, PAGE_READWRITE,&flOldProtect);
}
else
{
assert
(ExceptionCode
=
=
STATUS_ACCESS_VIOLATION && Mbi.Protect
=
=
PAGE_READWRITE);
if
((ULONG_PTR)MainFunctionAddress <
=
(ULONG_PTR)Exception
-
>ExceptionRecord
-
>ExceptionAddress
&&(ULONG_PTR)Exception
-
>ExceptionRecord
-
>ExceptionAddress <
=
(ULONG_PTR)MainFunctionAddress
+
PAGE_SIZE)
{
int
Ret
=
(Exception
-
>ContextRecord
-
>Rax);
PVOID NextRip
=
(PVOID)(
*
(ULONG_PTR
*
)Exception
-
>ContextRecord
-
>Rsp);
ZxDebug((__FUNCTION__
"():: (%d)RunFunction(a , b) NextRip=%p\n"
, Ret, NextRip));
/
/
将Main函数改为可执行
VirtualProtect((PVOID)MainFunctionAddress, PAGE_SIZE, PAGE_EXECUTE_READ,&flOldProtect);
/
/
将HeapMemory内存属性改为不可执行。
VirtualProtect(HeapMemory, PAGE_SIZE, PAGE_READWRITE,&flOldProtect);
}
}
return
EXCEPTION_CONTINUE_EXECUTION;
}
PVOID HeapMemory
=
NULL;
PVOID MainFunctionAddress
=
NULL;
int
RunFunction(
int
*
a,
int
*
b){
*
a
=
*
a
+
1
;
*
b
=
*
b
+
1
;
return
*
a
+
*
b;
}
VOID main(
int
argc, char
*
argv[])
{
MainFunctionAddress
=
GetDbgFunctionPointerAddress(main);
/
/
申请内存属性为读写权限
HeapMemory
=
VirtualAlloc(NULL, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
int
a
=
1
, b
=
11
;
LPVOID Address
=
(LPVOID)RunFunction;
Address
=
GetDbgFunctionPointerAddress(RunFunction);
/
/
将RunFunction的内容复制到HeapMemory。
RtlCopyMemory(HeapMemory, Address,
0x3b
);
ZxDebug((
"HeapMemory = %p MainFunctionAddress=%p \n"
, HeapMemory, MainFunctionAddress));
__try
{
/
/
执行HeapMemory,asmcall jmp r8
/
/
内存属性为读写,执行函数会产生异常
for
(
int
i
=
0
; i <
3
; i
+
+
)
asmcall((PVOID)&a, (PVOID)&b, HeapMemory);
}__except(FilterException(GetExceptionCode(), GetExceptionInformation()))
{
ZxDebug((__FUNCTION__
"():: EXCEPTION_EXECUTE_HANDLE\n"
));
}
ZxDebug((__FUNCTION__
"():: a = %d b = %d\n"
, a, b));
}
int
FilterException(ULONG ExceptionCode, _EXCEPTION_POINTERS
*
Exception)
{
MEMORY_BASIC_INFORMATION Mbi
=
{};
SIZE_T Size
=
VirtualQuery(Exception
-
>ExceptionRecord
-
>ExceptionAddress, &Mbi, sizeof(MEMORY_BASIC_INFORMATION));
DWORD flOldProtect
=
0
;
ZxDebug((__FUNCTION__
"():: ExceptionAddress:%p \n"
, Exception
-
>ExceptionRecord
-
>ExceptionAddress));
if
(Exception
-
>ExceptionRecord
-
>ExceptionAddress
=
=
HeapMemory)
{
assert
(ExceptionCode
=
=
STATUS_ACCESS_VIOLATION && Mbi.Protect
=
=
PAGE_READWRITE);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 1天前
被NoHeart编辑
,原因: