1.绑定导入表结构
2.定位绑定导入表
3.注意:
IMAGE_IMPORT_DESCRIPTOR结构中的TimeDateStamp可以知道一个DLL有没有被绑定。TimeDateStamp为0,即未绑定;为-1即为绑定。
当IMAGE_BOUND_IMPORT_DESCRIPTOR结构中的TimeDateStamp与DLL文件标准PE头中的TimeDateStamp值不相符
时,或者DLL需要重新定位的时候,就会重新计算IAT中的值.
4.代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define test 1
DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer);
BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile);
DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa);
DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva);
DWORD GetSctionEmptySpace(PVOID pFileBuffer, DWORD SectionOrdinal);
DWORD Alignment(DWORD alignment_value, DWORD addend, DWORD address);
VOID LogPEHeaderInfo(PVOID pFileBuffer);
VOID LogExportTable(PVOID pFileBuffer);
VOID LogBaseRelocationTable(PVOID pFileBuffer);
VOID LogImportTable(PVOID pFileBuffer);
VOID LogBoundImportTable(PVOID pFileBuffer);
char file_path[] = "c:\\users\\desktop\\notepad.exe";
//char file_path[] = "c:\\users\\desktop\\dll1test.dll";
//char file_path[] = "c:\\users\\desktop\\ipmsg2007.exe";
char write_file_path[] = "D:\\Lib\\cp_XX.exe";
char write_adddata_file_path[] = "D:\\Lib\\cp_adddata_XX.exe";
char write_addsec_file_path[] = "D:\\Lib\\cp_addsec_XX.exe";
char write_enlargersec_file_path[] = "D:\\Lib\\cp_enlargersec_XX.exe";
char write_mergesec_file_path[] = "D:\\Lib\\cp_mergesec_XX.exe";
//返回PE文件大小
DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer)
{
FILE *pFile = NULL;
DWORD FileSize = 0;
PVOID pFileBufferTemp = NULL;
pFile = fopen(file_path, "rb");
if (!pFile)
{
printf("(ToLoaderPE)Can't open file!\n");
return 0;
}
fseek(pFile, 0, SEEK_END);
FileSize = ftell(pFile);
printf("FileBuffer: %#x\n", FileSize);
fseek(pFile, 0, SEEK_SET);
pFileBufferTemp = malloc(FileSize);
if (!pFileBufferTemp)
{
printf("(ToLoaderPE)Allocate dynamic memory failed!\n");
fclose(pFile);
return 0;
}
DWORD n = fread(pFileBufferTemp, FileSize, 1, pFile);
if (!n)
{
printf("(ToLoaderPE)Read file failed!\n");
free(pFileBufferTemp);
fclose(pFile);
return 0;
}
*pFileBuffer = pFileBufferTemp;
pFileBufferTemp = NULL;
fclose(pFile);
return FileSize;
}
BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile)
{
FILE *fp;
fp = fopen(lpszFile, "wb");
if (fp != NULL)
{
fwrite(pMemBuffer, size, 1, fp);
}
fclose(fp);
printf("Store file success!\n");
return 1;
}
DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if (!pBuffer)
{
printf("(RvaToFileOffset)Can't open file!\n");
return 0;
}
if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(RvaToFileOffset)No MZ flag, not exe file!\n");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(RvaToFileOffset)Not a valid PE flag!\n");
return 0;
}
//printf("ImageOffset: %#x\n", dwRva);
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader;
if (dwRva <= pOptionHeader->SizeOfHeaders)
return (DWORD)dwRva;
else
{
for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++)
{ //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中)
if ((dwRva >= pSectionTemp->VirtualAddress) && (dwRva < pSectionTemp->VirtualAddress + pSectionTemp->Misc.VirtualSize))
{
return dwRva - pSectionTemp->VirtualAddress + pSectionTemp->PointerToRawData;
}
}
}
printf("RvaToFoa failed!\n");
return 0;
}
DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if (!pBuffer)
{
p