Skip to content Skip to navigation

No harm (reverse 200)


The task was to find MD5 of the biggets file from the file HARM.DAT, which is the part of game Harm0597 for MS DOS.

First of all let's ask Google to find this game and easily find URL to download it:

File HARM.DAT has an obvious structure:

struct _FILE_HEADER {
    char magic[32];
    __int32 numSubFiles;
    _PACKED_FILE_HEADER packedFileList[]; 
} FILE_HEADER, *PFILE_HEADER;   // sizeof(_FILE_HEADER) = 32 + 4 + numSubFiles*sizeof(_PACKED_FILE_HEADER)

    char fileNameA[12];
    unsigned char fileType;
    unsigned __int32 fileRealSize;
    unsigned __int32 fileDataOffset;

So we can easily find the biggest file: it's file with name "TRX-DRNK.RUS".

But sum of all _PACKED_FILE_HEADER.fileRealSize is much bigger that file size. This means that some files are compressed.
According to the next info we can make assumption that files with type = 3 are compressed.

	fileId = 21
	fileName = TECHINFO.RUS
	fileType = 0x3
	fileDataOffset = 0xd6d0
	fileDataSize = 0x5000

	fileId = 22
	fileName = YEP.BINO.RUS
	fileType = 0x1
	fileDataOffset = 0xdcca
	fileDataSize = 0x2d0

	fileId = 23
	fileName = NO.BINNO.RUS
	fileType = 0x1
	fileDataOffset = 0xdf9a
	fileDataSize = 0x330

 Fortunately, first 2 bytes of compressed files are the size of compressed data. So data of compressed files has the next format:

    unsigned __int16 dataSize;
    unsigned char    data[];    

Now we can dump file "TRX-DRNK.RUS" and... find nothing ;(

The problem is that I don't know the compression algorithm and this file has non-standard structure (or it's a raw data). Anyway this is my script for parsing HARM.DAT file, just in case.

Now let's start RE HARM.EXE. If you open it in IDA you will find that it's most likely packed..

And packed by pklite! So let's unpack it!

The things we need for that are:

  1. DosBox -- MS Dos emulator (URL:
  2. PkLite unpacker (we can take program UNP from
  3. DosBox debugger (just in case) (can be foud there:


the easiest unpacking ever ;)

Now open unpacked file in IDA and start reversing. Using IDA, debugger and script higher we can find that

  1. function sub_1417E returns id of the packed file with given name (call it get_file_id_by_name);
  2. function sub_1422C takes packed file id and address of buffer for uncompressed data (call it get_file_data_by_id).

Here is a part of main function (called PROGRAM in DOS)

Now let's start debugging unpacked program, stop at the beginning and make next changes:

1) set size of newly allocated memory at cs:2428 via "sm cs:2429 ff ff" (allocate memory block of size 0xFFFF)

2) set breakpoint at address cs:2430 (right after call for memory allocation to gather allocated memory address)

3) change file name offset at cs:2469 via "sm cs:246a 9f 22" (cs:229F points to string "TRX-DRNK.RUS")

4) at address cs:2474 set the code

les di,[3176]
push es
push di
call <newSeg8Value>:028C

via "sm cs:2474 c4 3e 76 31 06 57 9a 8c 02 <newSeg8Value.LowByte> <newSeg8Value.HighByte>", where newSeg8Value is the value of seg08 from IDA (0x0608 in my case)

5) set breakpoint at address cs:247F (right after call decompression function to dump decompressed data)

6) continue normal execution, at breapoint 1 remember address of allocated memory ({dx:ax}) and at breakpoint 2 make memory dump via "memdump <allocSeg>:<allocLinAddr> f8a0" (memdump 1e94:0000 f8a0)

Now you can find memory dump in DosBox's folder, convert it to binary data and find it's MD5 which will be the flag: 8C0C4C5F223D9B3822A51EEA0CABD524.

The only reason to make all changes in binary right before execution are relocations. When I've set the number of relocations to 0, my DosBox have crashed.. so I decided that the way above is better that try to guest the reason of DosBox's crash or searching for new DOS emulator:)