Hook ZwQueryInformationProcess 函數使得異常處理可以在shellcode上執行

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章