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);
}