One can do some other interesting stuff as well.
While I designed
the download tool for Dosbox-X/2 and the free DOS game Red Alert I found out that it's possible to recover code from DrDialog applications along side the resources.
Ok, we've known that for a long time, but how to calculate the length of each resource and extract them. A problem with resmgr/rdc is the extra bytes added that cause certain files to be unusable.
Anyway I reduced the code to extract images from the executable itself (specifically as icons) down to:
GetRes: PROCEDURE
PARSE SOURCE . . this /* where is this executable located */
CALL STREAM this, 'C', 'OPEN READ' /* open a stream to read itself while running */
C = 0 /* keep track of read position */
CALL SKP 60 /* skip over 60 characters (x 8 bit) from start */
lxofs = L2D(SKP(4)) /* find the offset for the exe lx data */
CALL SKP lxofs + 80 - C /* skip over data we're not looking for */
jmp = L2D(SKP(4)); jps = L2D(SKP(4)) /* find out resource position information and number of resources */
CALL SEEK 1 + lxofs + jmp /* reposition to location with info about resources */
DO i = 1 TO jps /* go through the resources */
CALL SKP 4 /* skip, just usable info we're not interested in here */
cb.i = L2D(SKP(4)) /* get resource start */
CALL SKP 2 /* skip, just more usable info we're not interested in here */
of.i = L2D(SKP(4)) /* get resource length */
END
DO i = 1 TO 8 /* The 8 icons (placed first with resources) */
CALL SEEK 135681 + of.i /* skip over the actual drrex.exe code (135681) */
CALL CHAROUT 'IMG'||( i + 990 )||'.ICO', CHARIN( this,, cb.i ) /* read resource data and write it out with a generic file name */
CALL STREAM 'IMG'||( i + 990 )||'.ICO', 'C', 'CLOSE' /* close the file afterward */
END
CALL STREAM this, 'C', 'CLOSE' /* and close the file we're reading from, this executable running */
RETURN 0
L2D: RETURN C2D( REVERSE( ARG(1) ) ) /* Helper function, C2D convert character to numeric value, while data must be read backwards */
SKP: C = C + ARG(1); RETURN CHARIN( this,, ARG(1) ) /* keep track of read position and reposition/skip relative read position */
SEEK: C = ARG(1) - 1; RETURN STREAM( this, 'C', 'SEEK ='||ARG(1) ) /* move read position to absolute position */
Tame/2, Inieditor and other software written with DrDialog where source code may only exist in the executable may be recovered if one want to rewrite/imporve/fix them.