没有它们如何获取 GetProcAdress 和 LoadLibrary?

How to obtain GetProcAdress and LoadLibrary without them?

假设我没有导入 .lib 库 我希望一切都以原始方式进行,通过手动编写 调用(如汇编或纯 c)

GetProcAdress LoadLibrary 是 winapi dll 的一部分 通常加载 dll 并获取指针 对于我需要调用这两个函数的函数,但是因为我 没有得到它们我可以用什么来获得它们?

这有点像悖论,可能可以通过一些其他机制来解决,但是在这里我缺乏知识,我不知道这个机制是什么,有人可以解释一下吗?

我以前确实做到过。确实有可能。解决方案基本上是手动实现 LdrGetDllHandle 并使用它在 [=14= 中搜索 LdrLoadDll/LdrUnloadDllLdrGetProcedureAddress ] 通过 NtCurrentPeb 获取指向进程 PEB_LDR_DATA 数据结构的指针,这是一个读取 FS 或 GS​​ CPU 寄存器的宏。
一旦您获得了这三个函数的指针,您就可以使用它们来加载您需要的其他 DLL。

我不会 post 代码给你,但是如果你看一下 ReactOS 的源代码,你应该能够逐渐弄清楚如何实现这个 -- 我认为这些应该足够的指导(没有双关语意)让你开始。 :)

以下假设从内部调用 mainCRTStartup() kernel32.dll。 它使用 return 地址定位模块的开始,并从那里搜索其 EAT 以获取 GetProcAddress()。

#include <windows.h>

static HMODULE findModuleBase( void *ptr )
{
  ULONG_PTR addr = (ULONG_PTR)ptr;
  addr &= ~0xffff;
  const UINT32 *mod = (const UINT32*)addr;
  while( mod[0]!=0x00905a4d ) // MZ.. header
    mod -= 0x4000; // 0x10000/4
  return( (HMODULE)mod );
}

#define REL_PTR( base,ofs ) ( ((PBYTE)base)+ofs )
static void *findGetProcAddress( HMODULE mod )
{
  PIMAGE_DOS_HEADER idh = (PIMAGE_DOS_HEADER)mod;
  PIMAGE_NT_HEADERS inh = (PIMAGE_NT_HEADERS)REL_PTR( idh,idh->e_lfanew );
  PIMAGE_EXPORT_DIRECTORY ied =
    (PIMAGE_EXPORT_DIRECTORY)REL_PTR( idh,inh->OptionalHeader.
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress );
  DWORD *names = (DWORD*)REL_PTR( idh,ied->AddressOfNames );
  unsigned int i;
  for( i=0; i<ied->NumberOfNames; i++ )
  {
    const UINT32 *name32 = (const UINT32*)REL_PTR( idh,names[i] );
    const UINT16 *name16 = (const UINT16*)name32;
    const UINT8 *name8 = (const UINT8*)name32;
    if( name32[0]!=0x50746547 || // GetP
        name32[1]!=0x41636f72 || // rocA
        name32[2]!=0x65726464 || // ddre
        name16[6]!=0x7373 ||     // ss
        name8[14]!=0x00 )
      continue;
    WORD *ordinals = (WORD*)REL_PTR( idh,ied->AddressOfNameOrdinals );
    DWORD *funcs = (DWORD*)REL_PTR( idh,ied->AddressOfFunctions );
    return( REL_PTR(idh,funcs[ordinals[i]]) );
  }
  return( NULL );
}

#ifdef __MINGW32__
#define RETURN_ADDRESS() __builtin_return_address(0)
#else
#define RETURN_ADDRESS() _ReturnAddress()
#endif
void mainCRTStartup( void )
{
  HMODULE kernel = findModuleBase( RETURN_ADDRESS() );

  typedef LPVOID WINAPI func_GetProcAddress( HMODULE,LPCSTR );
  func_GetProcAddress *fGetProcAddress = findGetProcAddress( kernel );

  typedef HMODULE WINAPI func_LoadLibraryA( LPCSTR );
  typedef VOID WINAPI func_ExitProcess( UINT );
  func_LoadLibraryA *fLoadLibraryA = fGetProcAddress( kernel,"LoadLibraryA" );
  func_ExitProcess *fExitProcess = fGetProcAddress( kernel,"ExitProcess" );

  typedef int func_printf( const char*,... );
  HMODULE msvcrt = fLoadLibraryA( "msvcrt.dll" );
  func_printf *f_printf = fGetProcAddress( msvcrt,"printf" );
  f_printf( "is this working?\n" );

  fExitProcess( 1 );
}