Отслеживание стека пользовательского режима потока во время функции обратного вызова минифильтра

Я пытаюсь отследить стек пользовательского режима потока во время функции обратного вызова минифильтра.
Предполагая, что я нахожусь в том же контексте, что и вызывающий поток, получаю адрес стека потока из его TEB/TIB и обрабатываю адреса на этот стек должен позволить мне отследить его стек.

Поскольку адреса, которые я получаю, не являются ожидаемыми модулями пользовательского режима, которые вызывают системный вызов, должно быть что-то не так, что я делаю.

Я буду рад, если вы укажете мне правильное направление.

Заранее спасибо.


Ниже приведен код, считывающий содержимое стека:

    pTEB = (PVOID *)((char *)pThread + 0x20);

    // Read TIB
    pTib = (NT_TIB*)pTEB;
    stackBottom = (PVOID*)pTib->StackLimit;
    stackTop = (PVOID*)pTib->StackBase;

    LogDbgView(("stackBottom=%p,  stackTop=%p",stackBottom, stackTop));

    if (!MyReadMemory(IoGetCurrentProcess(), stackBottom, buf, stackTop-stackBottom))
    {
        LogDbgView(("Read Memory = %x",buf));
        LogDbgView(("Read Memory = %x",buf+8));
        LogDbgView(("Read Memory = %x",buf+16));
        LogDbgView(("Read Memory = %x",buf+24));
    }

Ниже приведены функции, которые получают имена и адреса модулей:

    PVOID LoadModulesInformation()
    {
        PVOID pSystemInfoBuffer = NULL;

     __try
        {
            NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
            ULONG    SystemInfoBufferSize = 0;

            status = ZwQuerySystemInformation(SystemModuleInformation,
                &SystemInfoBufferSize,
                0,
                &SystemInfoBufferSize);

            if (!SystemInfoBufferSize)
                return NULL;

            pSystemInfoBuffer = (PVOID)ExAllocatePool(NonPagedPool, SystemInfoBufferSize*2);

            if (!pSystemInfoBuffer)
                return NULL;

            memset(pSystemInfoBuffer, 0, SystemInfoBufferSize*2);

            status = ZwQuerySystemInformation(SystemModuleInformation,
                pSystemInfoBuffer,
                SystemInfoBufferSize*2,
                &SystemInfoBufferSize);

            if (NT_SUCCESS(status))
            {
                return pSystemInfoBuffer;
            }

        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }

        return NULL;
    }


    PUNICODE_STRING findModuleName(PVOID addr, PVOID pSystemInfoBuffer, ULONG Tag FILE_AND_LINE_ARGS)
    {
        PVOID pModuleBase = NULL;
        PCHAR pCharRet=NULL;
        PUNICODE_STRING pus = NULL;

        __try
        {
            if (pSystemInfoBuffer != NULL && MmIsAddressValid(addr))
            {
                PSYSTEM_MODULE_ENTRY pSysModuleEntry = ((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Module;
                ULONG i;

                for (i = 0; i <((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Count; i++)
                {
                    if ((pSysModuleEntry[i].Base <= addr) && (pSysModuleEntry[i].Size < ((ULONG)addr - (ULONG)pSysModuleEntry[i].Base)))
                    {
                        pCharRet = pSysModuleEntry[i].ImageName+pSysModuleEntry[i].PathLength;
                        break;
                    }
                }
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            pCharRet = NULL;
        }

        if (pCharRet)
        {
            pus = UtlpCharToUnicode(pCharRet, TRUE, TRUE, Tag FILE_AND_LINE_PARAMS);
        }
        else
        {
            pus = UtlpCharToUnicode("UNKNOWN", TRUE, TRUE, Tag FILE_AND_LINE_PARAMS);
        }

        return pus;
    }

person user3483098    schedule 31.03.2014    source источник


Ответы (1)


pTEB = (PVOID *)((char *)pThread + 0x20);

Не делайте этого вообще, даже в PoC. Планировка структуры время от времени меняется. Вместо этого вы можете использовать PsGetProcessPeb (см. здесь, как https://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c)

LogDbgView(("Чтение памяти = %x",buf));

Вы не читаете память по адресу buf, вместо этого вы читаете значение buf. В C вы должны разыменовать указатель, чтобы читать оттуда память. Как это

LogDbgView(("Чтение памяти = %x",(PVOID)*buf));

LogDbgView(("Чтение памяти = %x",buf+8));

Чтобы иметь возможность компилировать для x86, а также для x64, вы должны избегать таких вещей. Вместо этого используйте sizeof(PVOID):

LogDbgView(("Чтение памяти = %x",(PVOID)*(buf+sizeof(PVOID))));

person Evgenii Gostiukhin    schedule 01.04.2014