Ecstatica 2 DOS/Win95 Debug Symbols
Just to let you know both Ecstatica 2 (DOS, WIN95) watcom executables have debug symbols which can be tested with your tool.
I got some xcode related errors that may be related with my setup:
[1759756556] [WARNING ] Offset != entry["end"]: offset: 0x1cc38, entry["end"]: 0x1cc3c [1759756556] [WARNING ] Length != entry["end"] - entry["start"]: length: 0x0 (0), entry["end"] - entry["start"]: 0x4 (4) [1759756556] [WARNING ] Offset != entry["start"]: offset: 0x1cc38, entry["start"]: 0x1cc3c [1759756556] [ERROR ] Error: command failed with exit code 1: [1759756556] [ERROR ] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: unknown argument '--architecture=i386'
but the convertion tool kept going and was able to produce multiple files, but I am unsure they are all complete.
I'm sending the game's dos version and the log and output_plain files in case it helps.
I've made a small script to dump the variables and function names into IDA `
import re
import json
with open('E2DOS.EXE_wdump_output_plain.txt', 'r') as file:
data = file.read()
lines = data.split('\n')
entries = []
modules = []
entry = {}
module_entry = {}
global_info = False
module_info = False
for line in lines:
if 'Module Info (section 0)' in line:
module_info = True
continue
if module_info:
if ')' in line:
index = line.split(')')[0].strip()
module_entry['index'] = index
if 'Name:' in line:
name = line.split('Name:')[1].strip()
module_entry['name'] = name
modules.append({ **module_entry })
if 'Global Info (section 0)' in line:
global_info = True
module_info = False
continue
if 'Addr Info (section 0)' in line:
global_info = False
break
if global_info:
if 'Name:' in line:
name = line.split('Name:')[1].strip()
entry['name'] = name
if 'address' in line:
address = line.split('address')[1].split('=')[1].strip()
entry['full_address'] = address
entry['segment'] = address.split(':')[0]
entry['address'] = int(address.split(':')[1], 16)
if 'module index' in line:
module_index = line.split('module index')[1].split('=')[1].strip()
entry['module_index'] = module_index
entry['module'] = modules[int(module_index)]['name']
if 'kind' in line:
kind = line.split('kind:')[1].strip()
entry['kind'] = kind
entries.append({ **entry })
for entry in entries:
entry['ida_prefix'] = entry['module'].split('\\')[-1].split('.')[0]
entry['ida_address'] = entry['address'] + (0x410000 if entry['segment'] == '0001' else 0x470000)
entry['ida_address_hex'] = hex(entry['ida_address']).replace('0x', '').upper()
entry['ida_name'] = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', entry['name'].replace('_',''))
entry['ida_name'] = re.sub('([a-z0-9])([A-Z])', r'\1_\2', entry['ida_name']).lower()
if entry['segment'] == '0001':
entry['ida_name'] = entry['ida_prefix'] + '_' + entry['ida_name']
entry['ida_name'] = entry['ida_name'] + '_' + entry['ida_address_hex']
entry['ida_name'] = entry['ida_name'].replace('@', '_').replace('sub_','sub')
with open('E2DOS.EXE.json', 'w') as file:
json.dump(entries, file, indent=4)
with open('E2DOS.EXE.modules.json', 'w') as file:
json.dump(modules, file, indent=4)
with open('E2DOS.EXE.idc', 'w') as file:
for entry in entries:
if int(entry['module_index']) > 18:
continue
file.write('MakeName(0x{ida_address_hex}, "{ida_name}");\n'.format(**entry))
`
Nice find. Won't work on Mac OS as its objdump does not support the x86 architecture (judging from the log).
Here's the full output (remove the trailing .zip, that's just for GitHub to accept the upload):
wcdatool-output.7z.001.zip
wcdatool-output.7z.002.zip
Seems to be coded quite densely, just a few source files:
.
├── C
│ └── e
│ ├── anim.c.asm
│ ├── chars.c.asm
│ ├── display.c.asm
│ ├── edit.c.asm
│ ├── ellipse.c.asm
│ ├── file.c.asm
│ ├── game.c.asm
│ ├── icon.c.asm
│ ├── init.c.asm
│ ├── map.c.asm
│ ├── menu.c.asm
│ ├── move.c.asm
│ ├── pack.c.asm
│ ├── req.c.asm
│ ├── topo.c.asm
│ └── tri.c.asm
├── asm.ASM
└── library.asm
Thanks for running the dump.
Yes indeed, some files seem to be very big but I believe it helps reversing. Having the file names, functions and variables is a huge help. Only missing the structures I guess, but I haven't dive into the files you gave yet.
Yes indeed, some files seem to be very big but I believe it helps reversing.
It's at least easier that way to keep an overall view. Many small files make that rather difficult in my experience.
Having the file names, functions and variables is a huge help. Only missing the structures I guess, but I haven't dive into the files you gave yet.
Yes. Watcom debug symbols contain file names, function/procedure names and labels for global variables, e.g. _HiResWidth.
Sadly, there is lots of stuff missing:
- Parameter lists/names for functions
- Local function variables
- Struct information (aside from starting offset, e.g.
_got11j0b)
Well, I guess that why they call it reverse engineering... ;)
I wonder with this extract we could compile the assembly back with OpenWatcom? Or would be better of using an extract from IDA/Ghydra.
Sorry for not getting back to you sooner.
You can try your luck with IDA/Ghidra or tools like le_disasm (https://github.com/samunders-core/le_disasm, https://github.com/klei1984/le_disasm).
Recompiling disassembled code is not an easy task.
No worries at all. Thanks for the links, didn't know about those tools. I will have a look. Cheers