首页
社区
课程
招聘
[原创]一步一步实现在PE文件中添加可执行代码
发表于: 2012-5-28 13:07 26944

[原创]一步一步实现在PE文件中添加可执行代码

2012-5-28 13:07
26944

最近在学习罗云彬老师写的《Windows环境下32位汇编语言程序设计》书中的PE文件,着重分析了下如何在PE文件中添加可执行代码的问题。因为书上对这个程序没有做过多分析,这里我把自己的分析过程及一些问题进行讲解,希望能给初学者一点帮助。
        众所周知,PE文件是Windows下的文件格式,包括exe、dll等,那么如何向PE文件中添加可执行代码呢?我们应该有以下这些问题:
1、        可执行代码应该添加到PE文件的什么位置?
2、        如何让添加的代码最先执行?
3、        执行完添加的代码后如何回到原PE文件的起始地址?
4、        添加的代码如何获取需要用到的API地址?
带着这些问题,我们的主题就开始了。
准备知识:
1、        首先你得知道PE文件结构,不然很多问题你不会很明白,附件中有一张我作的PE文件结构的思维导图,希望能对你有帮助。
2、        新加的代码功能很简单,就是在运行这个PE文件之前弹出一个选择对话框,询问是否继续。代码放在后面附件中,请读者先下载看看,后面的讲解中会涉及到。
3、        了解Windows环境下的程序设计,不然你会不知道我在说什么,呵呵。。
好了,废话不多说,我们进入正题。
1、        使用通用控件GetOpenFileName函数打开一个查找文件的对话框,选择想要添加代码的文件。获得文件句柄后,通过内存映射函数CreateFileMapping和MapViewOfFile获取PE文件的起始地址。然后通过对文件的MZ格式文件头和PE头分析该文件是不是有效的PE文件,如果不是直接退出,如果是则进入下一步。这部分的代码比较简单,就直接写在下面了。
               

local	@stOF:OPENFILENAME
		local	@hFile,@dwFileSize,@hMapFile,@lpMemory

		invoke	RtlZeroMemory,addr @stOF,sizeof @stOF
;初始化OPENFILENAME结构,以便使用
		mov	@stOF.lStructSize,sizeof @stOF
		push	hWinMain
		pop	@stOF.hwndOwner
		mov	@stOF.lpstrFilter,offset szExtPe
		mov	@stOF.lpstrFile,offset szFileName
		mov	@stOF.nMaxFile,MAX_PATH
		mov	@stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
		invoke	GetOpenFileName,addr @stOF
		.if	! eax
			jmp	@F
		.endif
; 打开文件获得文件句柄
			invoke	CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ or \
			FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
		.if	eax !=	INVALID_HANDLE_VALUE
			mov	@hFile,eax
			invoke	GetFileSize,eax,NULL
			mov	@dwFileSize,eax
			.if	eax

;用获得的文件句柄建立文件mapping
				invoke	CreateFileMapping,@hFile,NULL,PAGE_READONLY,0,0,NULL
				.if	eax
					mov	@hMapFile,eax
					invoke	MapViewOfFile,eax,FILE_MAP_READ,0,0,0
					.if	eax
						mov	@lpMemory,eax
; 检测 PE 文件是否有效
						mov	esi,@lpMemory
						assume	esi:ptr IMAGE_DOS_HEADER
;检查MZ格式文件头
						.if	[esi].e_magic != IMAGE_DOS_SIGNATURE
							jmp	_ErrFormat
						.endif
						add	esi,[esi].e_lfanew
						assume	esi:ptr IMAGE_NT_HEADERS
;检查PE文件头
						.if	[esi].Signature != IMAGE_NT_SIGNATURE
							jmp	_ErrFormat
						.endif
						invoke	_ProcessPeFile,@lpMemory,esi,@dwFileSize
;获取路径及文件名
		invoke	lstrcpy,addr @szNewFile,addr szFileName		
		invoke	lstrlen,addr @szNewFile
;获取新文件名字符串的地址
		lea	ecx,@szNewFile
;eax是路径及文件名的长度,eax-4就是除去后面的.exe格式后的长度,然后再加上新文件的名字xxx_new.exe构成一个新的.exe文件。					
		mov	byte ptr [ecx+eax-4],0		
		invoke	lstrcat,addr @szNewFile,addr szExt
;复制文件内容,建立新文件成功。
		invoke	CopyFile,addr szFileName,addr @szNewFile,FALSE
