LPVOID exefilebuffer = NULL;
DWORD exeFileLen = GetFileBuffer(TEST_IMPORt_INJECT_PATH, &exefilebuffer);
if (!exeFileLen)
{
printf("get filebuffer failed!\n");
return;
}
// 计算我们需要的长度...
UINT nAddLen = 0;
UINT oldDescripitorLen = 0;
PIMAGE_DOS_HEADER pexeDosHeader = NULL;
pexeDosHeader = (PIMAGE_DOS_HEADER)exefilebuffer;
PIMAGE_NT_HEADERS32 pexeNTHeader = NULL;
pexeNTHeader = (PIMAGE_NT_HEADERS32)((DWORD)exefilebuffer + pexeDosHeader->e_lfanew);
DWORD exeImportFOA = RVAtoFOA(exefilebuffer, pexeNTHeader->OptionalHeader.DataDirectory[1].VirtualAddress);
PIMAGE_IMPORT_DESCRIPTOR pexeImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)exefilebuffer + exeImportFOA);
while (pexeImport->Name != 0 && pexeImport->FirstThunk != 0 && pexeImport->OriginalFirstThunk != 0)
{
nAddLen += sizeof(IMAGE_IMPORT_DESCRIPTOR); //14bytes
pexeImport++;
}
oldDescripitorLen = nAddLen;
nAddLen += sizeof(IMAGE_IMPORT_DESCRIPTOR);// 最后一个0 结构也算上...
nAddLen += sizeof(IMAGE_IMPORT_DESCRIPTOR);//自己dll 的一个描述结构...
nAddLen += strlen("TestDll.dll") + 1;// 加上namebuffer ...
nAddLen += 16;// INT 和IAT 表长度最小值...
nAddLen += 2;
nAddLen += strlen("_Plus@8")+1; // 加上byName结构的及namebuffer...
//nAddLen += 2;
//nAddLen += strlen("_Plus@8") + 1; // 加上byName结构的及namebuffer... //多加了10bytes
//判断是否有这样的空白区...遍历节表...
PIMAGE_SECTION_HEADER pexeSecHeader = NULL; // 一般不可能只有一个节....
pexeSecHeader = (PIMAGE_SECTION_HEADER)((DWORD)pexeNTHeader + sizeof(IMAGE_NT_HEADERS32));
if (pexeNTHeader->FileHeader.NumberOfSections == 1)
{
DWORD BlankSpace = exeFileLen - pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize;
if (BlankSpace < nAddLen)
{
printf("空白区不足!\n");
return;
}
}
for (int i = 0; i < pexeNTHeader->FileHeader.NumberOfSections; ++i)
{
DWORD BlankSpace = (pexeSecHeader + 1)->PointerToRawData -
(pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize);
if (BlankSpace >= nAddLen)
break; // 发现第一个节就满足要求了...
pexeSecHeader++;
}
pexeImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)exefilebuffer + exeImportFOA);
// 直接移动原有的 导入描述结构...
memset((LPVOID)((DWORD)exefilebuffer + pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize), 0,
nAddLen);
memcpy((LPVOID)((DWORD)exefilebuffer + pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize),
(LPVOID)pexeImport, oldDescripitorLen);
// 添加一项 descriptor
PIMAGE_IMPORT_DESCRIPTOR pNewImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
((DWORD)exefilebuffer + pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize+oldDescripitorLen);
memcpy(pNewImportDescriptor, pexeImport, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// 描述结构结束 后就是iat int表...
PIMAGE_THUNK_DATA32 pINT = (PIMAGE_THUNK_DATA32)(pNewImportDescriptor + 2);
PIMAGE_THUNK_DATA32 pIAT = (PIMAGE_THUNK_DATA32)(pINT+2);
PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)(pIAT + 2);
pByName->Hint = 0;
strcpy(pByName->Name, "_Plus@8");
DWORD byNameRVA = FOAtoRVA(exefilebuffer, (DWORD)pByName - (DWORD)exefilebuffer);
pIAT->u1.AddressOfData = byNameRVA;
pINT->u1.AddressOfData = byNameRVA;
// 接着是dllname
LPVOID dllname = (LPVOID)((DWORD)pByName + 2 + strlen("_Plus@8") + 1);
memcpy(dllname, "TestDll.dll", strlen("TestDll.dll"));
DWORD dllNameRVA = FOAtoRVA(exefilebuffer, (DWORD)dllname - (DWORD)exefilebuffer);
pNewImportDescriptor->Name = dllNameRVA;
DWORD firstRVA = FOAtoRVA(exefilebuffer, (DWORD)pIAT - (DWORD)exefilebuffer);
pNewImportDescriptor->FirstThunk = firstRVA;
DWORD OridinalRVA = FOAtoRVA(exefilebuffer, (DWORD)pINT - (DWORD)exefilebuffer);
pNewImportDescriptor->OriginalFirstThunk = OridinalRVA;
//pNewImportDescriptor->FirstThunk = OridinalRVA;// 让他指向同一块内存...
// 修改目录属性...
DWORD newImportDescriptorFOA = pexeSecHeader->PointerToRawData + pexeSecHeader->Misc.VirtualSize;
pexeNTHeader->OptionalHeader.DataDirectory[1].VirtualAddress = FOAtoRVA(exefilebuffer, newImportDescriptorFOA);
pexeNTHeader->OptionalHeader.DataDirectory[1].Size += 0x14;
// 存盘... 不修改文件大小的情况下..
HANDLE hFile = CreateFile(L"C:\\Users\\Administrator\\Desktop\\1111.exe", GENERIC_ALL, FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("create file failed!\n");
return;
}
DWORD dwRetBytes = 0;
if (!WriteFile(hFile, exefilebuffer, exeFileLen, &dwRetBytes, NULL))
{
printf("write file failed!\n");
return;
}
delete[]exefilebuffer;
}
// 我的代码就这样,写好之后,用LoadPe看我的目标程序 导入表也没错啊 但是就是启动c00000005错误