最近老是盯着PE文件看,看它有什么秘密在里面,于是就产生了这样一个想法:构造一个PE头,构造自己的区段表,接着在.text中填一些机器码,当然还要构造自己的输入表,我想通过这种方式来实现一个程序.下面就是我的操作过程:
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
(-),首先构造一个PE头
->DOS Header
e_magic: 0x5A4D
e_cblp: 0x0000
e_cp: 0x0000
e_crlc: 0x0000
e_cparhdr: 0x0000
e_minalloc: 0x0000
e_maxalloc: 0x0000
e_ss: 0x0000
e_sp: 0x0000
e_csum: 0x0000
e_ip: 0x0000
e_cs: 0x0000
e_lfarlc: 0x0000
e_ovno: 0x0000
e_res: 0x0000000000000000
e_oemid: 0x0000
e_oeminfo: 0x0000
e_res2: 0x0000000000000000000000000000000000000000
e_lfanew: 0x00000040
->File Header
Machine: 0x014C (I386)
NumberOfSections: 0x0001
TimeDateStamp: 0x45B9CD97 (GMT: Fri Jan 26 09:44:55 2007)
PointerToSymbolTable: 0x00000000
NumberOfSymbols: 0x00000000
SizeOfOptionalHeader: 0x00E0
Characteristics: 0x010F
(RELOCS_STRIPPED)
(EXECUTABLE_IMAGE)
(LINE_NUMS_STRIPPED)
(LOCAL_SYMS_STRIPPED)
(32BIT_MACHINE)
->Optional Header
Magic: 0x010B (HDR32_MAGIC) ;书上说一般都是这个值
MajorLinkerVersion: 0x05
MinorLinkerVersion: 0x0C -> 5.12 ;好多程序都是这个值
SizeOfCode: 0x00000200 ;通常情况下和.text块的大小匹配
SizeOfInitializedData: 0x00000200
SizeOfUninitializedData: 0x00000000
AddressOfEntryPoint: 0x00001000
BaseOfCode: 0x00001000
BaseOfData: 0x00002000
ImageBase: 0x00400000
SectionAlignment: 0x00001000 ;这个值是最小的了
FileAlignment: 0x00000200 ;这个也是
MajorOperatingSystemVersion: 0x0004
MinorOperatingSystemVersion: 0x0000 -> 4.00
MajorImageVersion: 0x0000
MinorImageVersion: 0x0000 -> 0.00
MajorSubsystemVersion: 0x0004
MinorSubsystemVersion: 0x0000 -> 4.00
Win32VersionValue: 0x00000000 ;Reserved,以上都是常见的值
SizeOfImage: 0x00003000 //内存镜象大小
SizeOfHeaders: 0x00000200 ;从文件的开头到第一节的原始数据的偏移量
CheckSum: 0x00000000
Subsystem: 0x0002 (WINDOWS_GUI)
DllCharacteristics: 0x0000
SizeOfStackReserve: 0x00100000 ;以下的数据都是程序中常见的
SizeOfStackCommit: 0x00001000
SizeOfHeapReserve: 0x00100000
SizeOfHeapCommit: 0x00001000
LoaderFlags: 0x00000000
NumberOfRvaAndSizes: 0x0000000F
DataDirectory (F) RVA Size
------------- ---------- ----------
ExportTable 0x00000000 0x00000000
ImportTable 0x00002000 0x0000003C
Resource 0x00000000 0x00000000
Exception 0x00000000 0x00000000
Security 0x00000000 0x00000000
Relocation 0x00000000 0x00000000
Debug 0x00000000 0x00000000
Copyright 0x00000000 0x00000000
GlobalPtr 0x00000000 0x00000000
TLSTable 0x00000000 0x00000000
LoadConfig 0x00000000 0x00000000
BoundImport 0x00000000 0x00000000
IAT 0x00000000 0x00000000
DelayImport 0x00000000 0x00000000
COM 0x00000000 0x00000000
Reserved 0x00000000 0x00000000
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
(二)下面到块表了(剩下那些字段全部填0了)。。
Name VSize VAddress RSize Roffset characterstics
.TEXT 526 1000 200 200 60000020
.RDATA 592 2000 200 400 E0000040
接着就是我自己的代码了,当然是最简单的!
我把数据也放到.RDATA区段。
这些代码很多我是借住OD查看得来的(先写代码,在OD打开)
'pediy' 5B0------004021B0
'http://pediy.com' 5C1------004021C1
PUSH 0 6A00
push 'http://pediy.com' 68 C1214000 //指向http://pediy.com
PUSH 'pediy' 68 B0214000
push 0 6A00
call MessageBoxA E8 07000000 //也就是向前跳7个字节吧
push 0 6A00
call ExitProcess E8 06000000
jmp MessageBoxA FF25 B0204000 //跳到IMAGE_THUNK_DATA
jmp ExitProcess FF25 B8204000
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
(三)程序中引入了两个函数,这就得为它构造两个IID。。。。
MessageBoxA 44c--->204c----0040204c
ExitProcess 466--->2066--->00402066
User32.dll 45A--->205A--->0040205A
Kelnel32.dll 474--->2074--->00402074
IMAGE_THUNK_DATA (把它放在了地址4B0,4B8处)
B0200000 00000000 以0结束
B8200000 00000000
IMAGE_IMPORT_DIRECTORY
OrignFirstThunk TimeDateStamp ForWarderChain Name1 FirstThunk
00000000 00000000 00000000 5a200000 B0200000
00000000 00000000 00000000 74200000 B8200000
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
(四)将这些数据保存为pediy.exe
,结果见附件,都是我自己构造的数据,你可以用二进制编辑工具打开
再次感谢dummy
- 标 题: 一次PE文件之旅
- 作 者:小娃崽
- 时 间:2007-01-28 12:50
- 附 件:pediy.rar
- 链 接:http://bbs.pediy.com/showthread.php?t=38689