Alter.Org.UA
 << Back Home EN en   Donate Donate

Implementation of GetProcAddress
for Windows NT4/2000/XP/2003 kernel mode

Так надоело уже отвечать на вопросы вида "Как из драйвера динамически получить адрес экспортируемой ф-ции из ntdll.dll по имени этой самой ф-ции ?". Вот, граждане, держите исходники аналогов Win32'шных GetModuleHandle() и GetProcAddress() для режима ядра. В принципе, этот код должен работать не только kernel-mode, но и в user-mode при условии использования ntdll.dll.

Основное применение этих ф-ций - написание драйверов, работающих под разными версиями Windows, и имеющих общий .SYS. В сочетании с ф-цией PsGetVersion() можно творить чудеса.


KernelGetModuleBase

PVOID
KernelGetModuleBase(
    PCHAR  pModuleName
    )
{
    PVOID pModuleBase = NULL;
    PULONG pSystemInfoBuffer = NULL;

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

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

        if (!SystemInfoBufferSize)
            return NULL;

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

        if (!pSystemInfoBuffer)
            return NULL;

        memset(pSystemInfoBuffer, 0, SystemInfoBufferSize*2);

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

        if (NT_SUCCESS(status))
        {
            PSYSTEM_MODULE_ENTRY pSysModuleEntry =((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Module;
            ULONG i;
            
            for (i = 0; i <((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Count; i++)
            {
                if (_stricmp(pSysModuleEntry[i].ModuleName + pSysModuleEntry[i].ModuleNameOffset, pModuleName) == 0)
                {
                    pModuleBase = pSysModuleEntry[i].ModuleBaseAddress;
                    break;
                }
            }
        }

    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        pModuleBase = NULL;
    }
    if(pSystemInfoBuffer) {
        ExFreePool(pSystemInfoBuffer);
    }

    return pModuleBase;
} // end KernelGetModuleBase()

KernelGetProcAddress

PVOID
KernelGetProcAddress(
    PVOID ModuleBase,
    PCHAR pFunctionName
    )
{
    PVOID pFunctionAddress = NULL;
    
    __try
    {
        PIMAGE_DOS_HEADER dos =(PIMAGE_DOS_HEADER) ModuleBase;
        PIMAGE_NT_HEADERS nt  =(PIMAGE_NT_HEADERS)((ULONG) ModuleBase + dos->e_lfanew);

        PIMAGE_DATA_DIRECTORY expdir =(PIMAGE_DATA_DIRECTORY) nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;
        ULONG                 size = expdir->Size;
        ULONG                 addr = expdir->VirtualAddress;

        PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) ModuleBase + addr);

        PULONG functions =(PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
        PSHORT ordinals  =(PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
        PULONG names     =(PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
        ULONG  max_name  =exports->NumberOfNames;
        ULONG  max_func  =exports->NumberOfFunctions;

        ULONG i;

        for (i = 0; i < exports->AddressOfNames; i++)
        {
            ULONG ord = ordinals[i];
            if(i >= max_name || ord >= max_func) {
                return NULL;
            }
            if (functions[ord] < addr || functions[ord] >= addr + size)
            {
                if (strcmp((PCHAR) ModuleBase + names[i], pFunctionName)  == 0)
                {
                    pFunctionAddress =(PVOID)((PCHAR) ModuleBase + functions[ord]);
                    break;
                }
            }
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        pFunctionAddress = NULL;
    }

    return pFunctionAddress;
} // end KernelGetProcAddress()
<< Back Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2024