找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 836|回复: 1

FuckHsProtect

[复制链接]

1793

主题

457

回帖

0

积分

管理员

积分
0
发表于 2013-8-28 15:50:26 | 显示全部楼层 |阅读模式
//#include "stdafx.h"
#include "E.h"

NTSTATUS
NTAPI
RtlImageNtHeaderEx(
    ULONG Flags,
   &#160VOID Base,
    ULONG64 Size,
    OUT PIMAGE_NT_HEADERS * OutHeaders
    )

/*++

Routine Description:

    This function returns the address of the NT Header.

    This function is a bit complicated.
    It is this way because RtlImageNtHeader that it replaces was hard to understand,
      and this function retains compatibility with RtlImageNtHeader.

    RtlImageNtHeader was #ifed such as to act different in each of the three
        boot loader, kernel, usermode flavors.

    boot loader -- no exception handling
    usermode -- limit msdos header to 256meg, catch any exception accessing the msdos-header
                or the pe header
    kernel -- don't cross user/kernel boundary, don't catch the exceptions,
                no 256meg limit

Arguments:

    Flags - RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK -- don't be so picky
                about the image, for compatibility with RtlImageNtHeader
    Base - Supplies the base of the image.
    Size - The size of the view, usually larger than the size of the file on disk.
            This is available from NtMapViewOfSection but not from MapViewOfFile.
    OutHeaders -

Return Value:

    STATUS_SUCCESS -- everything ok
    STATUS_INVALID_IMAGE_FORMAT -- bad filesize or signature value
    STATUS_INVALID_PARAMETER -- bad parameters

--*/

