VOGONS


First post, by llm

User metadata
Rank Member
Rank
Member

hi,

im currently working on an call-hijacker (something like detours for 16bit calls) for an game-reverse engineering project

i want to merge 16bit code running inside of the emulator and combine that with normal 32/64bit code from the ouside (to ease traceing, and the step by step porting) - so its would not realy become a mainline patch (that means i can (and will maybe) use dirty tricks)

what i've got so far is (ugly) code that runnes my code when near,relative or far calls are occuring - i can use the stack through the Push/Pop16 (im was missing Read Variants for inspection of the stack-values but that was no problem) --> that gives me a nice call-trace with parameters

but what im realy missing is something like a pointer which gives me direct access to the dos memory - i want to use my C structs with casting them onto the linear dos mem - so that im be able to read,change values
(without using the write/readmem functions - i hope that this will ease the porting an that i can use the resulting ported code without much changes in an dosbox-free pure port)

but i can only find paging-mem-access stuff ... is there a way to go around the paging and get direct access to the memory?

i know that this is a very freaky idea - but the current porting evironment is a wild mixture of tasm32, wlink and bc3.1 ... and extending the real game code very carefully - without the possibility of doing good tests
there are ~850 functions waiting to be ported ... and it is all 16bit - with all the 16bit problems

thx

Reply 1 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

but what im realy missing is something like a pointer which gives me direct access to the dos memory

Please specify what you exactly want: direct access to the low memory (up to
1mb what usually is referenced as "dos memory") or direct access to the virtual
address space (protected mode but cheating around segment descriptors)?

When exactly do you need the access, are you in pmode (regular application that
runs inside dosbox) or are you hacking dosbox itself for this?

Reply 2 of 14, by llm

User metadata
Rank Member
Rank
Member

Please specify what you exactly want: direct access to the low memory (up to 1mb what usually is referenced as "dos memory")

that is what i want

When exactly do you need the access, are you in pmode (regular application that
runs inside dosbox) or are you hacking dosbox itself for this?

the 16bit game itself runs in realmode, and uses only the low memory
and yes im hacking dosbox itself

due to disassembling i know what the functions parameters and local vars are, and also what global vars are around (all what ida freeware can provide)

currently im sitting in CPU_CALL and give control over to my own code (currently directly coded into dosbox - i hope to move this code later into an .dll) - now i look for known function adresses and jump to my corresponding stack analyser and global var mapper - all i want now is the abilitiy to cast the 16bit seg/ofs pointers to real dosbox host ptrs

like

original_struct
dw first
db second

emulated-code:
push ptr ; a ptr value to a original_struct...
call bla
dosbox itself
--> CPU_CALL
--> my_code
16BitPtr = stackRead16() // value of ptr

equal_struct // same alignment/size of the original data
uint16 first
int8 second

equal_struct* values = (magic)16BitPtr;
// should change element also in the emulated-space
values.first = 10;
values.second = 20;

//and i also got here the information of used global variables

--> give control back to emulator

clear enough - i hope 😒

i don't want to use the memwrite functions with copying the structs around
(i want to have the ported code as clean as possible)

Reply 3 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

all i want now is the abilitiy to cast the 16bit seg/ofs pointers to real dosbox host ptrs

Direct access is not possible, you'll have to go through regular functions.
Simple example is if something references video memory, that may be
resolved to a *call* to some custom function (ie. no simple pointer).

If you want to add some complexity to this, check the functions
mem_readb_inline and host_readb (the first uses the latter). If a tlb address
can be resolved, you effectively have the pointer at hand. If you stick to real
mode anyways, you may not have to re-evaluate the address (ems memory
is one exception here) and the page-spanning word/dword writes may need
additional checks. But for x86 and a quick hack this may be what you're looking for.

Reply 4 of 14, by llm

User metadata
Rank Member
Rank
Member

Direct access is not possible, you'll have to go through regular functions.
Simple example is if something references video memory, that may be
resolved to a *call* to some custom function (ie. no simple pointer).

i though that there is still the underlaying memory-space - but i understand the problem (there a many of these mapping problems around)

If a tlb address
can be resolved, you effectively have the pointer at hand.

what function is that - is there an "example" line in the code where someone does stuff like this

something like resolvetlb(my16bitptr) ...

If you stick to real
mode anyways, you may not have to re-evaluate the address (ems memory
is one exception here)

the game needs realmode and do not use ems - so im happy with that

and the page-spanning word/dword writes may need
additional checks.

can you explain that more detailed - there could be a problem when
i come from one to the other page because of the write size?

But for x86 and a quick hack this may be what you're looking for.

maybe 😀

thx

Last edited by llm on 2010-10-01, 06:38. Edited 2 times in total.

Reply 5 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

what function is that - is there an "example" line in the code where someone does stuff like this

I've posted the function names above. They contain tlb resolution.

can you explain that more detailed - there could be a problem when
i come from one to the other page because of the write size?

For x86 hosts the low memory is an unpaged block so page/segment transitions
are nothing to worry about. Switching the a20 line would cause some mapping
but that may not be relevant for you either.

Reply 6 of 14, by llm

User metadata
Rank Member
Rank
Member

i will check if any a20gate action is in the game

another question: how can i get the "base" address of the game.exe - all my global vars and functions are relative adresses - i need to combine these relatives + base = absolute address - any functions around for information like that?

Reply 7 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

There's no base address. The game can allocate dos memory chunks, then re-calculate
the segment/offset pairs of that, so 0x1234 can be anything.
If you need the actual first address where the .exe file is loaded, try some dos
PSP functions.

Reply 9 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

and i will try to find the correct psp by the games exe name (or size,...) - should work

Not sure what exactly you're targeting at, but the psp may be relevant or
something as simple as the code segment value. Both may not be useful
though when you got an arbitrary memory reference (see the get dos
memory example).

Reply 10 of 14, by llm

User metadata
Rank Member
Rank
Member

Not sure what exactly you're targeting at

i've got global vars that i want to read/write from functions that do not use
these variables directly, or through stack parameters so i need a way of getting to the absolute address of it, i've got the relative adress of this global(s) from the disassembler -> how can i do this without knowing the start of the exe?

Reply 11 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

In general you can't, but at program start the application runs from cs:100
in most cases so you can use that for offsetting (use a simple example to
check what exact calculations you need, i'd assume if you have an address
in ida that is 0x1234 that should match with memory at cs+0x10:0x1234.

Reply 12 of 14, by llm

User metadata
Rank Member
Rank
Member

and what is if my cs value changed due to far calls (the program) consists of around 40 segments -> how can i just add a fixed value to the current cs and get to the right place - that can't work, or?

for now i can use a "fix" offset which every first loaded program starts
(it changes sometimes when updating the dosbox source but that is ok)

other way is to look for the psp(or the mcb) which gots the name of my exe and use the information of the first mcb(of the chain) -xyz to get the psp as the base...

Reply 13 of 14, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

and what is if my cs value changed due to far calls (the program) consists of around 40 segments

Was only talking about program start (you could intercept int21/4b and store the value,
or try psp functions). But as always this depends on the program structure and will
only work in some cases (any application can move/relocate complete program
blocks arbitrarily and you won't ever get some sensible matching to ida).