中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: 33字节DOS EXE文件,最短了? 上一主题 | 下一主题
本是
银牌会员





积分 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 ]

   此帖被 +4 点积分        点击查看详情   
评分人:【 sl543001 分数: +4  时间:2010-3-8 11:18


附件 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
查看资料  发送邮件  发短消息 网志  OICQ (363852426)  编辑帖子  回复  引用回复
本是
银牌会员





积分 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
查看资料  发送邮件  发短消息 网志  OICQ (363852426)  编辑帖子  回复  引用回复
本是
银牌会员





积分 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
状态 离线
『第 9 楼』:  

强! 编程是艺术啊!!!

2007-1-25 01:37
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Jneny
高级用户

中國DOS聯盟常任參議员


积分 686
发帖 318
注册 2005-11-4
状态 离线
『第 10 楼』:  

我要学习到这个地步得多少年呀,想下就晕



. 繽紛色彩閃出的美麗是因為它沒有分開每種色彩...>/

    我的百度空间: BEYOND超越        为什么用DOS  
2007-1-25 01:52
查看资料  发送邮件  发短消息 网志  OICQ (290256061)  编辑帖子  回复  引用回复
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
注意变红的行,它保证不能为零!

   此帖被 +4 点积分        点击查看详情   
评分人:【 sl543001 分数: +4  时间:2010-3-8 11:30




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
查看资料  发送邮件  发短消息 网志  OICQ (354324773)  编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: