User Tools

Site Tools


blog:pushbx:2022:1121_ldebug_e_inicomp_review_and_a_change

lDebug /E, inicomp review and a change

2022-11-19

This week I added another switch to lDebug to support using it for offline patching of iniload files (such as the debugger's own executable), even if the file exceeds 64 KiB.

Without the /E switch or its associated DCO6 option opt6_big_stack, loading a large file in flat binary format will leave ss == PSP and sp at FFFEh, that is, the stack points into the image data. If used, it will corrupt the binary image.

Now patching a binary does not require using a run command, so the stack is not used by running the program. However, patch.sld uses the stack as temporary storage to hold its search sequences. It uses the debugger's assembler (A command) to build those, then the S command's RANGE keyword to search for the pattern from memory.

So the /E switch will enable using the last 512 bytes of the PSP memory block for the stack, setting up ss properly and sp to 512. This, besides enabling patching, also allows the debugger to directly execute .big images like used by the debugger's own build process.

A .big image is essentially similar to a .com format flat executable, that is it is a flat binary without headers and it should be loaded to the PSP segment's offset 100h in full and executed with cs:ip == PSP:100h. Unlike .com files, .big files may exceed 64 KiB in size, and the stack should be initialised to point behind the loaded binary image. The latter is exactly what the /E switch does, albeit that was not its intended purpose.

inicomp's minsize

The compressed inicomp .big file's .exe mode entrypoint will use the stack it is passed to determine how much memory it has for decompression. And if the image .exe auto stack option is enabled, inicomp will pass the stack verbatim to its decompressed payload.

That briefly confused me today because how will the outer iniload know how much memory to assign to the stack?

Of course, this is already handled properly by the mak.sh script: It will use the tellsize and decompsize to determine the minsize. The decompsize is either detected using the test program build, or setup to equal the size of the compressed plus uncompressed image.

The minsize is used to determine the minimum allocation (exeMinAlloc) of the compressed executable's MZ .exe header. It is passed to iniload's image .exe min alloc calculation define. This define, in turn, is also used to determine the stack segment entered into the .exe header.

inicomp's zero entrypoint

During today's review I found that the inicomp executable image, eg pddebug.big, would enter its kernel mode entrypoint if entered at the file's offset zero. This is unlike the uncompressed image ddebug.big which would jump to the .exe mode entrypoint instead.

The zero entrypoint is not used by default: The application mode sets up the MZ header entrypoint as -16:256 + 64, and the kernel mode has its entrypoint as 0:32. The device driver entrypoint is referenced by the device header which lives at the beginning of the image.

This change allows loading pddebug.big using ldebug /e just like ddebug.big. The flat binary loading sets up cs:ip as -16:256.

You could leave a comment if you were logged in.
blog/pushbx/2022/1121_ldebug_e_inicomp_review_and_a_change.txt · Last modified: 2022-11-21 18:35:31 +0100 Nov Mon by ecm