设为主页 | 加入收藏 | 繁體中文

PE学习


  SizeOfStackCommit      0x1000    ;
  SizeOfHeapReserve      0x100000  ;
  SizeOfHeapCommit      0x1000    ;
  LoaderFlags          0x0
  NumberOfRvaAndSizes    0x10    ;总是这个值,下面有几多个目录
  ----------------------------------------
  数据目录部分
  Directory 0
  Size              0x0
  VirtualAddress        0x0
  ----------------------------------------
  Directory 1
  Size              0xb0    ;任意写 0x0~0xFF FF FF FF都可以
  VirtualAddress        0x2020    ;两个字符串0x20总够了吧
  ----------------------------------------
  .                    ;还有14个,全是0
  .
  .
  ----------------------------------------
  区段头
  Section  0
  Name            .code    ;区段的名字
  VirtualAddress        0x1000    ;内存中的地位
  SizeOfRawData        0x20    ;任意写 0x1~0x10 00都可以
  PointerToRawData      0x200    ;文件中的地位
  PointerToRelocations      0x0
  PointerToLinenumbers      0x0
  NumberOfRelocations      0x0
  NumberOfLinenumbers    0x0
  Characteristics        0x6000002  ;具体看pe说明
  ----------------------------------------
  Section  1
  Name            .data    ;区段的名字
  VirtualAddress        0x2000    ;内存中的地位
  SizeOfRawData        0xc0    ;写大一点就可以了
  PointerToRawData      0x400    ;文件中的地位
  PointerTToRelocations      0x0
  PointerToLinenumbers      0x0
  NumberOfRelocations      0x0
  NumberOfLinenumbers    0x0
  Characteristics        0xc000004  ;具体看pe说明
  ----------------------------------------
  关于“任意写”的中央,都是size。
  看来.code段无所谓size,别超过段大小就行。
  .data段就不行,不能少,但可以多,能多几多就要看文件的大小。
  SizeOfCode          0x20    ;任意写 0x0~0xFF FF FF FF都可以
  SizeOfInitializedData      0xd0    ;任意写 0x0~0xFF FF FF FF都可以
  Directory 1
  Size              0xb0    ;任意写 0x0~0xFF FF FF FF都可以
  这3个有点浮夸,但可以正常运行。
  c)如今不妨跳过.code段,先搞.data段
  00000400   50 45 D1 A7 CF B0 00 00  BF B4 B5 BD C4 E3 C1 CB   PE学习..看到你了
  00000410   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000420   5C 20 00 00 00 00 00 00  FF FF FF FF 7C 20 00 00   \ ......??| ..
  00000430   64 20 00 00 6C 20 00 00  00 00 00 00 FF FF FF FF   d ..l ......??
  00000440   8C 20 00 00 74 20 00 00  00 00 00 00 00 00 00 00   ?..t ..........
  00000450   00 00 00 00 00 00 00 00  00 00 00 00 AC 20 00 00   ............?..
  00000460   00 00 00 00 AC 20 00 00  00 00 00 00 BC 20 00 00   ....?......?..
  00000470   00 00 00 00 BC 20 00 00  00 00 00 00 75 73 65 72   ....?......user
  00000480   33 32 2E 64 6C 6C 00 00  00 00 00 00 6B 65 72 6E   32.dll......kern
  00000490   65 6C 33 32 2E 64 6C 6C  00 00 00 00 00 00 00 00   el32.dll........
  000004A0   00 00 00 00 00 00 00 00  00 00 00 00 01 00 4D 65   ..............Me
  000004B0   73 73 61 67 65 42 6F 78  41 00 00 00 02 00 45 78   ssageBoxA.....Ex
  000004C0   69 74 50 72 6F 63 65 73  73 00 00 00 00 00 00 00   itProcess.......
  000004D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000004E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  000004F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  下去两个字符串,注意最后加'\0'。对应的Rva是0x00 40 20 00和0x00 40 20 08
  从0x420开始是输入目录
  由于有2个DLL,所以先留3*0x14=0x3c的中央,先把4个FF写好,以后找起来方便些,逐一。
  OriginalFirstThunk    0x205c
  TimeDateStamp      0x0      ;
  ForwarderChain      0xffffffff    ;不中转
  Name          0x207c
  user32.dll
  FirstThunk        0x2064
  ----------------------------------------
  OriginalFirstThunk    0x206c
  TimeDateStamp      0x0      ;
  ForwarderChain      0xffffffff    ;不中转
  Name          0x208c
  kernel32.dll
  FirstThunk        0x2074
  ----------------------------------------
  全0
  ----------------------------------------
  之后我放的是4组Thunk,注意每组最后一个元素都是0。
  这样上面两个OriginalFirstThunk和FirstThunk都可以定上去了。
  之后是两个DLL的名字,于是Name可以定上去了。
  然后是两个IMAGE_IMPORT_BY_NAME
  WORD Hint      ;任意写一个
  BYTE Name[1]    ;函数名
  MessageBoxA是user32.dll的。
  ExitProcess是kernel32.dll的。
  这样上面的Thunk可以定了。
  好,数据段的大小也定了。回到上面去改一下。
  d)最后写代码。
  00000200   6A 00 68 00 20 40 00 68  08 20 40 00 6A 00 2E FF   j.h. @.h. @.j..?
  00000210   15 64 20 40 00 6A 00 2E  FF 15 74 20 40 00 00 00   .d @.j..?t @...
  00000220   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00000230   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  00401000 >/$  6A 00        push    0                  ; /Style = MB_OK|MB_APPLMODAL
  00401002  |.  68 00204000      push    00402000              ; |Title = "PE学?,B0,""
  00401007  |.  68 08204000      push    00402008              ; |Text = "?,B4,"?,BD,"你了"
  0040100C  |.  6A 00        push    0                  ; |hOwner = NULL
  0040100E  |.  2E:FF15 64204000>  call    dword ptr cs:[<&user32.MessageBoxA>  ; \MessageBoxA
  00401015  |.  6A 00        push    0
  00401017  \.  2E:FF15 74204000>  call    dword ptr cs:[<&kernel32.ExitProcess>]  ;  kernel32.ExitProcess
  代码很简单,00 20 40 00也就是 00 40 20 00,是第一个字符串的地址。
  要注意“高高低低”的规则。
  64 20 40 00 是00 40 20 64是user32.dll的FirstThunk,指向的就是MessageBoxA
  其他:
  学习pe的时间,用c写了段读pe结构的代码,对于学习照旧很有帮助的。
  winnt.h包含了pe结构的说明,但一开始include之后一排错。
  原来还要include
  终于竣事了,打完收工...
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: