一份兼容32位和64位的MmGetSystemRoutineAddressEx实现

委员长 · · Windows程序设计
1

本文共计1677个字,预计阅读时长6.7分钟。

获得任意模块任意导出函数的地址,不再受限于MmGetSystemRoutineAddress的鸡肋功能。代码从WRK里摘出。
PVOID MiFindExportedRoutine2
(
    IN PVOID DllBase,
        PIMAGE_EXPORT_DIRECTORY ExportDirectory,
        ULONG ExportSize,
    BOOL ByName,
    IN char *RoutineName,
    DWORD Ordinal
)
{
        USHORT OrdinalNumber;
        PULONG NameTableBase;
        PUSHORT NameOrdinalTableBase;
        PULONG AddressTableBase;
        PULONG Addr;
        LONG High;
        LONG Low;
        LONG Middle;
        LONG Result;
        PVOID FunctionAddress;
        if (ExportDirectory == NULL || ExportSize == 0)
        {
                return NULL;
        }
        NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
        NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
        AddressTableBase=(PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
        if (!ByName)
        {
                return (PVOID)AddressTableBase[Ordinal];
        }
        Low = 0;
        Middle = 0;
        High = ExportDirectory->NumberOfNames - 1;
        while (High >= Low)
        {
                Middle = (Low + High) >>1;
                Result = strcmp (RoutineName,
                                 (PCHAR)DllBase + NameTableBase[Middle]);
                if (Result <0)
                {
                        High = Middle - 1;
                }
                else if (Result >0)
                {
                        Low = Middle + 1;
                }
                else
                {
                        break;
                }
        }
        if (High (ULONG_PTR)ExportDirectory &&
                (ULONG_PTR)FunctionAddress <((ULONG_PTR)ExportDirectory + ExportSize))
        {
                FunctionAddress = NULL;
        }
        return FunctionAddress;
}

PVOID NativeGetProcAddress64(SIZE_T uModBase, CHAR *cSearchFnName)
{
        IMAGE_DOS_HEADER *doshdr;
        IMAGE_OPTIONAL_HEADER64 *opthdr;
        IMAGE_EXPORT_DIRECTORY *pExportTable;
        ULONG size;
        SIZE_T uFnAddr=0;
        //
        doshdr = (IMAGE_DOS_HEADER ?uModBase;
        if (NULL == doshdr)
        {
                goto __exit;
        }
        opthdr = (IMAGE_OPTIONAL_HEADER64 ?(uModBase + doshdr->e_lfanew + sizeof(ULONG)+sizeof(IMAGE_FILE_HEADER));
        if (NULL == opthdr)
        {
                goto __exit;
        }
        pExportTable = (IMAGE_EXPORT_DIRECTORY ?(uModBase + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        if (NULL == pExportTable)
        {
                goto __exit;
        }
        size = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
        uFnAddr = (SIZE_T)MiFindExportedRoutine2((PVOID)uModBase,pExportTable,size,TRUE,cSearchFnName,0);
__exit:
        return (PVOID)uFnAddr;
}

PVOID NativeGetProcAddress32(SIZE_T uModBase, CHAR *cSearchFnName)
{
        IMAGE_DOS_HEADER *doshdr;
        IMAGE_OPTIONAL_HEADER32 *opthdr;
        IMAGE_EXPORT_DIRECTORY *pExportTable;
        ULONG size;
        SIZE_T uFnAddr=0;
        //
        doshdr = (IMAGE_DOS_HEADER ?uModBase;
        if (NULL == doshdr)
        {
                goto __exit;
        }
        opthdr = (IMAGE_OPTIONAL_HEADER32 ?(uModBase + doshdr->e_lfanew + sizeof(ULONG)+sizeof(IMAGE_FILE_HEADER));
        if (NULL == opthdr)
        {
                goto __exit;
        }
        pExportTable = (IMAGE_EXPORT_DIRECTORY ?(uModBase + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        if (NULL == pExportTable)
        {
                goto __exit;
        }
        size = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
        uFnAddr = (SIZE_T)MiFindExportedRoutine2((PVOID)uModBase,pExportTable,size,TRUE,cSearchFnName,0);
__exit:
        return (PVOID)uFnAddr;
}
最后于 2023-2-26 被admin编辑 ,原因:

最新回复 ( 1 )
全部楼主
  • bbc @Ta
    2
     Error LNK2019: 无法解析的外部符号 MmGetSystemRoutineAddressEx。MmGetSystemRoutineAddressEx这个函数怎么链接编译啊