;打开文件,获取句柄,并保存到@hFile变量中,以便后面使用。
		invoke	CreateFile,addr @szNewFile,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or \
			FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
		.if	eax ==	INVALID_HANDLE_VALUE
			invoke	SetWindowText,hWinEdit,addr szErrCreate
			jmp	_Ret
		.endif
		mov	@hFile,eax
		mov	esi,_lpPeHead
		assume	esi:ptr IMAGE_NT_HEADERS,edi:ptr IMAGE_NT_HEADERS
;分配内存空间
		invoke	GlobalAlloc,GPTR,[esi].OptionalHeader.SizeOfHeaders
		mov	@lpMemory,eax
		mov	edi,eax
;将PE文件头复制到新分配的内存中
		invoke	RtlMoveMemory,edi,_lpFile,[esi].OptionalHeader.SizeOfHeaders
;下面两句是为了让分配的内存指针指跳过DOS块,指向PE文件头。Edi是新分配内存的起始地址,esi是原文件的PE文件头,_lpFile是原文件的起始地址。
		add	edi,esi
		sub	edi,_lpFile
;确定两个指针
		movzx	eax,[esi].FileHeader.NumberOfSections
		dec	eax			;注意这减了1
		mov	ecx,sizeof IMAGE_SECTION_HEADER
		mul	ecx
;现在eax中的值是节的总大小减去一个节的大小
		mov	edx,edi
		add	edx,eax
		add	edx,sizeof IMAGE_NT_HEADERS
;现在edx指向最后一个节的开始
		mov	ebx,edx
		add	ebx,sizeof IMAGE_SECTION_HEADER
;现在ebx指向新加节的开始
		assume	ebx:ptr IMAGE_SECTION_HEADER,edx:ptr IMAGE_SECTION_HEADER
[ATTACH]67747[/ATTACH]

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (30)
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
2
沙发……ing
2012-5-28 13:12
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
3
挺详细的东西
2012-5-28 13:28
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
4
大家有什么问题可以提出来,一起分析讨论。
2012-5-28 13:48
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
5
前段时间毕业设计我是做PE的研究和加壳机的设计实现,也要做代码移植,对这个还是比较了解的!
2012-5-28 13:55
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
6
太长了,上课去了,回来有时间再看...........
2012-5-28 13:59
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
7
我还要等两年才做毕业设计啊。。
2012-5-28 16:14
0
雪    币: 59
活跃值: (1506)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
呵呵,有本书叫 《Windows PE权威指南 》,上面也有非常详细的介绍在pe中添加代码的章节
2012-5-28 18:53
0
雪    币: 602
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
还没看到,不知道有没有下载版本
2012-5-29 05:56
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
图不错~~~~
2012-5-29 09:09
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
11
谢谢推荐,有空去图书馆找找这本书。。
2012-5-29 09:42
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
12
MARK一下,幸苦了
2012-5-29 09:50
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
牛人,学习了!
2012-5-29 10:29
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
从没见过这么详细的东东 感谢楼主
2012-5-29 10:51
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
15
我也不常做思维导图,还没有用到思维导图的核心东西----图片
2012-5-29 18:21
0
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
太好了,有打包的哇,不知道可以写入多大的数据进去....
2012-5-29 20:03
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
17
mov        [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
invoke        WriteFile,@hFile,offset APPEND_CODE,[ebx].Misc.VirtualSize,\
                                addr @dwTemp,NULL
理论上应该可以写入足够大的数据,具体没有试过。
2012-5-29 20:46
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
不错

值得一看
2012-5-29 21:42
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
19
我也只是把我理解的写出来。。
2012-5-30 20:32
0
雪    币: 154
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
流程非常详细。楼主可以考虑在解释完所有流程后,画一个大致的流程图然后总结下使用了哪些API,好文一个,赞!
2012-5-31 11:33
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
21
嗯,这个建议好,下次再写东西的时候添上去。。
2012-5-31 18:22
0
雪    币: 3213
活跃值: (5439)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
有分析这个的精力还不如去自己看看别人的外壳代码,自己写个壳子呢
2012-6-5 01:49
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
23
正在研究外壳编写。。
2012-6-5 22:28
0
雪    币: 219
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
先顶后看,感谢LZ
2012-6-6 16:55
0
雪    币: 201
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
楼主 请问你的图使用什么软件画的
2012-6-9 11:22
0
游客
登录 | 注册 方可回帖
返回
//