导入表注入

程序开始运行时,加载程序根据导入表的DLL名字加载DLL。首先在运行目录下查找DLL,如果找到,则把他加载进进程空间。如果没找到则在系统目录下继续寻找。可以通过这一个特点,在原有的导入表后面增加一个导入表结构(INT和IAT表至少有一个函数的名字)。
这就是导入表注入。
自定义的要写入的结构
typedef struct _NEW_IMPORT_TABLE
{
IMAGE_IMPORT_DESCRIPTOR iid;//一个新的导入表结构
IMAGE_IMPORT_DESCRIPTOR zero_iid;//一个全0的导入表结构
DWORD Int;//INT表
DWORD Int_ZERO;//INT表的结束
DWORD Iat;//IAT表
DWORD Iat_zero;//IAT表的结束
WORD Hint;// 取结构体大小时注意结构体对齐问题
}NEW_IMPORT_TABLE, *PNEWIMPORTTABLE;


{
	

	//移动所有导入表
	PVOID pOptionHeader = NULL;
	GetPEOptionHeader(pImage,&pOptionHeader);
	//得到第一个导入表的FOA
	DWORD ImportTable_FOA = RVA_To_FOA(pImage,((PIMAGE_OPTIONAL_HEADER32)pOptionHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
	/*
	typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    DWORD   OriginalFirstThunk
	DWORD   TimeDateStamp;                  // 0 if not bound,
    DWORD   ForwarderChain;                 // -1 if no forwarders
	DWORD   Name;
	DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
	} IMAGE_IMPORT_DESCRIPTOR;
	*/
	//遍历导入表得到导入表的大小
	DWORD Index = 0;
	PIMAGE_IMPORT_DESCRIPTOR pIID=(PIMAGE_IMPORT_DESCRIPTOR)((PCHAR)pImage+ ImportTable_FOA);
	while (pIID->FirstThunk&&pIID->OriginalFirstThunk)
	{
        Index++;
		pIID++;
	}
	//获取新增加节的FOA 
	PVOID pSectionTable = NULL;
	GetPESectionTable(pImage, &pSectionTable, GetNumberOfSections(pImage));
	DWORD WriteAddr_FOA =((PIMAGE_SECTION_HEADER)pSectionTable)->PointerToRawData;
	//复制原来的导入表
	memcpy_s((char*)pImage+ WriteAddr_FOA, Index*sizeof(IMAGE_IMPORT_DESCRIPTOR), (PCHAR)pImage + ImportTable_FOA, Index * sizeof(IMAGE_IMPORT_DESCRIPTOR));
	//修改导入表的virtualAddress
	((PIMAGE_OPTIONAL_HEADER32)pOptionHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = FOA_To_RVA(pImage, WriteAddr_FOA);
	//构建两个IMAGE_IMPORT_DESCRIPTOR结构 第二个全0结构。

	//得到新加入的导入表的FOA
	DWORD NewImprtTable_FOA = WriteAddr_FOA + Index * sizeof(IMAGE_IMPORT_DESCRIPTOR);
	//新写入开始的指针
	PNEWIMPORTTABLE pNewImportTable =(PNEWIMPORTTABLE)((char*)pImage + WriteAddr_FOA + Index * sizeof(IMAGE_IMPORT_DESCRIPTOR));
	
	//需要找到的FOA值: DLL名字的FOA   导入函数名字的FOA  
	// IAT 表的FOA  INT表的FOA  写入 iid OriginalFitstThunk FitstThunk
	//注意  IAT表存放的是导入函数名前两个字节的RVA Hint
	//iid 的OriginalFitstThunk存放INT表的RVA 
	//iid 的FitstThunk存放IAT表的RVA
	//先写入函数名字和 dll名字  先写入 函数名 再写入dll名 
	char lpszFuncName[] = "Show";
	char lpszDllName[] = "Inject.dll";
    //获得函数名的长度  strlen 返回的长度不包括0结尾
	DWORD SizofFuncName = strlen(lpszFuncName);

	//获得dll名字的长度
	DWORD SizeofDllName = strlen(lpszDllName);
	// 先写入 函数名  
	memcpy_s((PCHAR)pNewImportTable+sizeof(NEW_IMPORT_TABLE)-2,
		SizofFuncName,
		lpszFuncName,
		SizofFuncName);
	//再写入dll名 
	memcpy_s((PCHAR)pNewImportTable + sizeof(NEW_IMPORT_TABLE)+ SizofFuncName+1-2,
		SizeofDllName,
		lpszDllName,
		SizeofDllName);
	//需要找到的FOA值:   导入函数名字的FOA  DLL名字的FOA 
	DWORD FuncName_FOA = NewImprtTable_FOA + 56;
	DWORD DllName_FOA = FuncName_FOA + SizofFuncName + 3;//这里加3的原因是因为FuncName_FOA的位置是在hint索引的两字节位置+上函数的0结尾就是3字节

	DWORD INT_FOA = NewImprtTable_FOA + 40;
	DWORD IAT_FOA = NewImprtTable_FOA + 48;


	pNewImportTable->Int=FOA_To_RVA(pImage, FuncName_FOA);
	pNewImportTable->Iat = FOA_To_RVA(pImage, FuncName_FOA);
	pNewImportTable->iid.OriginalFirstThunk = FOA_To_RVA(pImage, INT_FOA);
	pNewImportTable->iid.FirstThunk = FOA_To_RVA(pImage, IAT_FOA);
	pNewImportTable->iid.Name= FOA_To_RVA(pImage, DllName_FOA);

    ImageBufferToFile(pImage,"c:/InjectOver.exe");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值