macair 暗组
题记:写给看到的高手们
一个人的技术永远只是一个人的技术,永远只会死在暂时满足的襁褓里,强烈建议高手共享信息,知识的贫穷让我等菜鸟无法呼吸,带带我们的菜鸟吧!
这个JB学校真的让我快疯了,沉痛悼念死去的学生!但愿人们不要在自己的职责里玩社会工程学!这是一个需要责任的年代!
因为能力问题可能写的有错误,大家心情讨论!
一:PE结构基础
1:几个地址的概念
VA:虚拟地址,也就是内存中的地址!
RVA:相对虚拟地址,等于VA-ImageBase
Offset:物理地址,磁盘上文件的地址,等于RVA-ImageBase-节偏移!
PE装入器:程序需要装入内存后才可以运行,PE装入器就是为了装入PE文件
装入:装入是将磁盘上程序的指令数据转的地址载入内存并进行地址转换的过程!
连接:连接是将多个OBJ文件制作成可供PE装载器装入模块的过程!
2:OD中的地址为什么是虚拟地址
3:DLL文件是怎么来的
最早使用库的方法就是STATIC LINKING,静态连接方式,这与动态的连接的根本区别在于前者每个程序都有一个库COPY,而动态连接只会有一个库的引用说明,并没有将库连接的时候写进每一个程序,所以WINDOWS缺少DLL文件的时候,某些程序会不能执行,这时候PE装入器会自动告诉我们,而且是运行程序时候的才报错,显然这说明Windows的DLL文件是一种运行时动态连接的工作方式!
三:PE结构
1:整体结构
IMAGE_DOS_HEADER
DOS_STUB
IMAGE_NT_HEADERS
IMAGE_SECTION_HEADER
SECTION 1
SECTION 2
SECTION ……
SECTION N
IMAGE_DOS_HEADER
这是DOS产物,因为PE结构产生的时候比较早,第一个WINDOWS是运行在DOS环境中的,所以为了和DOS兼容PE结构引入了这个东东!
IMAGE_DOS_HEAER只有两个比较有效,一个是大家熟知的MZ,它在编程的时候称为e_magic,还有一个就是e_lfanew,也就是用C32ASM打开PE文件时候对应的3c处,它指向的是IMAGE_NT_HEADER的offset,是一个地址!好了,对于IMAGE_DOS_HEADER的东东就说这些,
DOS_STUB是一个DOS下标准的EXE文件,类似于用MASM写的DOS APP!
这两个东东因为用处不大,所以常被我们用于修改PE头,目的是为了防调试、免杀、保存输入表等等! PE变形技术是一种有意思的东东,而IMAGE_DOS_HEADER与IMAGE_NT_HEADER的重叠又是最常见的!
IMAGE_NT_HEADERS 248 Byte
通过它的名字我们就知道这里面还有HEADER,因为它是一个HEADERS,那么有什么?
它包括三部分,IMAGE_NT_SIGNATURE IMAGE_FILE_HEADER IMAGE_OPTINAL_HEADER
IMAGE_FILE_HEADER 这个是定位物理信息
IMAGE_OPTIONAL_HEADER 这个是定位内存信息,所以这里一般都是一些RVA地址!
IMAGE_FILE_HEADER 20字节
IMAGE_OPTIONAL_HEADER
AddressOfEntryPoint:程序的入口点,这个大家比较熟悉,免杀的最后一步
ImageBase :基址,上面我在基本概念中作了说明
SectionAligment :内存对齐粒度(这个用GetSystemInfo()就可以找到
FileAlignment:文件对齐粒度(碰到陌生名字,就把它们当成美女的名字,多记几次就成了熟人了)
SizeOfImage:内存中的镜象大小
SizeOfHeaders:所有的头大小,这个可以通过IMAGE_BASE+SIZEOF_HEADERS来定位IMAGE_SECTION_HEADER的位置
DataDirectory:目录,这里面保存的是需要操作系统提供的东东比如DLL文件有128个字节
IMAGE_DOS_HAEDER的e_lfanew定位到了IMAGE_NT_HEADER的物理偏移,IMAGE_FILE_HEADER的NumberOfSecion指出节表结构数组的大小,同时指出为Opional_Header的大小!
OPTIONAL_HEADER指明了程序第一个要载入的地址,指明了它载入哪,指明了其它指令以多大单位来载入,上面只是初步工作,它与IMAGE_SECTION_HEADER的联系,再于如何找定位IMAGE_SECTION_HEADER的位置!有e_lfanew找到了IMAGE_NT_HEADERS,有IMAGE_NT_HEADERS的最后一个头也就是IMAGE_OPTIONAL_HEADER指明了IMAGE_SECTION_HEADER的地址!
好了,好像写的有点乱,下面让大家记住这些位置!要记住这些位置只要记住两个数字,16和32
IMAGE_NT_SIGNATURE也就是PE,这两个字符是PE头开始的标志!找到它你就找到了IMAGE_NT_HEADER的起始!
后面20个字节就是IMAGE_FILE_HEADER的内容,下面说重点,从IMAGE_FILE_HEADER起
加16个字节,就是AddressOfEntryPoint
加32个字节
从FileAlignment开始,大家注意这里不是从IMGA_FILE_HEADER的结尾算了,从FileAlignment开始加16个字节就是SizeOfImage,后面接的就是SizeOfHeaders!
相信记住16和32你就记住了大部分的内容!
对于DataDirectory它是128个字节,当你看到.text或者是.code节的时候,回推128个字节就是DataDirectory了!
IMAGE_DATA_DIRECTORY
IMAGE_IMPORT_DESCRIPOR的主要内容如下
OrignalThunk HNT的RVA
FirstThunk IAT的RVA
Name DLL文件名的RVA
太累了,写东西就是麻烦,大家明白这里面的值都是RVA就可以了,这个RVA指向的并是DLL中导出函数的RVA,它们指向一个IMAGE_DATA_THUNK的结构,这个结构保存了导入函数的RVA,也就是说要定位一个DLL文件中的函数,必须经历三次RVA才可找到!
IMAGE_SECTION_HEADER
VirtualAddress:这个是LORDPE中的Roffset的地址
PointToRawData:这个是LORDPE中的Voffset的地址
VirtualSize:是内存中的大小,除以上面说的粒度就知道需要几个基本功能单位了
SizeOfRawData:这个文件中的大小,除以上面说的文件粒度就知道有几个基本功能单位了!
它的作用是计算节偏移!
#include <windows.h>
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{