#include <windows.h>



DWORD ReGetProcAddress(HMODULE hModule, HMODULE hOldModule, LPCSTR lpProcName)
{
  DWORD MyApiAddr;
  DWORD ApiOffset;
  DWORD ReApiAddr;

  
  MyApiAddr = (DWORD)GetProcAddress(hOldModule, lpProcName);
  ApiOffset = MyApiAddr - (DWORD)hOldModule;
  ReApiAddr = (DWORD)hModule + ApiOffset;

  return (ReApiAddr);
}


HMODULE RemapLibrary(LPCSTR lpModuleName)
{
  HMODULE hMod;
  DWORD ImageSize;
  BYTE* Virtual;
  PIMAGE_DOS_HEADER DosHeader;
  PIMAGE_NT_HEADERS NtHeader;

  hMod = GetModuleHandleA(lpModuleName);
  if(!hMod)
  {
    return (0);
  }

  DosHeader = (PIMAGE_DOS_HEADER)hMod;
  NtHeader = (PIMAGE_NT_HEADERS)((DWORD)DosHeader + (DWORD)DosHeader->e_lfanew);
  ImageSize = (DWORD)NtHeader->OptionalHeader.SizeOfImage;
  
  Virtual = (BYTE*)VirtualAlloc(NULL, ImageSize, MEM_COMMIT, PAGE_READWRITE);
  if(!Virtual)
  {
    return (0);
  }

  VirtualLock(Virtual, ImageSize);

  memcpy(Virtual, (PBYTE)hMod, ImageSize);

  return ((HMODULE)Virtual);
}


typedef DWORD (WINAPI *MSGBOX)(HWND,LPSTR,LPSTR,UINT);

void main()
{
  HMODULE hOldMod, hNewMod;
  MSGBOX MyMessageBox;

  printf("开始动态加载User32.dll\n");

  hOldMod = LoadLibrary("user32.dll");

  printf("User32.dll加载成功!\n");

  printf("开始重新映射User32.dll\n");

  hNewMod = RemapLibrary("user32.dll");

  printf("User32.dll重新映射成功!\n按任意键继续...\n");

  getchar();

  printf("开始释放原User32.dll\n");

  FreeLibrary(hOldMod);

  printf("User32.dll释放成功!\n按任意键继续...\n");

  getchar();

  MyMessageBox = (MSGBOX)ReGetProcAddress(hNewMod, hOldMod, "MessageBoxA");
  
  MyMessageBox(NULL, "ReMapLibrary OK!", "Test", 0);

  printf("调用MessageBoxA成功!");

}: