GetProcAddress не возвращает реальный адрес для LoadLibraryA

DWORD dwLoadLibrary = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); 

Когда я перехожу на возвращенный адрес в OllyDbg, я вижу, что этот адрес указывает на код, который перескакивает на реальный адрес LoadLibraryA. Я хочу получить реальный адрес LoadLibraryA, который не изменяется, потому что kernel32.dll загружается в одном месте в каждом процессе, а также мне хотелось бы знать, почему GetProcAddress не возвращает реальный адрес.

введите описание изображения здесь

Вы получаете «реальный» адрес kernel32.LoadLibraryA , поскольку GetProcAddress() возвращает реальный адрес. Просто реализация kernel32.LoadLibrayA переместилась из kernel32.dll в kernelbase.dll , и в результате kernel32.LoadLibraryA просто состоит из одной команды:

 jmp dword ptr[kernelbase.LoadLibraryA] 

Если вы посмотрите на другие функции в kernel32.dll , многие из них также имеют такой же шаблон:

 kernel32.somefunc: jmp [kernelbase.somefunc] 

Это «реальный» адрес LoadLibraryA . Инструкция перехода есть для инструментов, чтобы установить там косвенность. Они будут менять адрес назначения этого прыжка с чем-то другим, указывая на крючок и переходить в исходное местоположение после выполнения крюка для фактического выполнения функции.

Откуда вы знаете, что это не настоящий адрес LoadLibraryA ? Может быть, вместо этого попробуйте WinDbg?

В моей системе Windows 8 GetProcAddress(x, "LoadLibraryA") возвращает функцию, которая начинается с обычного резервирования ed edi mov edi,edi edi hotpatch (и остальной функции), но это не означает, что он не может начинаться с перехода в другие версии.