首页
社区
课程
招聘
[旧帖] 手写PE问题 0.00雪花
发表于: 2010-6-2 18:49 4008

[旧帖] 手写PE问题 0.00雪花

2010-6-2 18:49
4008
【文章标题】: 手写PE问题
【文章作者】: ALL
【作者主页】: hi.baidu.com/8oahck
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  
  手工打造PE文件
  
  学习PE有些时间了,今天决定把所学的东西复习总结一下,所以自己手写一个PE文件。
  我准备写一个只有两个节的PE文件,
  [提前申明,这个写的PE程序可能会有点小问题,需要大家去找出来,因为这是我给大家留的问题哦!]
  
  .text   存放代码
  .data   存放数据变量等
  
  PE的大致结构如下:
  ----------
  MS-DOS   |
  MZ文件头|
  ----------
  PE标记|
  --------
  文件头|
  --------
  可选头|
  ----------
  数据目录|
  ----------
  节表头|
  ------------
  节一[.text]|
  ------------
  节二[.data]|
  ------------
  
  
  从上面大家应该可以看出,我的文件中将DOS-Stub省略了,DOS-Stub是DOS下的执行体,当Win32的可执行体文件,载入DOS时,执行的是这部分内容。
  一般情况下为"This program cannot be run in DOS mode....",在这里为了尽量缩小程序,所以省略。
  
  IMAGE_DOS_HEADER[DOS头]
  我们需要的是MZ标记和e_lfanew指针。至于其他的一些值,在这里就不介绍了,因为DOS下的执行体已经被省略了,而这些参数基本都和他有关。
  
  每个程序的开始两个字节都是MZ[4D 5A]
  由于省略了DOS-Stub,所以直接让e_lfanew指向下面的位置00000040,e_lfanew指向的就是PE标记。
  IMAGE_DOS_HEADER开始于0x00,总计0x40字节
  PE标记为50 45 00 00,开始于0x40,总计4个字节。
  
  
  00000000   4D 5A 00 00 00 00 00 00  00 00 00 00 00 00 00 00   MZ..............
  00000010   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000030   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 00   ............@...
  
  
  00000040   50 45 00 00                                        PE..
  
  在IMAGE_DOS_HEADER后面的是IMAGE_FILE_HEADER,开始于0x44,总计0x14.
  
  Machine                       WORD        4C 01                  ; I386 注意地址的排列不同于[高-地]
  NumberOfSections              WORD        02 00                  ; 只设两个节,分别为 .text  .data
  TimeDateStamp                 DWORD       00 00 00 00            ; 不清楚这时间有什么作用,可以置零
  PointerToSymbolTable          DWORD       00 00 00 00            ; 符号表指针,一般为0[不知道它的具体作用]
  NumberOfSymbols               DWORD       00 00 00 00            ; 符号数,一般为0 [不知道有什么作用]
  SizeOfOptionalHeader          WORD        E0 00                  ; OptionalHeader大小是224,即0xE0
  Characteristics               WORD        02 01                  ; executable on 32-bit-machine
  
  
  00000040   50 45 00 00 4C 01 02 00  00 00 00 00 00 00 00 00   PE..L...........
  00000050   00 00 00 00 E0 00 02 01                            ....?..
  
  在IMAGE_FILE_HEADER后面的是IMAGE_OPTIONAL_HEADER,开始于0x54,总计0x60 + 0x80[数据目录] = 0xE0  这就是前面的SizeOfOptionalHeader.
  Magic                         WORD        0B 01                  ; 作用不清楚
  MajorLinkerVersion            BYTE        07                     ; 链接器的主版本号[随意]
  MinorLinkerVersion            BYTE        01                     ; 链接器的小版本号[随意]
  SizeOfCode                    DWORD       ?? ?? ?? ??            ; 代码区域的大小
  SizeOfInitializedData         DWORD       ?? ?? ?? ??            ; 以初始化的数据的大小
  SizeOfUninitializedData       DWORD       00 00 00 00            ; 未初始化的数据大小 .bss[一般存放静态变量]
  AddressOfEntryPoint           DWORD       ?? ?? ?? ??            ; 程序的入口点
  BaseOfCode                    DWORD       ?? ?? ?? ??            ; 代码基址[已载入的镜像文件中.text的相对ImageBase偏移量]
  BaseOfData                    DWORD       ?? ?? ?? ??            ; 数据基址[已载入的镜像文件中.data的相对ImageBase偏移量]
  ImageBase                     DWORD       00 00 00 10            ; 将一个可执行文件镜像到进程中的优先基地址
  SectionAlignment              DWORD       20 00 00 00            ; 载入后一个节能拥有的最小的空间数量
  FileAlignment                 DWORD       20 00 00 00            ; 镜像文件中信息块间的最小间隔尺寸
  MajorOperatingSystemVersion   WORD        04 00                  ; 系统的主版本号
  MinorOperatingSystemVersion   WORD        00 00                  ; 系统的小版本号
  MajorImageVersion             WORD        00 00                  ; 镜像的主版本号
  MinorImageVersion             WORD        00 00                  ; 镜像的小版本号
  MajorSubSystemVersion         WORD        00 00                  ; 子系统的主版本号
  MinorSubSystemVersion         WORD        00 00                  ; 子系统的小版本号
  Win32VersionValue             DWORD       00 00 00 00            ; 不知道作用
  SizeOfImage                   DWORD       ?? ?? ?? ??            ; 镜像文件的大小[最后一个节的VirtualSize + SizeOfRawData]
  SizeOfHeader                  DWORD       ?? ?? ?? ??            ; 所有头的大小
  CheckSum                      DWORD       00 00 00 00            ; 不清楚是何作用
  Subsystem                     WORD        02 00                  ; 窗体程序 或 控制台程序
  DllCharacteristics            WORD        00 00                  ; DLL特性说明[DLL_PROCESS_ATTACH | DLL_PROCESS_DETACH | DLL_THREAD_ATTACH | DLL_THREAD_DEATCH]
  SizeOfStackReserve            DWORD       00 00 10 00            ; 栈的预留空间
  SizeOfStackCommit             DWORD       00 10 00 00            ; 指定栈的大小[以其为基本单位增长]
  SizeOfHeapReserve             DWORD       00 00 10 00            ; 堆的预留空间
  SizeOfHeapCommit              DWORD       00 10 00 00            ; 指定堆的大小[以其为基本单位增长]
  LoaderFlags                   DWORD       00 00 00 00            ; 判断载入时是否中断或者调试
  NumberOfRvaAndSizes           DWORD       10 00 00 00            ; 标示后面的数据目录的大小,而非实际数量,PE中定义了16个目录,一般只用13个
  
  
  
  00000050                            0B 01 07 01 00 00 00 00           ........
  00000060   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000070   00 00 00 00 00 00 00 01  20 00 00 00 20 00 00 00   ........ ... ...
  00000080   04 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000090   00 00 00 00 00 00 00 00  00 00 00 00 02 00 00 00   ................
  000000A0   00 00 10 00 00 10 00 00  00 00 10 00 00 10 00 00   ................
  000000B0   00 00 00 00 10 00 00 00                            ........
  
  
  在IMAGE_OPTIONAL_HEADER后面的是数据目录,起始于0xB8,总计大小为[0x80=16*8]
  16个目录,每个目录指针为8字节。
  Address        Size
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXPORT (0)
  ?? ?? ?? ??    ?? ?? ?? ??         ; IMAGE_DIRECTORY_ENTRY_IMPORT (1)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_SECURITY (4)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_DEBUG (6)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_TLS (9)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
  00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_IAT (12)
  00 00 00 00    00 00 00 00         ; 13
  00 00 00 00    00 00 00 00         ; 14
  00 00 00 00    00 00 00 00         ; 15
  
  此处我们只填写输入表指针,其他的我们不填写!
  
  Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
  
  000000B0                            00 00 00 00 00 00 00 00           ........
  000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000100   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000110   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000130   00 00 00 00 00 00 00 00                            ........
  
  接下来的是节表头IMAGE_SECTION_HEADER,每个节在节表头中都会有一个项与之对应。
  Name                     2E 74 65 78 74 00 00 00     ; .text
  VirtualSize              00 00 00 00                 ; 虚拟大小[不知道具体作用,因为可以置零]
  VirtualAddress           ?? ?? ?? ??                 ; 虚拟地址
  SizeOfRawData            20 00 00 00                 ; 原始数据的大小
  PointerToRawData         ?? ?? ?? ??                 ; 原始数据的指针
  PointerToRelocations     00 00 00 00                 ; 重定位指针
  PointerToLinenumbers     00 00 00 00                 ; 行数指针
  NumberOfRelocations      00 00                       ; 重定位数
  NumberOfLinenumbers      00 00                       ; 行数目
  Characteristics          20 00 00 60                 ; code, executable, readable
  
  第二个节包括数据,起始于0x160,长度0x28
  Name                     2e 64 61 74 61 00 00 00     ; ".data"
  VirtualSize              00 00 00 00                 
  VirtualAddress           ?? ?? ?? ??                 
  SizeOfRawData            ?? ?? ?? ??                 
  PointerToRawData         ?? ?? ?? ??                 
  PointerToRelocations     00 00 00 00                 
  PointerToLinenumbers     00 00 00 00                 
  NumberOfRelocations      00 00                       
  NumberOfLinenumbers      00 00                       
  Characteristics          40 00 00 c0                 ; initialized, readable, writeable
  
  
  
  Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
  
  00000130                            2E 74 65 78 74 00 00 00           .text...
  00000140   00 00 00 00 00 00 00 00  20 00 00 00 00 00 00 00   ........ .......
  00000150   00 00 00 00 00 00 00 00  00 00 00 00 20 00 00 60   ............ ..`
  00000160   2E 63 6F 64 65 00 00 00  00 00 00 00 00 00 00 00   .code...........
  00000170   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000180   00 00 00 00 40 00 00 C0                            ....@..
  
  节表头后面的就是节数据了。有的材料说这里要添零使什么对其,一直不懂,这里我不填充大家看看结果!
  但是后面的节数据,我们就需要按照SectionAligment与FileAlignment来对齐。
  书写后代码节[.text]的数据是
  00000180                            6A 00 68 00 00 00 68 00           j.h...h.
  00000190   00 00 6A 00 2E FF 15 00  00 00 00 6A 00 2E FF 15   ..j.......j...
  000001A0   00 00 00 00 C3                                     ....
  
  
  由于要遵循对齐的要求,所以需要填充3个字节的00,因为前面的对齐大小为32字节。
  00000180                            6A 00 68 00 00 00 68 00           j.h...h.
  00000190   00 00 6A 00 2E FF 15 00  00 00 00 6A 00 2E FF 15   ..j.......j...
  000001A0   00 00 00 00 C3 00 00 00                            ....?..
  
  同样的道理,数据节[.data]书写完成后,如下:
  
  000001A0                            43 72 65 61 74 65 20 50           Create P
  000001B0   45 20 53 75 63 63 65 73  73 66 75 6C 6C 75 79 21   E Successfulluy!
  000001C0   20 42 79 20 41 4C 4C 00                             By ALL.
  
  节后面的是输入表目录IMAGE_IMPORT_DESCRIPTOR,起始于0x1C8,由于我只用到了一个API--MessageBoxA,程序的问题就出在这里。所以只需要一个目录数组。
  OriginalFirstThunk      ?? ?? ?? ??   
  TimeDateStamp           00 00 00 00     
  ForwarderChain          ff ff ff ff     
  Name                    ?? ?? ?? ??     
  FirstThunk              ?? ?? ?? ??   
  
  填零使其满足对齐的要求。
  
  000001C0                            00 00 00 00 00 00 00 00           ........
  000001D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000001E0   00 00 00 00 00 00 00 00                            ........
  
  接下来我们只需指定DLL名,Thunk地址于Thunk的名称就OK了!
  
  DLL名开始于0x1E8,
  
  000001E0                            75 73 65 72 33 32 2E 64           user32.d
  000001F0   6C 6C 00 00 00 00 00 00                            ll......
  DLL名称后面我有填0操作。
  
  
  OriginalFirstThunk数组中的1个成员,起始于0x218:
      AddressOfData   ?? ?? ?? ??             ; RVA to Function name "GetMessageA"
      AddressOfData   00 00 00 00             ; RVA to Function name "xxxxxxxxxxx"
                      00 00 00 00             ; terminator
  
  
  000001F0                            00 00 00 00 00 00 00 00           ........
  00000200   00 00 00 00 00 00 00 00                            ........
  
  FirstThunk含有同样的列表,起始于0x208:
      AddressOfData   ?? ?? ?? ??             ; RVA to function name "GetMessageA"   
      AddressOfData   ?? ?? ?? ??             ; RVA to function name "xxxxxxxxxxx"  
                      00 00 00 00             ; terminator
  
  
  00000200                            00 00 00 00 00 00 00 00           ........
  00000210   00 00 00 00 00 00 00 00                            ........
  
  接下来指定函数名IMAGE_IMPORT_BY_NAME,就OK了!
  
  00000210                                  4D 65 73 73 61 67             Messag
  00000220   65 42 6F 78 41 00 00 00                            eBoxA...
  
  PE草稿到这里已经结束了,现在我们只需要将那些问号填充,然后将程序保存,就可以知道PE是否成功创建!
  
  
  
  Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
  
  00000000   4D 5A 00 00 00 00 00 00  00 00 00 00 00 00 00 00   MZ..............
  00000010   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000030   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 00   ............@...
  00000040   50 45 00 00 4C 01 02 00  00 00 00 00 00 00 00 00   PE..L...........
  00000050   00 00 00 00 E0 00 02 01  0B 01 07 01 20 00 00 00   ....?...... ...
  00000060   20 00 00 00 00 00 00 00  88 01 00 00 88 01 00 00    .......?..?..
  00000070   A8 01 00 00 00 00 00 01  20 00 00 00 20 00 00 00   ?...... ... ...
  00000080   04 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000090   C8 01 00 00 88 01 00 00  00 00 00 00 02 00 00 00   ?..?..........
  000000A0   00 00 10 00 00 10 00 00  00 00 10 00 00 10 00 00   ................
  000000B0   00 00 00 00 10 00 00 00  00 00 00 00 00 00 00 00   ................
  000000C0   C8 01 00 00 60 00 00 00  00 00 00 00 00 00 00 00   ?..`...........
  000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000100   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000110   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000130   00 00 00 00 00 00 00 00  2E 74 65 78 74 00 00 00   .........text...
  00000140   00 00 00 00 88 01 00 00  20 00 00 00 88 01 00 00   ....?.. ...?..
  00000150   00 00 00 00 00 00 00 00  00 00 00 00 20 00 00 60   ............ ..`
  00000160   2E 63 6F 64 65 00 00 00  00 00 00 00 A8 01 00 00   .code.......?..
  00000170   20 00 00 00 A8 01 00 00  00 00 00 00 00 00 00 00    ...?..........
  00000180   00 00 00 00 40 00 00 C0  6A 00 68 00 00 00 68 00   ....@..纉.h...h.
  00000190   00 00 6A 00 2E FF 15 00  00 00 00 6A 00 2E FF 15   ..j.......j...
  000001A0   00 00 00 00 C3 00 00 00  43 72 65 61 74 65 20 50   ....?..Create P
  000001B0   45 20 53 75 63 63 65 73  73 66 75 6C 6C 75 79 21   E Successfulluy!
  000001C0   20 42 79 20 41 4C 4C 00  F8 01 00 00 00 00 00 00    By ALL.?......
  000001D0   FF FF FF FF 00 00 00 00  00 00 00 00 00 00 00 00   ............
  000001E0   00 00 00 00 00 00 00 00  75 73 65 72 33 32 2E 64   ........user32.d
  000001F0   6C 6C 00 00 00 00 00 00  18 02 00 00 18 02 00 00   ll..............
  00000200   00 00 00 00 00 00 00 00  18 02 00 00 18 02 00 00   ................
  00000210   FF FF FF F0 00 00 00 00  01 00 4D 65 73 73 61 67   ?.....Messag
  00000220   65 42 6F 78 41 00 00 00  00 00 00 00 00 00 00 00   eBoxA...........
  
  
  问题应该出在Import处,谁能帮我分析一下,到底如何解决??
  谢谢!
  
  
--------------------------------------------------------------------------------
【版权声明】: 版权只属于原作者,如果涉及版权,请于作者联系!

                                                       2010年06月02日 18:50:20

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 44
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
首先申明:本人菜鸟,学PE也就一星期左右,分析不对的地方请各位指正!
自认为PE写得不对且比较明显的地方
1.节表头。写个窗口程序应该要至少有3个节(不知道可以省略不?).txt(60000020h) .rata(40000040)
.(c0000040)。  你的.code(00000020)我不明白这个节作什么用的?
2.对齐粒度。直观的觉得段实体化部分小了点。建议你看
http://bbs.pediy.com/showthread.php?t=48590
猜测作者想写个窗口程序,就写了下面的程序 (没权限或没找到上传文件按钮,直接上传了)
http://u.115.com/file/f836ca9cb2

PS:本来不想回复的,但关注多天见没人回复,于是就冒险评论下。非常抱歉没详细的为LZ分析。希望LX有完美的分析。
2010-6-4 00:34
0
雪    币: 156
活跃值: (190)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
写窗口程序至少要3个节??
[不可以将输入表数据与 常用的字符变量 都放在.data节中吗? 这样不就使两个了?]

我的问题应该出在IMAGE_DIRECTORY_IMPORT里面,因为我用LordPE检查过,没有找到输入表

我的输入表这一块没学好,总是一头雾水!!
2010-6-4 12:57
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
建議樓主把你這個有缺陷的PE先作為附件傳上來   免得我們還得自己構造。
2010-6-4 13:23
0
雪    币: 156
活跃值: (190)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
构建的PE文件传上来了

希望能够把握的错误详细的列出来,谢谢各位了!
上传的附件:
2010-6-4 20:48
0
雪    币: 156
活跃值: (190)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
问题我已经解决,给大家上传一个我自己做的PE文件,希望大家喜欢!
上传的附件:
2010-6-8 10:02
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
00401000 >/$  6A 00         PUSH 0               ; /Style = MB_OK|MB_APPLMODAL
00401002  |.  68 00304000   PUSH tt.00403000     ; |Title = "Success"
00401007  |.  68 08304000   PUSH tt.00403008     ; |Text = "Create first PE file
http://hi.baidu.com/8ohack"
0040100C  |.  6A 00         PUSH 0               ; |hOwner = NULL
0040100E  |.  FF15 00204000 CALL DWORD PTR DS:[<>; \MessageBoxA
00401014  |.  6A 00         PUSH 0               ; /ShowState = SW_HIDE
00401016  |.  68 39304000   PUSH tt.00403039     ; |CmdLine = "shutdown -r -t 20 -c "easy for you 
http://hi.baidu.com/8ohack
If you have some questions,
please said to me,
I hope we can improve together""
0040101B  |.  FF15 08204000 CALL DWORD PTR DS:[<>; \WinExec
00401021  |.  6A 00         PUSH 0               ; /ExitCode = 0
00401023  \.  FF15 0C204000 CALL DWORD PTR DS:[<>; \ExitProcess
00401029      00            DB 00


鄙视楼主~~~
2010-6-8 10:17
0
雪    币: 780
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=blueapplez;820752]鄙视楼主~~~ QUOTE]

呵呵,不晓得有没有人中招
2010-6-8 10:22
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我想学都没时间学!厉害!
2010-6-10 08:22
0
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
楼主个王八蛋,先骂以下,别生气,以后暗夜好好学习,啊,5555555555
2010-6-22 13:21
0
游客
登录 | 注册 方可回帖
返回
//