New kernel compression methods - exeExtraBytes jump (Announce)
> > Funny, I don't actually know how much UPX would compress things. So I
> made
> > a test. I had to patch out the short jump in the "last page size" bytes
> of
> > the EXE header. (These are used for the MS-DOS 6.x and FreeDOS kernel
> > entrypoints.) The invalid value of the short jump instruction in that
> field
> > otherwise leads to "CantPackException: exe header corrupted".
> (Obviously,
> > packing the kernel file with UPX without special handling makes it no
> > longer work as a kernel file.)
>
> Not sure which short jump you are referring to --- care to elaborate?
Sure! It is the jump at line 236 in iniload.asm, which reads as follows:
start:
db "MZ" ; exeSignature
; dec bp, pop dx
jmp strict short ms6_entry ; exeExtraBytes
; db 0EBh, 16h ; dw 16EBh
This is need because the FreeDOS, PC-DOS (6/7), and MS-DOS (6) entrypoints don't care about the kernel being in .EXE format, they always load their kernels (whole kernel at 60h:0 for FreeDOS) or initial loaders (at 70h:0 for the other three protocols) to the segment start and then jump to the entrypoint at offset zero. Because the pop dx
instruction (the "Z" in the MZ .EXE signature) overwrites the dl register, we depend on ss:bp pointing to a valid BPB with the boot load unit field set.
We do need our kernel file to be in .EXE format because it can grow larger than 64 KiB, which would disable loading (properly) as a .COM format application program. This can be either simply due to the kernel's size, or due to appended large data (such as a .ZIP archive) which is valid for the RxDOS.3 / lDOS protocols. Besides, the .EXE format allows for the file to specify how much additional memory it needs (for decompression or in the case of lDebug also to make the initial relocations work). That means an error due to too little memory will be detected by the OS's executable loader, rather than later by the application itself. And the OS's loader can also determine that a potential UMB would be too small to load the application into it.
The jump instruction, as the comment indicates, sits in the "exeExtraBytes" field of the .EXE header. This field is not used by the MS-DOS executable loader I believe; its structure's field exec_len_mod_512 (link to permissively licensed MS-DOS 2 sources) is never referenced. For systems that do use the field, we assume they will treat an invalid value as some value between zero and 512. We include alignment to a 512 bytes boundary and then an additional 512 bytes of padding after the .EXE image, to insure that even with a low assumed value all of the actual image will be loaded. And the exeInitSS is calculated assuming a low exeExtraBytes too.
---
l
Complete thread:
- New kernel compression methods - ecm, 13.04.2020, 00:05 (Announce)
- New kernel compression methods - ecm, 13.04.2020, 00:17
- New kernel compression methods - tkchia, 13.04.2020, 14:23
- New kernel compression methods - ecm, 13.04.2020, 18:31
- New kernel compression methods - ecm, 13.04.2020, 18:35
- New kernel compression methods - tkchia, 14.04.2020, 14:46
- New kernel compression methods - fdkernpl - ecm, 14.04.2020, 17:05
- New kernel compression methods - exeExtraBytes jump - ecm, 14.04.2020, 17:06
- New kernel compression methods - tom, 14.04.2020, 20:06
- New kernel compression methods - ecm, 13.04.2020, 18:31
- New kernel compression methods - Updated lDebug lzd results - ecm, 16.04.2020, 17:29
- New kernel compression methods - Corrections - ecm, 16.04.2020, 22:06
- New kernel compression methods - X compressor layers - ecm, 16.04.2020, 22:22
- New kernel compression methods - Updated lzd, new lzo - ecm, 25.04.2020, 22:23
- New kernel compression methods - Updated lzd, new lzo - tom, 26.04.2020, 13:46
- New kernel compression methods - UPX, 512 runs clarification - ecm, 26.04.2020, 20:17
- New kernel compression methods - Updated lzd, new lzo - tom, 26.04.2020, 13:46