32位系统上当你的shellcode有使用
__try
__except
进行处理时,系统最终会调用RtlIsValidHandler来判断异常处理函数是否有效,如果你希望处理异常
应该是Hook RtlIsValidHandler,可是微软没有导出这个接口
于是我们逆向看看RtlIsValidHandler
发现它会判断ZwQueryInformationProcess的返回值,这里就是ExecuteFlag,这个值不好进行设置,内核会根据flag=8将其锁死,所以我们hook ZwQueryInformationProcess即可
我们再看调用IsValidHandler的RtlDispatchException函数
也判断了一个标记
那么最终我们应该增加0x40+0x30 也就是0x70的标记即可
//根据逆向我们似乎发现了一个办法,也就是Process的MemoryFlag,可用ZwQueryInformationProcess来进行查询
//0x22 flag,返回的一个字节就是MemoryFlag
//#define MEM_EXECUTE_OPTION_DISABLE 0x1
//#define MEM_EXECUTE_OPTION_ENABLE 0x2
//#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION 0x4
//#define MEM_EXECUTE_OPTION_PERMANENT 0x8
//#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE 0x10
//#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE 0x20
//#define MEM_EXECUTE_OPTION_VALID_FLAGS 0x3F
//当其具有MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE | MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE时就可以了
//或者是0x70
下面是hook函数的代码
NTSTATUS __stdcall MyZwQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
)
{
g_bInMyZwQueryInformationProcess ++;
if (ProcessInformationClass == ProcessExecuteFlags && ProcessHandle == GetCurrentProcess() && ProcessInformationLength == sizeof(ULONG))
{
NTSTATUS n2 = raw_ZwQueryInformationProcess(ProcessHandle,
ProcessInformationClass,
ProcessInformation,
ProcessInformationLength,
ReturnLength);
if (g_bInMyZwQueryInformationProcess == 1)
{
//Debug_View(L"n2=%x, retlen=%d", n2, (*ReturnLength));
}
if (n2 == 0 && ProcessInformation)
{
if (g_bInMyZwQueryInformationProcess == 1)
{
//Debug_View(L"Old Execute Flag: %x", (*((ULONG*)ProcessInformation)));
}
(*((ULONG*)ProcessInformation)) |=0x70;
if (g_bInMyZwQueryInformationProcess == 1)
{
//Debug_View(L"New Execute Flag: %x", (*((ULONG*)ProcessInformation)));
}
}
g_bInMyZwQueryInformationProcess--;
return n2;
}
g_bInMyZwQueryInformationProcess--;
return raw_ZwQueryInformationProcess(ProcessHandle,
ProcessInformationClass,
ProcessInformation,
ProcessInformationLength,
ReturnLength);
}