滴水逆向——PE导入表注入

1.注入概念:

2.导入表注入流程:

第一步:         

          根据目录项(第二个就是导入表)得到导入表信息:     

          typedef struct _IMAGE_DATA_DIRECTORY {     

    DWORD   VirtualAddress;      

    DWORD   Size;        

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;    

          VirtualAddress :指向导入表结构      

Size:导入表的总大小       

          这两个值都需要            

第二步:         

          typedef struct _IMAGE_IMPORT_DESCRIPTOR {     

    union {        

        DWORD   Characteristics;                

        DWORD   OriginalFirstThunk;              

    };          

    DWORD   TimeDateStamp;                    

    DWORD   ForwarderChain;                   

    DWORD   Name;        

    DWORD   FirstThunk;                      

} IMAGE_IMPORT_DESCRIPTOR;       

typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;  

          判断哪一个节的空白区 > Size(原导入表的大小) + 20 + A + B + C + D  

          如果空间不够:可以将C/D 存储在其他的空白区     

          也就是,只要空白区 > Size + 0x20就可以了     

          如果仍然不够,就需要扩大最后一个节,或者新增节来解决.               

第三步:         

          将原导入表全部Copy到空白区       

第四步:         

          在新的导入表后面,追加一个导入表.            

第五步:         

          追加8个字节的INT表  8个字节的IAT表         

第六步:         

          追加一个IMAGE_IMPORT_BY_NAME 结构,前2个字节是0 后面是函数名称字符串         

第七步:         

          将IMAGE_IMPORT_BY_NAME结构的RVA赋值给INT和IAT表中的第一项        

第八步:         

          分配空间存储DLL名称字符串 并将该字符串的RVA赋值给Name属性       

第九步:         

          修正IMAGE_DATA_DIRECTORY结构的VirtualAddress和Size    

4.代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>

#define size_surplus_sizeofheader 0x50
#define test 1

BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile);
DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer);
DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer);
DWORD CopyImageBufferToNewFileBuffer(PVOID pImageBuffer, PVOID* pNewFileBuffer);
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);
DWORD DLLInject(PVOID pFileBuffer, PVOID* pNewFileBuffer, char* dllname, char* dllfunction);
VOID LogPEHeaderInfo(PVOID pFileBuffer);
VOID LogImportTable(PVOID pFileBuffer);

char file_path[] = "d:\\ipmsg2007\\ipmsg2007.exe";
char dllname[] = "InjectDll.dll";
char dllfunction[] = "ExportFunction";
char write_dllinject_file_path[] = "D:\\Lib\\cp_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)No
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值