{
   &#160IMAGE_NT_HEADERS NtHeaders = 0;
    ULONG e_lfanew = 0;
    BOOLEAN RangeCheck = 0;
    NTSTATUS Status = 0;
    const ULONG ValidFlags =
        RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK;

    if (OutHeaders != NULL) {
        *OutHeaders = NULL;
    }
    if (OutHeaders == NULL) {
        Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }
    if ((Flags & ~ValidFlags) != 0) {
        Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }
    if (Base == NULL || Base == (PVOID)(LONG_PTR)-1) {
        Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    RangeCheck = ((Flags & RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK) == 0);
    if (RangeCheck) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (Size < sizeof(IMAGE_DOS_HEADER)) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;goto Exit;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Exception handling is not available in the boot loader, and exceptions
&#160;&#160;&#160;&#160;// were not historically caught here in kernel mode. Drivers are considered
&#160;&#160;&#160;&#160;// trusted, so we can&#39;t get an exception here due to a bad file, but we
&#160;&#160;&#160;&#160;// could take an inpage error.
&#160;&#160;&#160;&#160;//
#define EXIT goto Exit
&#160;&#160;&#160;&#160;if (((PIMAGE_DOS_HEADER)Base)->e_magic != IMAGE_DOS_SIGNATURE) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EXIT;
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;e_lfanew = ((PIMAGE_DOS_HEADER)Base)->e_lfanew;
&#160;&#160;&#160;&#160;if (RangeCheck) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (e_lfanew >= Size
#define SIZEOF_PE_SIGNATURE 4
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;|| e_lfanew >= (MAXULONG - SIZEOF_PE_SIGNATURE - sizeof(IMAGE_FILE_HEADER))
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;|| (e_lfanew + SIZEOF_PE_SIGNATURE + sizeof(IMAGE_FILE_HEADER)) >= Size
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EXIT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + e_lfanew);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// In kernelmode, do not cross from usermode address to kernelmode address.
&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;if (Base < MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if ((PVOID)NtHeaders >= MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EXIT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// Note that this check is slightly overeager since IMAGE_NT_HEADERS has
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// a builtin array of data_directories that may be larger than the image
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// actually has. A better check would be to add FileHeader.SizeOfOptionalHeader,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// after ensuring that the FileHeader does not cross the u/k boundary.
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if ((PVOID)((PCHAR)NtHeaders + sizeof (IMAGE_NT_HEADERS)) >= MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EXIT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;if (NtHeaders->Signature != IMAGE_NT_SIGNATURE) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Status = STATUS_INVALID_IMAGE_FORMAT;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EXIT;
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;Status = STATUS_SUCCESS;

Exit:
&#160;&#160;&#160;&#160;if (NT_SUCCESS(Status)) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;*OutHeaders = NtHeaders;
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;return Status;
}

PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PVOID Base
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )
{
&#160;&#160;&#160;&#160IMAGE_NT_HEADERS NtHeaders = NULL;
&#160;&#160;&#160;&#160;(VOID)RtlImageNtHeaderEx(RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK, Base, 0, &NtHeaders);
&#160;&#160;&#160;&#160;return NtHeaders;
}

PIMAGE_SECTION_HEADER
RtlSectionTableFromVirtualAddress (
&#160;&#160;&#160;&#160;IN PIMAGE_NT_HEADERS NtHeaders,
&#160;&#160;&#160;&#160;IN PVOID Base,
&#160;&#160;&#160;&#160;IN ULONG Address
&#160;&#160;&#160;&#160;)

/*++

Routine Description:

&#160;&#160;&#160;&#160;This function locates a VirtualAddress within the image header
&#160;&#160;&#160;&#160;of a file that is mapped as a file and returns a pointer to the
&#160;&#160;&#160;&#160;section table entry for that virtual address

Arguments:

&#160;&#160;&#160;&#160;NtHeaders - Supplies the pointer to the image or data file.

&#160;&#160;&#160;&#160;Base - Supplies the base of the image or data file.

&#160;&#160;&#160;&#160;Address - Supplies the virtual address to locate.

Return Value:

&#160;&#160;&#160;&#160;NULL - The file does not contain data for the specified directory entry.

&#160;&#160;&#160;&#160;NON-NULL - Returns the pointer of the section entry containing the data.

--*/

{
&#160;&#160;&#160;&#160;ULONG i;
&#160;&#160;&#160;&#160IMAGE_SECTION_HEADER NtSection;

&#160;&#160;&#160;&#160;NtSection = IMAGE_FIRST_SECTION( NtHeaders );
&#160;&#160;&#160;&#160;for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if ((ULONG)Address >= NtSection->VirtualAddress &&
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NtSection;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;++NtSection;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;return NULL;
}
PVOID
RtlAddressInSectionTable (
&#160;&#160;&#160;&#160;IN PIMAGE_NT_HEADERS NtHeaders,
&#160;&#160;&#160;&#160;IN PVOID Base,
&#160;&#160;&#160;&#160;IN ULONG Address
&#160;&#160;&#160;&#160;)

/*++

Routine Description:

&#160;&#160;&#160;&#160;This function locates a VirtualAddress within the image header
&#160;&#160;&#160;&#160;of a file that is mapped as a file and returns the seek address
&#160;&#160;&#160;&#160;of the data the Directory describes.

Arguments:

&#160;&#160;&#160;&#160;NtHeaders - Supplies the pointer to the image or data file.

&#160;&#160;&#160;&#160;Base - Supplies the base of the image or data file.

&#160;&#160;&#160;&#160;Address - Supplies the virtual address to locate.

Return Value:

&#160;&#160;&#160;&#160;NULL - The file does not contain data for the specified directory entry.

&#160;&#160;&#160;&#160;NON-NULL - Returns the address of the raw data the directory describes.

--*/

{
&#160;&#160;&#160;&#160IMAGE_SECTION_HEADER NtSection;

&#160;&#160;&#160;&#160;NtSection = RtlSectionTableFromVirtualAddress( NtHeaders,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Base,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Address
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );
&#160;&#160;&#160;&#160;if (NtSection != NULL) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( ((PCHAR)Base + ((ULONG_PTR)Address - NtSection->VirtualAddress) + NtSection->ointerToRawData) );
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;else {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
}

PVOID
RtlpImageDirectoryEntryToData32 (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN PVOID Base,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN BOOLEAN MappedAsImage,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN USHORT DirectoryEntry,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OUT PULONG Size,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PIMAGE_NT_HEADERS32 NtHeaders
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )
{
&#160;&#160;&#160;&#160;ULONG DirectoryAddress;

&#160;&#160;&#160;&#160;if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;if (Base < MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;*Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
&#160;&#160;&#160;&#160;if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( (PVOID)((PCHAR)Base + DirectoryAddress) );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;return( RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
}


PVOID
RtlpImageDirectoryEntryToData64 (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN PVOID Base,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN BOOLEAN MappedAsImage,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN USHORT DirectoryEntry,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OUT PULONG Size,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PIMAGE_NT_HEADERS64 NtHeaders
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )
{
&#160;&#160;&#160;&#160;ULONG DirectoryAddress;

&#160;&#160;&#160;&#160;if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;if (Base < MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( NULL );
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;*Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
&#160;&#160;&#160;&#160;if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return( (PVOID)((PCHAR)Base + DirectoryAddress) );
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;return( RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
}

PVOID
RtlImageDirectoryEntryToData (
&#160;&#160;&#160;&#160;IN PVOID Base,
&#160;&#160;&#160;&#160;IN BOOLEAN MappedAsImage,
&#160;&#160;&#160;&#160;IN USHORT DirectoryEntry,
&#160;&#160;&#160;&#160;OUT PULONG Size
&#160;&#160;&#160;&#160;)

/*++

Routine Description:

&#160;&#160;&#160;&#160;This function locates a Directory Entry within the image header
&#160;&#160;&#160;&#160;and returns either the virtual address or seek address of the
&#160;&#160;&#160;&#160;data the Directory describes.

Arguments:

&#160;&#160;&#160;&#160;Base - Supplies the base of the image or data file.

&#160;&#160;&#160;&#160;MappedAsImage - FALSE if the file is mapped as a data file.
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;- TRUE if the file is mapped as an image.

&#160;&#160;&#160;&#160;DirectoryEntry - Supplies the directory entry to locate.

&#160;&#160;&#160;&#160;Size - Return the size of the directory.

Return Value:

&#160;&#160;&#160;&#160;NULL - The file does not contain data for the specified directory entry.

&#160;&#160;&#160;&#160;NON-NULL - Returns the address of the raw data the directory describes.

--*/

{
&#160;&#160;&#160;&#160IMAGE_NT_HEADERS NtHeaders;

&#160;&#160;&#160;&#160;if (LDR_IS_DATAFILE(Base)) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Base = LDR_DATAFILE_TO_VIEW(Base);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;MappedAsImage = FALSE;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;NtHeaders = RtlImageNtHeader(Base);

&#160;&#160;&#160;&#160;if (!NtHeaders)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;

&#160;&#160;&#160;&#160;if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return (RtlpImageDirectoryEntryToData32(Base,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;MappedAsImage,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DirectoryEntry,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Size,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(PIMAGE_NT_HEADERS32)NtHeaders));
&#160;&#160;&#160;&#160;} else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return (RtlpImageDirectoryEntryToData64(Base,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;MappedAsImage,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DirectoryEntry,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Size,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(PIMAGE_NT_HEADERS64)NtHeaders));
&#160;&#160;&#160;&#160;} else {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return (NULL);
&#160;&#160;&#160;&#160;}
}

PVOID
MiFindExportedRoutineByName (
&#160;&#160;&#160;&#160;IN PVOID DllBase,
&#160;&#160;&#160;&#160;IN PANSI_STRING AnsiImageRoutineName
&#160;&#160;&#160;&#160;)

/*++

Routine Description:

&#160;&#160;&#160;&#160;This function searches the argument module looking for the requested
&#160;&#160;&#160;&#160;exported function name.

Arguments:

&#160;&#160;&#160;&#160;DllBase - Supplies the base address of the requested module.

&#160;&#160;&#160;&#160;AnsiImageRoutineName - Supplies the ANSI routine name being searched for.

Return Value:

&#160;&#160;&#160;&#160;The virtual address of the requested routine or NULL if not found.

--*/

{
&#160;&#160;&#160;&#160;USHORT OrdinalNumber;
&#160;&#160;&#160;&#160ULONG NameTableBase;
&#160;&#160;&#160;&#160USHORT NameOrdinalTableBase;
&#160;&#160;&#160;&#160;PULONG Addr;
&#160;&#160;&#160;&#160;LONG High;
&#160;&#160;&#160;&#160;LONG Low;
&#160;&#160;&#160;&#160;LONG Middle;
&#160;&#160;&#160;&#160;LONG Result;
&#160;&#160;&#160;&#160;ULONG ExportSize;
&#160;&#160;&#160;&#160;PVOID FunctionAddress;
&#160;&#160;&#160;&#160;PIMAGE_EXPORT_DIRECTORY ExportDirectory;

&#160;&#160;&#160;&#160;PAGED_CODE();

&#160;&#160;&#160;&#160;ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;TRUE,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IMAGE_DIRECTORY_ENTRY_EXPORT,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&ExportSize);

&#160;&#160;&#160;&#160;if (ExportDirectory == NULL) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of RVA-based ansi export strings.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of USHORT ordinal numbers.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Lookup the desired name in the name table using a binary search.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Low = 0;
&#160;&#160;&#160;&#160;Middle = 0;
&#160;&#160;&#160;&#160;High = ExportDirectory->NumberOfNames - 1;

&#160;&#160;&#160;&#160;while (High >= Low) {

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// Compute the next probe index and compare the import name
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// with the export name entry.
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Middle = (Low + High) >> 1;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Result = strcmp (AnsiImageRoutineName->Buffer,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (PCHAR)DllBase + NameTableBase[Middle]);

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (Result < 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;High = Middle - 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else if (Result > 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Low = Middle + 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the high index is less than the low index, then a matching
&#160;&#160;&#160;&#160;// table entry was not found. Otherwise, get the ordinal number
&#160;&#160;&#160;&#160;// from the ordinal table.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if (High < Low) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;OrdinalNumber = NameOrdinalTableBase[Middle];

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the OrdinalNumber is not within the Export Address Table,
&#160;&#160;&#160;&#160;// then this image does not implement the function.&#160;&#160;Return not found.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Index into the array of RVA export addresses by ordinal number.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);

&#160;&#160;&#160;&#160;FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Forwarders are not used by the kernel and HAL to each other.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));

&#160;&#160;&#160;&#160;return FunctionAddress;
}

PVOID
MiFindExportedRoutineByNameByRaw (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN PVOID DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IN PANSI_STRING AnsiImageRoutineName
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )
{
&#160;&#160;&#160;&#160;USHORT OrdinalNumber;
&#160;&#160;&#160;&#160;PULONG NameTableBase;
&#160;&#160;&#160;&#160;PUSHORT NameOrdinalTableBase;
&#160;&#160;&#160;&#160;PULONG Addr;
&#160;&#160;&#160;&#160;LONG High;
&#160;&#160;&#160;&#160;LONG Low;
&#160;&#160;&#160;&#160;LONG Middle;
&#160;&#160;&#160;&#160;LONG Result;
&#160;&#160;&#160;&#160;ULONG ExportSize;
&#160;&#160;&#160;&#160;PVOID FunctionAddress;
&#160;&#160;&#160;&#160;PIMAGE_EXPORT_DIRECTORY ExportDirectory;

&#160;&#160;&#160;&#160;PAGED_CODE();

&#160;&#160;&#160;&#160;ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FALSE,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IMAGE_DIRECTORY_ENTRY_EXPORT,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&ExportSize);

&#160;&#160;&#160;&#160;if (ExportDirectory == NULL)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of RVA-based ansi export strings.
&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;

&#160;&#160;&#160;&#160;NameTableBase = (PULONG)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfNames);
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of USHORT ordinal numbers.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;NameOrdinalTableBase = (PUSHORT)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfNameOrdinals);
&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Lookup the desired name in the name table using a binary search.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Low = 0;
&#160;&#160;&#160;&#160;Middle = 0;
&#160;&#160;&#160;&#160;High = ExportDirectory->NumberOfNames - 1;

&#160;&#160;&#160;&#160;while (High >= Low) {

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// Compute the next probe index and compare the import name
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// with the export name entry.
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Middle = (Low + High) >> 1;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// NameTableBase[Middle] rva
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// ULONG uNameRwa =

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Result = strcmp (AnsiImageRoutineName->Buffer,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(PCHAR)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;NameTableBase[Middle]));

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (Result < 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;High = Middle - 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else if (Result > 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Low = Middle + 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the high index is less than the low index, then a matching
&#160;&#160;&#160;&#160;// table entry was not found. Otherwise, get the ordinal number
&#160;&#160;&#160;&#160;// from the ordinal table.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if (High < Low) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;OrdinalNumber = NameOrdinalTableBase[Middle];

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the OrdinalNumber is not within the Export Address Table,
&#160;&#160;&#160;&#160;// then this image does not implement the function.&#160;&#160;Return not found.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Index into the array of RVA export addresses by ordinal number.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Addr = (PULONG)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfFunctions);

&#160;&#160;&#160;&#160;FunctionAddress = RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Addr[OrdinalNumber]);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Forwarders are not used by the kernel and HAL to each other.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));

&#160;&#160;&#160;&#160;return FunctionAddress;
}

void LoadImage(IN PVOID pImageBase, IN PVOID pLoadData)
{
&#160;&#160;&#160;&#160;PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pLoadData;
&#160;&#160;&#160;&#160;PIMAGE_NT_HEADERS pNtHeader = RtlImageNtHeader(pLoadData);
&#160;&#160;&#160;&#160;ULONG uPeHeaderSize = pNtHeader->OptionalHeader.SizeOfHeaders;
&#160;&#160;&#160;&#160;RtlCopyMemory(pImageBase, pLoadData, uPeHeaderSize);

&#160;&#160;&#160;&#160;ULONG uSectionNum = pNtHeader->FileHeader.NumberOfSections;
&#160;&#160;&#160;&#160;ULONG nSectionOffset = pDosHeader->e_lfanew
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ sizeof(pNtHeader->Signature)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ sizeof(IMAGE_FILE_HEADER)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ pNtHeader->FileHeader.SizeOfOptionalHeader;
&#160;&#160;&#160;&#160;PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((ULONG)pLoadData + nSectionOffset);
&#160;&#160;&#160;&#160;for (ULONG i = 0; i < uSectionNum; i++)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;PVOID pSectionInfo = (PVOID)(pSection.PointerToRawData + (ULONG)pLoadData);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;RtlCopyMemory((PVOID)((ULONG)pImageBase + pSection.VirtualAddress),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pSectionInfo,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pSection.SizeOfRawData);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;}
}


PVOID
MiFindExportedRoutineRvaByNameByRaw (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IN PVOID DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IN PANSI_STRING AnsiImageRoutineName
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)
{
&#160;&#160;&#160;&#160;USHORT OrdinalNumber;
&#160;&#160;&#160;&#160;PULONG NameTableBase;
&#160;&#160;&#160;&#160;PUSHORT NameOrdinalTableBase;
&#160;&#160;&#160;&#160;PULONG Addr;
&#160;&#160;&#160;&#160;LONG High;
&#160;&#160;&#160;&#160;LONG Low;
&#160;&#160;&#160;&#160;LONG Middle;
&#160;&#160;&#160;&#160;LONG Result;
&#160;&#160;&#160;&#160;ULONG ExportSize;
&#160;&#160;&#160;&#160;PVOID FunctionAddress;
&#160;&#160;&#160;&#160;PIMAGE_EXPORT_DIRECTORY ExportDirectory;

&#160;&#160;&#160;&#160;PAGED_CODE();

&#160;&#160;&#160;&#160;ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FALSE,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IMAGE_DIRECTORY_ENTRY_EXPORT,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&ExportSize);

&#160;&#160;&#160;&#160;if (ExportDirectory == NULL)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of RVA-based ansi export strings.
&#160;&#160;&#160;&#160;//


&#160;&#160;&#160;&#160;NameTableBase = (PULONG)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfNames);

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Initialize the pointer to the array of USHORT ordinal numbers.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;NameOrdinalTableBase = (PUSHORT)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfNameOrdinals);
&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Lookup the desired name in the name table using a binary search.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Low = 0;
&#160;&#160;&#160;&#160;Middle = 0;
&#160;&#160;&#160;&#160;High = ExportDirectory->NumberOfNames - 1;

&#160;&#160;&#160;&#160;while (High >= Low) {

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// Compute the next probe index and compare the import name
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// with the export name entry.
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Middle = (Low + High) >> 1;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// NameTableBase[Middle] rva
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// ULONG uNameRwa =

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Result = strcmp (AnsiImageRoutineName->Buffer,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(PCHAR)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;NameTableBase[Middle]));

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (Result < 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;High = Middle - 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else if (Result > 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Low = Middle + 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the high index is less than the low index, then a matching
&#160;&#160;&#160;&#160;// table entry was not found. Otherwise, get the ordinal number
&#160;&#160;&#160;&#160;// from the ordinal table.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if (High < Low) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;OrdinalNumber = NameOrdinalTableBase[Middle];

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// If the OrdinalNumber is not within the Export Address Table,
&#160;&#160;&#160;&#160;// then this image does not implement the function.&#160;&#160;Return not found.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return NULL;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Index into the array of RVA export addresses by ordinal number.
&#160;&#160;&#160;&#160;//

&#160;&#160;&#160;&#160;Addr = (PULONG)RtlAddressInSectionTable((PIMAGE_NT_HEADERS)RtlImageNtHeader(DllBase),
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;DllBase,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ExportDirectory->AddressOfFunctions);

&#160;&#160;&#160;&#160;FunctionAddress = (PVOID)Addr[OrdinalNumber];

&#160;&#160;&#160;&#160;//
&#160;&#160;&#160;&#160;// Forwarders are not used by the kernel and HAL to each other.
&#160;&#160;&#160;&#160;//


&#160;&#160;&#160;&#160;return FunctionAddress;
}

4

主题

24

回帖

0

积分

新手上路

积分
0
发表于 2013-8-28 17:07:01 | 显示全部楼层
这个有没有出处?:?:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-2 05:43 , Processed in 0.137828 second(s), 21 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表