无法在kernel32.dll导出目录中找到GetProcAddress?

时间:2016-07-07 06:20:07

标签: c++11 dll export portable-executable kernel32

我试图在kernel32.dll中获取特定函数的RVA,因此我可以将RVA用作指定进程中kernel32.dll的基址的偏移量,以获得VA的值我需要注入我的dll的函数。我已经找不到LoadLibrary了,但我确实找到了LoadLibraryExA,而是使用了我的dll注入器,但我现在无法找到GetProcAddress我要去的地方用于在我的ThreadProc函数中找到函数的VA。因此,如果我找不到它意味着我将需要计算并存储我需要的每个函数的VA,并将其放入一个结构中以传递给LPVOID lpParam参数ThreadProc 1}}这不是理想的。

以下是所有相关功能:

void* GetFileImage(char path[])
{
    HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
    if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded

    HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
    if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed

    LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
    if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed

    return file_image; //return the base address of the image
}

DWORD RVAddress(char* image, const char* proc_name)
{
    DWORD address = 0xFFFFFFFF; 

    PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
    PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
    IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
    IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 
    PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory 

    void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
    WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
    BYTE** name_table = (BYTE**)(image+pExp_dir->AddressOfNames); //Get an array of function names

    for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
    {
        printf("%s ", (BYTE*)image+(DWORD)(intptr_t)name_table[i]); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
        if(strcmp(proc_name, (const char*)(BYTE*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
        {
            address = (DWORD)(intptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
            system("CLS"); //Clear the screen
            return address; //return the address of the function
        }
    }

    return (DWORD)0; //Other wise return 0
}

DWORD GetRemoteFunctionAddress(DWORD dwPid, char* kernel_path, char* function_name)
{
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;
    me32.dwSize = sizeof(MODULEENTRY32);

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, dwPid); //Get a snapshot of all the modules in the program(64 and 32 bit, 32 since kernel is 32)
    if(hSnapshot == INVALID_HANDLE_VALUE){printf("Snapshot failed");return 0;} //Snapshot not created

    if(!(Module32First(hSnapshot, &me32))) //Don't care about it because it will be the exe of the process
    {
        printf("Mod32First failed");
        return 0;
    }

    while(Module32Next(hSnapshot, &me32)) //Iterate through until...
    {
        if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL") //we find kernel32.dll
        {
            CloseHandle(hSnapshot);
            break;
        }
    }

    printf("\nBase address: 0x%08X\n", (DWORD)(intptr_t)me32.modBaseAddr); //Used this for CheatEngine

    DWORD RVA = (DWORD_PTR)RVAddress((char*)GetFileImage(kernel_path), function_name); //Get the relative virtual address of the function

    DWORD Load = (DWORD_PTR)me32.modBaseAddr+(DWORD_PTR)RVA; //Add the base address of kernel32.dll and the RVA of the function to get a DWORD representation of the address of the function in the remote process

    return Load; //return the address of the function in the remote process
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL")

您不能在char数组上使用==,必须使用stricmp

您可以使用以下方法代替所有这些方法:

GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA")

这将在运行时为您提供绝对地址