完全手工打造一个小的EXE文件,第一个为1024字节,最终改造到512字节。
废话不多说,开始工作:
写个汇编程序:
start:
xor ebx,ebx
jz tcall
tjmp:
pop eax
push ebx
push eax
add eax,7
push eax
push ebx
push ExitProcess
push MessageBoxA
ret
tcall: call tjmp
db "ExeDIY",0
db "Hello!",0
用masm32编译链接后生成Hello.exe
该exe为2k大小,为了把它大小裁减下来,用UltraEdit新建一个16进制文件,
然后我们参考原来的文件来手工创建一个新的hello.exe。
文件如附件最终为1k大小,已经在WinXp/2k/Nt上测试。
我们作的主要工作是:
1. 把Dos Stub去掉;按照新的信息构造文件头。
2. 新文件对齐值为0x200,在0x200处填入指令信息。
3. 把数据段去掉。(但由于WinXp上section个数不能为一个,否则报不是Win32程序,所以仍
然保留了数据段的section信息,但把它指向都改为了.text段)
4. 由于数据段已经被去掉,需要将Imports相关信息搬入.text段0x300处。并从新计算
输入表的地址和输入地址表的地址及Import结构相关链表和指针的地址。由于我们在0x300
处,执行时内存映像中地址为0x401100,需要按照0x1100为参照修改链表的各个值。
在制作过程中发现文件对齐WinXp不能小于0x200,否则为非法win32程序,而NT可以时32字节倍数的对齐
,如果只针对NT的话可以把文件构造的更小.
虽然我们只用到1个段,但pe文件还是必须要有两个section!
修改Import相关地址后必须修改指令信息中的地址。因为每次对API的引用都是在操作编译器提供的一个地址,
该地址存放的时一条jmp [xxxx] 的指令, xxxx 地址即为Import的函数指针数组,Loader在加载程序时
会根据调用的DLL函数的具体加载地址来填充这里,但我们已经把这一地址移到了0x401100,要作修正。
整个文件dump出来的内容如下(WinHex真是强大呀!)。具体意义在后面描述。
你可以在这里下载它:http://watercloud.diy.163.com/others/Hello1.exe
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 4D 5A D5 E2 C0 EF BB F9 B1 BE B6 BC C3 BB D3 D0 MZ这里基本都没有
00000010 D3 C3 2C 44 4F 53 B1 A3 C1 F4 B5 C4 CD B7 B2 BF 用,DOS保留的头部
00000020 D0 C5 CF A2 2C CE D2 C3 C7 B6 BC B2 BB D3 C3 2E 信息,我们都不用.
00000030 D2 BB D6 B1 B5 BD D5 E2 C0 EF C0 B2 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 0F 01 0B 01 00 00 00 02 00 00 ....?..........
00000060 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 ................
00000070 00 00 00 00 00 00 40 00 00 10 00 00 00 02 00 00 ......@.........
00000080 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ................
00000090 00 30 00 00 00 02 00 00 00 00 00 00 02 00 00 00 .0..............
000000A0 00 01 00 00 00 00 00 00 00 01 00 00 00 10 00 00 ................
000000B0 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0 10 11 00 00 3C 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 11 00 00 10 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 43 6C 6F 75 64 00 00 00 ........Cloud...
00000140 00 02 00 00 00 10 00 00 00 02 00 00 00 02 00 00 ................
00000150 00 00 00 00 00 00 00 00 00 00 00 00 60 00 00 60 ............`..`
00000160 4E 53 46 4F 43 55 53 00 00 02 00 00 00 20 00 00 NSFOCUS...... ..
00000170 00 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................
00000180 00 00 00 00 60 00 00 60 D5 E2 C0 EF BF AA CA BC ....`..`这里开始
00000190 CA C7 B6 D4 C6 EB CC EE B3 E4 D0 C5 CF A2 A3 AC 是对齐填充信息,
000001A0 C3 BB D3 D0 D3 C3 2E 20 D2 BB D6 B1 B5 BD 30 78 没有用. 一直到0x
000001B0 32 30 30 68 BF AA CA BC CE AA 2E 74 65 78 74 28 200h开始为.text(
000001C0 D2 B2 BE CD CA C7 43 6C 6F 75 64 29 B6 CE BF AA 也就是Cloud)段开
000001D0 CA BC 2C CE D2 C3 C7 B0 D1 20 49 6D 70 6F 72 74 始,我们把 Import
000001E0 B1 ED D2 B2 B7 C5 B5 BD D5 E2 B8 F6 B6 CE C0 EF 表也放到这个段里
000001F0 C0 B4 C1 CB 2F 2F BA C7 BA C7 20 3A 29 20 20 20 来了//呵呵 :)
00000200 33 DB 74 13 58 53 50 83 C0 07 50 53 68 2A 10 40 3踭.XSP兝.PSh*.@
00000210 00 68 30 10 40 00 C3 E8 E8 FF FF FF 45 78 65 44 .h0.@.描?