This program uses the PharLap DOS extender, as can be seen in its MZ header. The 32-bit executable program starts at offset 18A0, per "offset within header of relocation table" (see http://www.program-transformation.org/Transform/PcExeFormat), and at that position you can see the correct signature P3. According to the header info, the executable's length is ...
I'll dive into the past and try to give an explanation of the different checks you are observing in your software. I found three references explaining the behaviour (as I hope), which I will reference to in this answer as /1/, /2/, /3/.
It is an archive article from the ...
This looks like a 32-bit shift right compiler helper. In 16-bit era, 32-bit numbers were represented by a pair of registers, in this case ax:dx. The check for 16 is an optimization: if the shift is over 16, the low register value is lost completely, so it can be discarded and replaced by dx>>(shift-16), while the high register is filled with the sign ...
If you build with --enable-debug[=heavy] and run the program via debug.com, it automatically breaks on the first instruction. See the DOS_Execute function in src/dos/dos_execute.cpp and DEBUG_CheckExecuteBreakpoint in src/debug/debug.cpp.
There's an ida plugin that connects to (a patched version of) DosBox and allows you to debug DosBox games from ida. However, i doubt you'd get that to work with the free version of ida.
The fact that your memdumpbin uses the address 180:0 hints that the game uses a dos extender, so the "real" program is a 32 bit program which runs in protected mode - 180 is ...
Any hex editor will do. Under DOS both NC and VC have their own which are enough. Very good DOS tool is HIEW (hex editor + x86 dissasembler).
what to do
determine the executable form
open it as text/hex and if no program string are present then they are in different file or the file is packed/encrypted. Some executables are packet by PKLITE tools ...
DOS didn't have a concept of more than one application being able to run at the same time, with each of those applications able to allocate memory. Programs that stayed resident after termination weren't able to allocate more memory while another program was running. So, there was no fragmentation in memory, and no "memory location that was big enough".
I am wondering whether it is possible to reverse engineer this program and put in into a "modern" jacket, + enable easy data instruction.
Yes, it is possible, but not for a non programmer. To do so, one should examine how the calculations are performed and exact formulas used. Then, after obtaining such a knowledge, one could write an application working ...
This appears to be a 32 bit multiplication implemented on a 16 bit architecture.
Input numbers are dx:ax and cx:bx, result in dx:ax.
The xchgs make the code confusing but if you play it through you notice it does a bunch of a seperate multiplications with the high and low 16 bit of the input numbers.
At this point I had a hunch it may be 32 bit ...
It appears to be a 32 bit right shift with the 32 bit number provided in dx:ax, and cl being the number of bits to shift.
If you assume cl is over 16, a right shift by more than 16 bit only needs to care about the upper 16 bit, which are stored in dx, because the lower 16 bit are shifted out anyway.
So that's exactly what the 2nd block does. If cl larger ...
By intercepting or hooking interrupts in DOS you can make the system behave differently whenever an interrupt is triggered. And there are many interrupts used in x86 architecture, some are triggered by hardware (such as clock, keyboard, divide overflow/divide by zero), some are BIOS services that can be called from software and some are OS services or other ...
Unused functions in executables
There are various explanations for that.
Obfuscation, as Itsbriany said, but i don't think that was much of a thing in old DOS executables.
Unneeded library functions. If your code links in, for example, the math library (those old processors typically didn't have math coprocessors for floating point), you'll typically get all ...
In case anyone has same question, here is how I solved it :
1) I exported all debug symbol information to a text file, using TDUMP.
TDUMP somefile.exe > 1.txt
2) I cleaned the txt file to keep only useful information :
[Function name] + [Address]
3) I imported the file back to IDA using a python script : see here
Oh, the happyness of near functions vs. far functions, near pointers vs. far pointers, and mixed models (far functions, near pointers)
Back in the 16 bit world, programs could either
use a maximum of 64 KB code, and 64 KB data, have all pointers use 16 bit, and ignore segment registers. This was called the near model, because all offsets were within the ...
MZ-format executables also have the PSP at CS-0x10 just before the data loaded from the file.
Quoting Tech Help!, probaly the best DOS programming reference:
EXE-format programs define multiple program segments, including a
code, data, and stack segment. The EXE file is loaded starting at
In a DOS EXE file, if I have sub1, sub2, and sub3, split between two
code segments, how do I know which sub is in which segment?
Theoretically, you can't, since most addresses can belong to at least 16 different segments, but in practice there are some heuristics. For example, for targets of far calls and jumps you know their selector (segment value) and ...
You can use -m 0x100 to load the binary at a specific address, as can be seen in r2 -h output:
-m [addr] map file at given address (loadaddr)
So you can do something like this:
$ r2 -m 0x100 -b 16 test.com
[x] Analyze all flags starting with sym. and entry0 (aa)
╭ (fcn) fcn.00000100 13
│ fcn.00000100 ();
First: the code is only checking bit 2 (bit 0,1,2) if 25 or 28Mhz clock is set
Second: maybe its redundant but can't say without original code - could be still a problem with your disassembler
retf 0004 ; instance pointer?
is a far return with pop of 4 bytes from stack
It is typically true that DOS loads a .EXE program immediately after the PSP, meaning in your terms that base - PSP == 0x0010. But it's not necessarily true, and if you were writing this (or any) DOS executable, you might do better to know this. However, this is not you. Instead, here, you are a reverse engineer - or at least trying your hand at being one. ...
Check 2: While check 1 tests if the high-order bits of the flag word can be cleared, check 2 tests whether they can be set. On an 80286, these bits cannot be set in real mode, while on an 80386 they can.
Check 3: This is testing what kind of shifter the processor has. Some (the newer ones) have a barrel shifter that effectively masks the shift count to the ...
It looks like the code is specifically generating these outputs:
ax: (ax * bx)
dx: (bx * dx + ax * cx)
This is under the assumption that the mul instructions never have operands large enough to set dx to a non-zero value. (If that is true, it seems kinda weird that seg000:374F is an add and not just an xchg.)
Maybe it's calculating the addition of two ...
File extensions normaly do not help - there is no real standard, there are 1000 of .DAT and .KAN files around with absolutly not relation
only the content of the files can give us any hint
an executable does normaly not contain source (or source like stuff), only enough information that the cpu can work with it, nearly not human readable - except by the ...
DOS/4GW executables normally use LE (linear executable) format for the actual main program (the DOS stub is just a launcher for the DOS4GW.EXE extender) and should be detected as such by IDA so you can probably just check the loaded file format.
I found the code accessing the string using SoftICE for MS-DOS.
To use I did the following:
Add SoftICE driver as first entry in CONFIG.SYS
DEVICE=C:\SICE\S-ICE.EXE /SYM 50
Launch program and Alt+PrintScreen triggered break into SoftICE Window. (SoftIce Documentation also mentioned Ctrl+D but this didn't work for me)
Searched memory for my target string:
In DOS programs, a common sequence to look for is a sequence of push instructions, interleaved with sub sp,<size-of-local-vars>. This is a typical entry to a function. Whether this is an API entry point is harder to determine without more information. You could use a disassembler tool that is capable of handling MS-DOS images (like Reko, https://github....
It sounds like it's still possible to communicate with the company. Excellent: ask them what their opinions are with
reverse engineering the program, expressly to facilitate continuation of business operations
publicly disseminating binary copies of the program on the internet, modified or unmodified, also for the express purpose of reverse engineering to ...