15,471
社区成员
发帖
与我相关
我的任务
分享
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION* prev;
DWORD handler;
};
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION* prev;
DWORD handler;
};
EXCEPTION_DISPOSITION myHandler(
_EXCEPTION_RECORD *ExcRecord,
void * EstablisherFrame,
_CONTEXT *ContextRecord,
void * DispatcherContext)
{
cout << "Just a TEST. exiting..." << endl;
exit(0);
return ExceptionContinueExecution; //不会运行到这
}
//initialize EXCEPTION_REGISTRATION structure
EXCEPTION_REGISTRATION reg, *preg = ®
reg.handler = (DWORD)myHandler;
//get the current head of the exception handling chain
DWORD prev;
_asm
{
mov EAX, FS:[0]
mov prev, EAX
}
reg.prev = (EXCEPTION_REGISTRATION*) prev;
//register it!
_asm
{
mov EAX, preg
mov FS:[0], EAX
}
//generate the exception
//install_my_handler.cpp
#include <windows.h>
#include "install_my_handler.h"
//C++默认的异常处理程序
extern "C"
EXCEPTION_DISPOSITION __CxxFrameHandler(
struct _EXCEPTION_RECORD* ExceptionRecord,
void* EstablisherFrame,
struct _CONTEXT* ContextRecord,
void* DispatcherContext
);
namespace
{
char cpp_handler_instructions[5];
bool saved_handler_instructions = false;
}
namespace my_handler
{
//我的异常处理程序 EXCEPTION_DISPOSITION
my_exc_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext
) throw();
#pragma pack(push, 1)
struct jmp_instr
{
unsigned char jmp;
DWORD offset;
};
#pragma pack(pop)
bool WriteMemory(void* loc, void* buffer, int size)
{
HANDLE hProcess = GetCurrentProcess();
//把包含内存范围[loc,loc+size]的页面的保护方式改成可读写
DWORD old_protection;
BOOL ret = VirtualProtectEx(hProcess, loc, size, PAGE_READWRITE, &old_protection);
if(ret == FALSE)
return false;
ret = WriteProcessMemory(hProcess, loc, buffer, size, NULL);
//恢复原来的保护方式
DWORD o2;
VirtualProtectEx(hProcess, loc, size, old_protection, &o2);
return (ret == TRUE);
}
bool ReadMemory(void* loc, void* buffer, DWORD size)
{
HANDLE hProcess = GetCurrentProcess();
DWORD bytes_read = 0;
BOOL ret = ReadProcessMemory(hProcess, loc, buffer, size, &bytes_read);
return (ret == TRUE && bytes_read == size);
}
bool install_my_handler()
{
void* my_hdlr = my_exc_handler; void* cpp_hdlr = __CxxFrameHandler;
jmp_instr jmp_my_hdlr;
jmp_my_hdlr.jmp = 0xE9;
//从__CxxFrameHandler+5开始计算偏移,因为jmp指令长5字节
jmp_my_hdlr.offset = reinterpret_cast(my_hdlr) - (reinterpret_cast(cpp_hdlr) + 5);
if(!saved_handler_instructions)
{
if(!ReadMemory(cpp_hdlr, cpp_handler_instructions, sizeof(cpp_handler_instructions)))
return false;
saved_handler_instructions = true;
}
return WriteMemory(cpp_hdlr, &jmp_my_hdlr, sizeof(jmp_my_hdlr));
}
bool restore_cpp_handler()
{
if(!saved_handler_instructions)
return false;
else
{
void* loc = __CxxFrameHandler;
return WriteMemory(loc, cpp_handler_instructions, sizeof(cpp_handler_instructions));
}
}
}