| dong's profileThinking ...PhotosBlogLists | Help |
PE文件分析15导出函数节.edata 如果已知导出函数名,获取函数地址的步骤如下 下一步我准备用C++做一个读取PE中信息的程序 PE文件分析14idata节的起始地址是A4400H,长度实际有3000H,对齐后有竟然只有2800H,不能理解,我又看了几个多于一个字节exe这种情况还不少 他们各自的结构定义如下: typedef struct _IMAGE_IMPORT_BY_NAME { 数组的个数就是导入的DLL的个数。 PE文件中,所有DLL对应的导入地址数组在位置上排列在一起,全部这些数组的组合,称作导入地址表,FirstThunk指向导入地址表的起始地址。 PE文件实例分析12idata节的起始地址是A4400H,长度实际有3000H,对齐后有竟然只有2800H,不能理解,我又看了几个多于一个字节exe这种情况还不少 转到A4400H PE文件实例分析11节 虽然节表中对于节的 个数是确定的,数组大小也是定制的,但是在节表的后面到真正的节之前仍有一块区域全是零,这在test.exe中就是220h到400h之间的那一部分, 节的起始位置在节表中已经明确给出,PointerToRawData记录了这个节开始的位置,节对齐后的尺寸。由UE可见,有非零数据的部分仅仅是400h到41Eh这一小部分后面有一大部分0区,这是病毒藏身之所。 .text 代码节, .idata导入函数节 含有从其他DLL(kernel32.dll,user32.dll中导入的函数地址。 这个节的开始是一个IMAGE_IMPORT_DESCRIPTOR结构的数组,这就是导入地址表(IAT)即导入表。可惜test.exe中没有idata项。iceSword.exe中也没有,峰回路转,幸好我发现winrar安装文件中的WinRARr.exe中含有这个idata节,就那它来分析吧 PE文件实例分析10Characteristics: 代码节一般是60000020H 可读写,可执行,节中包含代码 数据节一般是:C0000040H 可读可写,包含已初始化数据 节属性的定义:来自微软VisualStudio2005 中winnt.h // // Section characteristics. // // IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. // IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. // IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. // IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. // IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. // IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved. #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. // 0x00002000 // Reserved. // IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000 #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. #define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP #define IMAGE_SCN_MEM_FARDATA 0x00008000 // IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 #define IMAGE_SCN_MEM_16BIT 0x00020000 #define IMAGE_SCN_MEM_LOCKED 0x00040000 #define IMAGE_SCN_MEM_PRELOAD 0x00080000
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // // Unused 0x00F00000 #define IMAGE_SCN_ALIGN_MASK 0x00F00000
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
喔 ,Section Table的作用是给所有的节提供一个便于PE装载器查找装载用的索引 下面讨论节 PE文件实例分析9节表是一个数组,其元素个数由IMAGE_FILE_HEADER中的NumberOfSections的值决定在test.exe中是0300,即3个 其中内含 image 的每一个sections 的信息 以下是微软VisualStudio2005 中winnt.h中的定义 // // Section header format. //
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
VirtualSize:本节实际字节数,计算文件对齐后的节尺寸 VirtualAddress PE装载器将该节映射到内存时会读取该值,地道内存中的位置 SizeOfRawData 值是200H与(与FileAlignment吻合)显然大于Misc本节的实际字节数目E1h,所以病毒可以不增加文件长度来感染文件。 PointerToRawData:节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中的位置病毒应该在此创建新值,指向新创建的节 PE文件实例分析8今天继续分析PE 下面到节表了(Section Table)
由上表可见节表是紧跟着PE文件头的一个结构 PE文件实例分析7AddresssOfEntryPoint 程序开始执行的地方,PE装载器准备运行的PE文件第一个指令的RVA,如果改变整个执行的流程,可以将该值指向新的RVA,新的RVA除的指令首选被执行,可以先保留原来的值,然后再跳转过来 ImageBase: PE文件的首选装载地址如果此处被占用,则另选其他空闲地址这个的值是00040000H SectionAlignment:内存中节对其的标准位置,内存中每个节起始地址都必须是这个值的倍数此例是0010 0000即1000H比如第一节是402000H,大小必然小于1000H比如20个字节,那么下一个节的起始地址必然是403000H FileAlignment:文件中节对齐的标准位置。文件中每个节的起始地址必须是这个值的倍数。此例是0002 0000 即00000200H,作用同上 SiezeOfImage:内存中PE文件的影响体的尺寸,是所有头,节处理对齐后的大小 SizeOfHeaders:所有的头,节表的和,SizeOfImage-文件中节的尺寸,这就是:PE文件第一节的偏移量了 Subsystem:此PE文件是窗体程序还是Console app。 此一可执行文件用来作为使用者接口的子系统。WINNT.H 定义了下列常数: NATIVE=1 不需要子系统(例如驱动程序) WINDOWS_GUI=2 在 Windows GUI 子系统中执行 WINDOWS_CUI=3 在 Windows 字符模式子系统中执行(也就是 console 应用程序) OS2_CUI=5 在 OS/2 字符模式子系统中执行(也就是 OS/2 1.x 应用程序) POSIZ_CUI=7 在 Posix 字符模式子系统中执行
数据目录表 以下是VisualStudio2005中winnt.h中的定义
// // Directory format. //
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 它的体积就是4×2×16即128个字节,在UE中占了8行 数据目录中各值的意义, 来自VisualStudio2005中winnt.h
// Directory Entries
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor 虽然定义了16个数组元素但是给出明确意义的只有前15个,难道最后一个保留备用?? 通过各项的VirturalAddress获取地址 在test.exe中的值是从0128h到1a8 如导入地址表即第13个元素,它的VirtualAddress是 0020 0000即2000h 它的Size是0800 0000即8h PE文件实例分析6
PE文件实例分析5映像文件头的大小: 从pe00开始的位置再偏移0x18个字节都是映像头的范围。 这样就可以计算出节表的起始位置,一个节表28H个字节,就可以进一步确定最后一个界节表的末尾的地址,这样就能添加新节了!--》有想法了!!
可选映像头:包含了PE文件的逻辑分布信息: 以下是VisualStudio2005中winnt.h中的定义 typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. //
WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData;
// // NT additional fields. //
DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
PE文件实例分析4PE文件头 Pe文件头标志:结构体的末尾,long e_lfanew 一个long型的四个字节的数据:pe00分别是图中0b0h,0b1h, ob2h,0b3h,
映像文件头以下是来自在微软的VisualStudio2005中winnt.h中的定义: typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; }; 对照UE中的数据:
(注意:WORD中的数字是反向存储的比如4C01,实际的表达的值是014C 这些值有特殊的意义: 机器类型Machine常见值:
如果我们要在文件中增加或者删除一个节,就要修改NumberOfSections 利用SizeOfOptionalHeader就可以知道节表的起始位置。 另一点要注意,这里的扎合理的文件创立的时间按并不是属性项里面的那个时间,而应该是PE文件被编译成的时间,因为文件被拷贝后,属性项里的时间会改变,这个时间是由磁盘文件表维护的。,但是文件中的时间信息并不改变
Characteristics中的值实际是:010F 它可以展开成0000000100001111从右到左依次称为bit0~bin15各自含义如下
PE文件实例分析3
作成test.exe文件,然后对照pe文件的结构分析 第一部分是DOS头 MZ文件头从0x00到0x3f共是 占了64(10)个字节 (注:四个字节等于一个双字,两个字节一个字,一个字节8个bit ,UE中一行是16个半字节即八个字节。)前四行都是MZ文件头 MS-DOS头是一个结构体,在微软的VisualStudio2005中winnt.h中的定义 typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } WORD e_magic 就是0x4D5A即我们在UE中看到的MZ两个字母的十六进制形式
将UE中的实际数据和结构体对照在一起看
观察对比多个程序发现插桩程序的字符出现位置是固定的,而pe00这个标志出现的位置不是固定的,固定的只是记录这个标志的变量的位置, 注意:DWORD中的数字是反向存储的比如上面的F800 0000,实际的表达的值是 0000 00F8,这就与UE中显示的PE00字符的出现位置对应起来了 更典型的如果UE中显示某个DWORD是1234 5678,那么实际的值是:7856 3412 上面表格中的e_lfarlc 的值其实是00 40,这就是重定向表的地址了! 学过汇编的人可能对此有点印象
中间从0x3c到pe头位置是一个dos插桩程序,其长度用e_lfanew-3f即可 以上构成了DOS头,
PE文件实例分析2
作成test.exe文件,然后对照pe文件的结构分析 PE文件实例分析1今天开始分析pe文件 虚地址VA=相对虚拟地址RVA+基地址Image Base 基地址是可执行文件映射到内存中的基地址 我先用汇编写成了一个很小的一个文件故意把它写的非常小,以便于分析,麻雀虽小,五脏俱全!
.386 .MODEL FLAT ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD .DATA number1 DWORD 10 number2 DWORD 100 sum DWORD ? .CODE _start: mov eax, number1 add eax, number2 mov sum, eax
INVOKE ExitProcess, 0 PUBLIC _start END 以下是这个程序的可执行文件的二进制信息 装SUSE我敢说OPENSuSE 10.2是我装过的界面最好的linux版本,比Ubuntu还要好一点,
而且还有一个比Ubuntu好一点的地方,那就是SuSE自带很多工具,不用再去网上四处搜索下载了,而Ubuntu精简的没什么其他功能了
则一点对我们这种喜欢探索尝鲜的人是很没有吸引力的.
上个学期有一段时间也曾经试图装过,但是当时我是直接安装,结果显式器不支持,我只能进入一个控制台界面,
现在改变策略,用虚拟机安装的满是慢了点但是总比不能用好啊 DDKBuild: 在Visual Studio中集成DDK初学驱动,搭建这个配置环境就让人无从着手,Google了几天后,终于找到一种可以在Visual Studio 中集成DDK的方案。 在Google中搜 ddkBuild,单击链接可以转到 把DDKBuild.bat DDKBuild.cmd,DDKBuildWizard.exe还有一个PDF格式的帮助文档下载下来。 仔细阅读那个罗里罗嗦的文档后就知道怎么做了 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|