进程创建期修改PE输入表法注入

进程创建期修改PE输入表法注入

程序定义

CImage类

内部包含了一些有关PE结构的变量和一些函数函数列表如下

  • findImagebase()
  • AttachToProcess()
  • InitializePEHeaders()
  • AddNewSectionToMemory()
  • LocateSectionByRVA()
  • ALIGN_SIZE_UPALIGN_SIZE_UP(Size,Alignment) (((ULONG_PTR)(Size) + Alignment - 1) & ~(Alignment - 1))

程序执行流程

启动注入程序

利用CreateProcess并以挂起的方式启动需要注入程序

寻找程序基址

这里采用的方法是遍历全部内存地址,并且以dwpagesize为单位,VirtualQueryEX判断页面状态,如果为MEM_COMMIT(提交)状态,在判断内存种类如果为MEM_IMAGE,则利用函数GetMappedFileName,判断该内存的名称与我们是否一致。如果一致则成功得到基址。

初始化PE

首先ReadProcessMemory读取PE程序,并初始化PE头,根据基地址获取PIMAGE_DOS_HEADER

根据DOS头e_lfanew获取PIMAGE_NT_HEADER地址

根据NT头FileHeader获取文件头地址,OptionalHeader获取可选头地址

根据文件头NumberOfSections获取节区个数

根据可选头DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]获取基址重定位表,加上可选头大小即可得到节区头地址。AddressOfEntryPoint获取程序入口地址。SizeOfImage获取镜像大小。ImageBase获取基址DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]获取导入表,DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]获取导出表。

根据导入表VirtualAddress获取导入表虚拟地址,size获取大小

根据导出表VirtualAddress获取导出表虚拟地址。

导入表在内存区的区段

遍历各个节区头的VirtualAddress,来判断。

在内存中添加新节区

计算好新节区大小(导入表原始大小+一个导入表结构体+4*sizeof(ULONG_PTR)+strlen(szDllName)+1+sizeof(word)+strlen(szDllExportFunName)+1)

其中4个(ULONG_PTR)的指针分别为Import_BY_NAME结构体VA和0填充再加上IAT和0填充

计算新节区的内存偏移

dwSectionVA = pLastSecHeader->VirtualAddress + ALIGN_SIZE_UP(pLastSecHeader->Misc.VirtualSize,m_pOptHeader->SectionAlignment);

计算新节区头偏移

PIMAGE_SECTION_HEADER pNewSecHeader = m_pSecHeader + m_SectionCnt

VirtualAllocEXdwSectionVA+Imagebase开始分配内存,大小为新节区大小

之后将节区头大小偏移。并且将节区头各属性一一赋值。

再更新文件头的节区个数,可选头的SizeOfImage大小要加上新节区大小。

为新节区填充

首先填充DLLname,之后填充PIMPORT_BY_NAME结构,之后再填充OriginalFirst其中OringalFirst指向PIMPORT_BY_NAME偏移。FirstThunk就用0来填充。

更新pe头

将更新导入表的大小,设立新导入表的偏移

Image.m_pImpDataDir->Size = dwNewIIDSize;
Image.m_pImpDataDir->VirtualAddress = dwVAToStoreNewIID;

清空绑定输入表

Image.m_pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
	Image.m_pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;

强迫加载器重新加载IAT。

写入进程内存

将改写的数据(文件头,可选头,节区头,新节区)全部写入进程内存。

Resume

最后执行主线程。注入完毕,程序加载该dll。


代码参考:加密与解密4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值