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

 

 

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