1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| #include <iostream> #include <Windows.h>
constexpr auto FilePath_SRC = "xxx\\Dll1.dll"; constexpr auto FilePath_DEST = "xxx\\Dll1_demo.dll";
DWORD RVA2FOA(DWORD dwRVA, LPVOID lpBuffer) { PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpBuffer; PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)pDos); PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(pNt);
if (dwRVA < pSec[0].VirtualAddress) { return dwRVA; }
for (size_t i = 0; i < pNt->FileHeader.NumberOfSections; i++) { if (dwRVA >= pSec[i].VirtualAddress && dwRVA <= pSec[i].VirtualAddress + pSec[i].Misc.VirtualSize) { return dwRVA - pSec[i].VirtualAddress + pSec[i].PointerToRawData; } } return dwRVA; }
DWORD FOA2RVA(DWORD dwFOA, LPVOID lpBuffer) { PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpBuffer; PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)pDos); PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(pNt);
if (dwFOA < pSec[0].PointerToRawData) { return dwFOA; } for (size_t i = 0; i < pNt->FileHeader.NumberOfSections; i++) { if (dwFOA >= pSec[i].PointerToRawData && dwFOA < pSec[i].PointerToRawData + pSec[i].SizeOfRawData) { return pSec[i].VirtualAddress + dwFOA - pSec[i].PointerToRawData; } } return dwFOA; }
int main() { HANDLE hFile = CreateFileA( FilePath_SRC, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL ); if (INVALID_HANDLE_VALUE == hFile) { printf("CreateFileA Failed\n"); return 0; } DWORD dwFileSize = GetFileSize(hFile, NULL); printf("dwFileSize: %d\n", dwFileSize); LPVOID lpData = new BYTE[dwFileSize]; if (lpData == NULL) { printf("申请内存失败\n"); return 0; } DWORD dwRead = 0; if (FALSE == ReadFile(hFile, lpData, dwFileSize, &dwRead, NULL)) { printf("ReadFile Failed\n"); return 0; } printf("lpData: %x\n", *(short*)lpData);
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpData; PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)lpData); PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(pNt);
PIMAGE_SECTION_HEADER pNewSec = pSec + pNt->FileHeader.NumberOfSections; if (((DWORD)lpData + dwFileSize - (DWORD)pNewSec) < 80) { printf("空间不足新增节表\n"); return 0; }
strcpy((char*)pNewSec->Name, ".rbase"); pNewSec->Misc.VirtualSize = 0x7000; pNewSec->VirtualAddress = pNt->OptionalHeader.SizeOfImage; pNewSec->SizeOfRawData = 0x7000; PIMAGE_SECTION_HEADER pLastSec = pSec + (pNt->FileHeader.NumberOfSections - 1); pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData; pNewSec->Characteristics = pSec[0].Characteristics;
pNt->FileHeader.NumberOfSections += 1; pNt->OptionalHeader.SizeOfImage += 0x7000;
LPVOID lpSecMemory = new BYTE[0x7000]; if (lpSecMemory == NULL) { printf("新节表申请内存失败\n"); return 0; } memset(lpSecMemory, 0, 0x7000);
PIMAGE_DATA_DIRECTORY pDir = (PIMAGE_DATA_DIRECTORY)(pNt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_BASERELOC); PIMAGE_BASE_RELOCATION pReloc = (PIMAGE_BASE_RELOCATION)(RVA2FOA(pDir->VirtualAddress, lpData) + (DWORD)lpData); printf("pDir->Size: %x\n", pDir->Size);
memcpy(lpSecMemory, pReloc, pDir->Size);
pDir->VirtualAddress = FOA2RVA(dwFileSize, lpData);
HANDLE hNewFile = CreateFileA(FilePath_DEST, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hNewFile) { printf("CreateFileA Failed\n"); return 0; } DWORD lpNumberOfBytesWritten1 = 0; if (FALSE == WriteFile(hNewFile, lpData, dwFileSize, &lpNumberOfBytesWritten1, NULL)) { printf("WriteFile One Failed\n"); return 0; } DWORD lpNumberOfBytesWritten2 = 0; if (FALSE == WriteFile(hNewFile, lpSecMemory, 0x7000, &lpNumberOfBytesWritten2, NULL)) { printf("WriteFile Two Failed\n"); return 0; } CloseHandle(hNewFile); printf("WriteFile Success: %d %d\n", lpNumberOfBytesWritten1, lpNumberOfBytesWritten2);
typedef void (*MyShowMessage)(); HMODULE hDll = LoadLibraryA(FilePath_DEST); if (hDll == NULL) { printf("LoadLibraryA Failed\n"); return 0; } MyShowMessage myShowMessage = (MyShowMessage)GetProcAddress(hDll, "ShowMessage"); myShowMessage(); }
|