查找内核模块的导出函数

/*

调用示例:

GetModExportFunc(L"ntdll.dll","NtCreateFile");

GetModExportFunc(L"ntkrnlpa.exe","KeServiceDescriptorTable");

*/

NTSTATUS GetModExportFunc(IN WCHAR ModuleName[],IN CHAR FuncName[])

{
    PIMAGE_DOS_HEADER       DosHdr=NULL;
    PIMAGE_NT_HEADERS       NtHdrs=NULL;   
    PIMAGE_EXPORT_DIRECTORY ExpDir=NULL;
    PULONG          AddressOfNames=NULL;
    PULONG      AddressOfFunctions=NULL;
    PUSHORT  AddressOfNameOrdinals=NULL;
    ULONG            NumberOfNames=0;  
    ULONG                  Address=0;
    PVOID               ModuleBase=NULL;
    LONG            high=0,low=0,mid=0,ret=0;
    NTSTATUS            Status=STATUS_UNSUCCESSFUL;
    HANDLE              SectionHandle=NULL;
    HANDLE              FileHandle=NULL;
    OBJECT_ATTRIBUTES   ObjectAttributes={0};
    IO_STATUS_BLOCK     IoStatusBlock={0};
    UNICODE_STRING      FileName={0};
    PVOID               BaseAddress=NULL;
    SIZE_T              ViewSize=0;
    WCHAR                ModulePath[260]=L"\\??\\C:\\windows\\system32\\";
   
    while(ModuleName && FuncName)
    {
        wcscat(ModulePath,ModuleName);
        RtlInitUnicodeString(&FileName,ModulePath);  
        InitializeObjectAttributes(&ObjectAttributes,&FileName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
        Status=ZwCreateFile(&FileHandle,GENERIC_ALL,&ObjectAttributes,&IoStatusBlock,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN,FILE_NON_DIRECTORY_FILE,NULL,0);
        if (!NT_SUCCESS(Status))
        {
            Status=ZwOpenFile(&FileHandle,GENERIC_READ,&ObjectAttributes,&IoStatusBlock,FILE_SHARE_READ,FILE_NON_DIRECTORY_FILE);
        }       
        if (!NT_SUCCESS(Status))
        {
            DbgPrint("ZwOpenFile error: %08X\n",Status);
            break;
        }

        Status=ZwCreateSection(&SectionHandle,SECTION_ALL_ACCESS,NULL,0,PAGE_READWRITE,SEC_IMAGE,FileHandle);
        if (!NT_SUCCESS(Status))
        {
            DbgPrint("ZwCreateSection error: %08X\n",Status);
            break;
        }

        Status=ZwMapViewOfSection(SectionHandle,ZwCurrentProcess(),&BaseAddress,0,PAGE_SIZE,NULL,&ViewSize,ViewShare,MEM_TOP_DOWN,PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            DbgPrint("ZwMapViewOfSection error: %08X\n",Status);
            break;
        }
       
        if ( (DosHdr=(PIMAGE_DOS_HEADER)BaseAddress, DosHdr->e_magic==IMAGE_DOS_SIGNATURE) &&
            (NtHdrs=(PIMAGE_NT_HEADERS)((ULONG)DosHdr+DosHdr->e_lfanew), NtHdrs->Signature==IMAGE_NT_SIGNATURE))
        {
            ModuleBase=BaseAddress;

            ExpDir=(PIMAGE_EXPORT_DIRECTORY)((ULONG)DosHdr+NtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
            AddressOfNames=(PULONG)((ULONG)ModuleBase+ExpDir->AddressOfNames);
            AddressOfFunctions=(PULONG)((ULONG)ModuleBase+ExpDir->AddressOfFunctions);
            AddressOfNameOrdinals=(PUSHORT)((ULONG)ModuleBase+ExpDir->AddressOfNameOrdinals);
            NumberOfNames=ExpDir->NumberOfNames;       

            high=ExpDir->NumberOfNames-1;
            low=0;
            while(low<=high)//二分查找,快速定位
            {
                mid=(high+low)/2;

                ret=strcmp((PCHAR)ModuleBase+AddressOfNames[mid],FuncName);//不能用_stricmp
                if (ret==0)
                {
                    Address=AddressOfFunctions[AddressOfNameOrdinals[mid]];
                    KdPrint(("%04d/%04d:<0x%08X>0x%08X,%s!%s\n",
                        mid,
                        ExpDir->NumberOfNames,
                        Address,
                        (PCHAR)ModuleBase+Address,
                        (PCHAR)ModuleBase+ExpDir->Name,
                        (PCHAR)ModuleBase+AddressOfNames[mid]));

                    break;
                }
                else if(ret>0)
                {
                    high=mid-1;
                }
                else
                {
                    low=mid+1;
                }
            }
        }

        break;
    }
   
    if (BaseAddress)
    {
        ZwUnmapViewOfSection(ZwCurrentProcess(),BaseAddress);
    }
    if (SectionHandle)
    {
        ZwClose(SectionHandle);
    }

    if(FileHandle)
    {
        ZwClose(FileHandle);
    }

    return Status;
}

你可能感兴趣的:(导出函数)