/*
调用示例:
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;
}