|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『楼 主』:
33字节DOS EXE文件,最短了?
33字节DOS EXE文件,最短了?
DOS下简单的.EXE文件通常是由汇编、链接工具生成的,但它们一般在文件头内包含了
一个480字节的空白部分,要去掉它们也很容易,只要将02H、04H及08H处的值改变就可以了。
执行代码为mov ah,4ch和int 21h的.exe文件一般是32+480+4字节长,头部如下:
000000 4D 5A 04 00 02 00 00 00 20 00 01 00 FF FF 01 00
000010 00 00 EB 36 00 00 00 00 1E 00 00 00 01 00 00 00
尾部如:
000200 B4 4C CD 21
头尾之间是480字节的NUL字符。02h处改为24,04h处改为01,08h处改为02,原200h处的执行代码移到20h处。
这样,文件长32+4字节。所以,如果这就是EXE文件的常规,那么exe文件的长度,就取决于
执行代码的长度,因为头的长度是固定的32字节。作为正常的文件结束,应该最短了(int 20h只有2字节);再想短
的话,就要使用特别代码如int 19h(重新启动)了。***还有更短的,如ret,参见5楼、6楼贴***那样,文件长32+1字节。
这是短的极限吗?有没有更短的?
附件中,
0.asm ----源文件
0.exe ----516字节
01.exe ----36字节
03.asm ----源文件
03.exe ----514字节
04.exe ----34字节
[ Last edited by 本是 on 2007-1-21 at 01:51 AM ]
附件
1: COOLEXE.RAR (2007-1-16 12:20, 533 bytes, 下载附件所需积分 1 点
,下载次数: 46)
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2007-1-16 12:12 |
|
|
electronixtar
铂金会员
积分 7493
发帖 2672
注册 2005-9-2
状态 离线
|
『第
2 楼』:
34字节,汗~~~
|
C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>" |
|
2007-1-17 10:54 |
|
|
enjoyer
中级用户
部落守望者
积分 351
发帖 140
注册 2006-6-19
状态 离线
|
『第
3 楼』:
本是兄解释一下为什么把04h,和08h处的值改变就能去掉中间的空白部分.
是程序加载时不分配这480字节吗? 最好是在可执行文件中去掉啊.
|
一切从底层开始 |
|
2007-1-19 09:32 |
|
|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『第
4 楼』:
Quote: | Originally posted by enjoyer at 2007-1-19 09:32:
本是兄解释一下为什么把04h,和08h处的值改变就能去掉中间的空白部分.
是程序加载时不分配这480字节吗? 最好是在可执行文件中去掉啊. |
|
比如下面的文件:
000000 4D 5A 04 00 02 00 00 00 20 00 01 00 FF FF 01 00
000010 00 00 EB 36 00 00 00 00 1E 00 00 00 01 00 00 00
尾部如:
000200 B4 4C CD 21
EXE文件头的第04h、06h处word分别存储着EXE文件长度的200h的模及商(不能为0,所以要+1),08h处word存储文件头长度(以节为单位)以确定载入模块的开始位置,其它内容因此次修改简单并不涉及:
04 00 --> 0004:4字节
02 00 --> 0002:(2-1)*512字节;4+(2-1)*512=516字节
20 00 --> 0020:20h*16=512字节
现在截去20h--200h之间的部分,文件长 mod 512=36,文件长/512+1=1,
文件头长32/16=2,改后为
000000 4D 5A 24 00 01 00 00 00 02 00 01 00 FF FF 01 00
000010 00 00 EB 36 00 00 00 00 1E 00 00 00 01 00 00 00
000020 B4 4C CD 21
查查EXE文件头的结构就应该清楚了。
此帖被 +7 点积分 点击查看详情 评分人:【 enjoyer 】 | 分数: +2 | 时间:2007-1-21 09:32 | 评分人:【 Jneny 】 | 分数: +1 | 时间:2007-1-25 01:51 | 评分人:【 sl543001 】 | 分数: +4 | 时间:2010-3-8 11:17 |
|
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2007-1-20 11:11 |
|
|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『第
5 楼』:
再给个COM2EXE的转换程序,大家可以对照学习EXE与COM的文件差别。
所附源程序中第1行及相关部分为我所加,你可以根据需要把xtra_bytes equ后面的数字256改为0到65500之间的任何值。试一试吧!
xtra_bytes equ 256 ;0--65500,so long as you need!!!
.286
Code SEGMENT para PUBLIC 'CODE'
Assume CS:Code, DS:Code
ORG 100h
;==========================================================
cr equ 10
lf equ 13
;==========================================================
Start:
Call Header ;logo
Call CmdLine
cmp al,-1
je _usage
Call OpenRFile ;open readfile
cmp al,-1
je _norfile
Call OpenWFile ;open writefile
cmp al,-1
je _nowfile
Call HeadOn ;write header
_closewfile: Call CloseWFile ;close writefile
jmp _closerfile
_nowfile: Call NoFile
_closerfile: Call CloseRFile ;close readfile
jmp _ende
_norfile: Call NoFile
jmp _ende
_usage: Call Usage ;display usage
_ende: Call Footer ;display ---------------------
mov ax,4c00h
int 21h
;==========================================================
HeadOn PROC near
pusha
mov cx,32+xtra_bytes ;bytes
mov ah,40h ;write to file
mov bx,WFileHandle ;handle of file
lea dx,exe_header ;data: where at
int 21h
jc headon_fail
headon_lop:
mov ah,3fh ;read
mov bx,RFileHandle ;handle
mov cx,63000 ;bytes
lea dx,loadword ;where at
int 21h
or ax,ax ;0 bytes ? !!!!
jz headon_end ; !!!!
add filesize,ax
mov cx,ax ;bytes
mov ah,40h ;write
mov bx,WFileHandle ;handle
lea dx,loadword ;where at
int 21h
jc headon_fail
jmp headon_lop
headon_end:
add filesize,32+xtra_bytes
xor cx,cx
mov dx,2 ;where at (cx:dx)
mov ax,4200h ;move filepointer to (from files begin)
mov bx,WFileHandle ;handle
int 21h
mov ax,filesize
and ax,511
mov loadword,ax ;length mod 512
mov ax,filesize
mov cl,9
shr ax,cl ;div 512
inc ax
mov [loadword+2],ax ;pages
mov cx,4 ;bytes
mov ah,40h ;write
mov bx,WFileHandle ;handle
lea dx,loadword ;where at
int 21h
lea dx,headon_
Call Print
popa
ret
headon_fail:
lea dx,headon_fail_
Call Print
CALL FileName
popa
mov al,-1
ret
headon_ db 'CREATED EXE-FILE',cr,lf,'$'
headon_fail_ db 'CANNOT WRITE TO $'
exe_header db 'MZ' ;offset 00 (EXE-signature)
dw 0,0 ;bytes on last page, pages
dw 0 ;relocations
dw 2+(xtra_bytes shr 4) ;size of header in paragraphs
dw 1000h,-1 ;minimum, maximum memory
dw 0fff0h,0fffeh ;ss,sp values (ss=PSP)
dw 0 ;checksum
dw 100h,0fff0h ;ip,cs values (cs=PSP)
dw 1ch ;offset to reloc table
dw 0,0,0 ;overlay number, 0,0 (fill-ups)
db xtra_bytes dup(0)
HeadOn ENDP
;==========================================================
CloseRFile PROC near
pusha
mov bx,RFileHandle
mov ah,3eh
int 21h
popa
ret
CloseRFile ENDP
;==========================================================
CloseWFile PROC near
pusha
mov bx,WFileHandle
mov ah,3eh
int 21h
popa
ret
CloseWFile ENDP
;==========================================================
NoFile PROC near
pusha
lea dx,nofile_
Call Print
Call FileName
popa
ret
nofile_ db 'CANNOT OPEN FILE $'
NoFile ENDP
;==========================================================
OpenRFile PROC near
pusha
mov dx,82h ;asciiz = cmdline
mov ax,3d00h ;open it for read
int 21h
jc openrfile_fail
mov RFileHandle,ax
lea dx,openrfile_
Call Print
Call FileName
popa
ret
openrfile_fail:
popa
mov al,-1
ret
openrfile_ db 'OPENED FILE $'
OpenRFile ENDP
;==========================================================
OpenWFile PROC near
pusha
xor ah,ah
mov al,ds:80h
mov di,ax
mov ds:[di+80h-2],'XE'
mov byte ptr ds:[di+80h],'E'
mov dx,82h ;asciiz = cmdline
mov ah,3ch ;open it for write
mov cx,0 ;attribute
int 21h
cmp ax,0
je openwfile_fail
mov WFileHandle,ax
lea dx,openwfile_
Call Print
Call FileName
popa
ret
openwfile_fail:
popa
mov al,-1
ret
openwfile_ db 'OPENED FILE $'
OpenWFile ENDP
;==========================================================
CmdLine PROC near
pusha
xor ah,ah
mov al,ds:80h
cmp ax,6 ;less than 5 chars (cmd-LINE) incl. ret?
jl cmdline_fail
mov di,ax
mov word ptr ds:[di+81h],'$'*256
popa
ret
cmdline_fail:
popa
mov al,-1
ret
CmdLine ENDP
;==========================================================
Header PROC near
pusha
lea dx,header_
Call Print
popa
ret
header_ db cr,lf
db '--==-- COM2EXE --==-- by HENDR璛 of OBSESSION',cr,lf,'$'
Header ENDP
;==========================================================
Footer PROC near
pusha
lea dx,footer_
Call Print
popa
ret
footer_ db '--==**==-- COM2EXE --==**==--',cr,lf,'$'
Footer ENDP
;==========================================================
Usage PROC near
pusha
lea dx,usage_
Call Print
popa
ret
usage_ db 'USAGE: C2E PROGRAM.COM',cr,lf,'$'
Usage ENDP
;==========================================================
Print PROC near
mov ah,09h
int 21h
ret
Print ENDP
;==========================================================
Return PROC near
pusha
lea dx,return_
Call Print
popa
ret
return_ db cr,lf,'$'
Return ENDP
;==========================================================
FileName PROC near
pusha
mov dx,82h
Call Print
Call Return
popa
ret
FileName ENDP
;==========================================================
filesize dw 0
RFileHandle dw ?
WFileHandle dw ?
loadword dw ?
;==========================================================
Code ENDS
END Start
[ Last edited by 本是 on 2007-1-21 at 01:22 AM ]
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2007-1-21 01:20 |
|
|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『第
6 楼』:
通过C2E把COM转换成EXE的实验,我发觉EXE文件最小的长度应该是33字节!
先把5楼的首行equ后的256改成0,存为c2e.asm,
masm c2e;
link c2e;
exe2bin c2e
再在debug下生成0、1、2、3、4字节的COM文件:
debug
n0.com
rcx
0
w
a100
ret
n1.com
rcx
1
w
a100
int 20
n2.com
rcx
2
w
a100
push cs
pop ds
ret
n3.com
rcx
3
w
a100
mov ah,4c
int 21
n4.com
rcx
4
w
q
然后
c2e 0.com
c2e 1.com
c2e 2.com
c2e 3.com
c2e 4.com
可以得到32、33、34、35、36字节的EXE文件(见本楼附件)!!!再分别运行
1.exe
2.exe
3.exe
4.exe
通过!
不要在真实机纯DOS下运行0.exe,要死机的!或者会重复运行刚刚运行过的执行文件的内存映象----因为所有的运行都是在内存中进行的!!!而32字节的EXE文件载入后无运行代码进入内存,而它又指示运行文件头后的代码,而此处的代码就自然是上一次运行过的代码喽!
[ Last edited by 本是 on 2007-1-21 at 02:14 AM ]
附件
1: 01234.RAR (2007-1-21 02:14, 472 bytes, 下载附件所需积分 1 点
,下载次数: 11)
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2007-1-21 01:43 |
|
|
enjoyer
中级用户
部落守望者
积分 351
发帖 140
注册 2006-6-19
状态 离线
|
『第
7 楼』:
Quote: | Originally posted by 本是 at 2007-1-20 11:11:
比如下面的文件:
000000 4D 5A 24 00 01 00 00 00 02 00 01 00 FF FF 01 00
000010 00 00 EB 36 00 00 00 00 1E 00 00 00 01 00 ... |
|
本是兄果然出手不凡, 佩服.不过我还有一点疑问就是为什么一定要是36不是20个字节呢?
上面三行去掉中间一行, 第一行改为:
000000 4D 5A 14 00 01 00 00 00 01 00 01 00 FF FF 01 00
[ Last edited by enjoyer on 2007-1-21 at 10:06 AM ]
|
一切从底层开始 |
|
2007-1-21 10:03 |
|
|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『第
8 楼』:
这一点我已经试验并思考多次:EXE文件头02h和14h的word值都改成负值、再把执行代码藏在文件头的某些位置,但都不成功。原因可能是EXE格式本身规定所致:我用俄罗斯跟踪工具INSIGHT跟踪的结果是----如果填入0、0FFFEh,并把C3填入文件头的第1Fh字节,载入时预备运行位置是在无符号值0FFFEh而不是有符号值的-1处!也就是说执行代码位置只能为正,为0时执行内存映象----通常为上次运行过的程序映象!如果我的观察没有出错,确实EXE文件最小值就是33字节!!!
[ Last edited by 本是 on 2007-1-22 at 04:59 AM ]
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2007-1-22 04:58 |
|
|
nyuser
新手上路
积分 4
发帖 2
注册 2007-1-24
状态 离线
|
|
2007-1-25 01:37 |
|
|
Jneny
高级用户
中國DOS聯盟常任參議员
积分 686
发帖 318
注册 2005-11-4
状态 离线
|
『第
10 楼』:
我要学习到这个地步得多少年呀,想下就晕
|
. 繽紛色彩閃出的美麗是因為它沒有分開每種色彩...>/
我的百度空间: BEYOND超越 为什么用DOS |
|
2007-1-25 01:52 |
|
|
atoms
初级用户
积分 182
发帖 28
注册 2002-12-13
状态 离线
|
『第
11 楼』:
aaaaa
当文件字节为512的陪数时,02h为是0,04h为1?而不是为2,1-1=0*512不不成立了
|
|
2010-3-7 14:59 |
|
|
本是
银牌会员
积分 2201
发帖 789
注册 2005-1-27
状态 离线
|
『第
12 楼』:
请再看看5楼源程序中的这一段:
mov ax,filesize
and ax,511
mov loadword,ax ;length mod 512
mov ax,filesize
mov cl,9
shr ax,cl ;div 512
inc ax
mov [loadword+2],ax ;pages
注意变红的行,它保证不能为零!
|
my major is english----my love is dos----my teacher is the buddha----my friends--how about U |
|
2010-3-8 10:18 |
|
|
sl543001
中级用户
积分 499
发帖 225
注册 2008-12-30
状态 离线
|
『第
13 楼』:
坚决支持.
|
SYBNQQ:354324773
|
|
2010-3-8 11:29 |
|
|