News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu

Wanting to understand Restunts source code structure

Started by Cas, August 28, 2022, 11:24:08 PM

Previous topic - Next topic

llm

Quote from: Daniel3D on October 04, 2022, 01:31:09 PM
Quote from: llm on October 04, 2022, 08:37:17 AMa TSR will not change the problem of moving code around
(which is solveable by link-virus style programming)

it makes not real sense staying away from the source by adding a patch-systems with mods that still can't be created without
decent knowledege about the code and positions
That is where my idea for a replacement main menu came from. We only need to know how it stores global variables (player car, opponent and car, track and graphics settings).
Then we can use the new menu as tsr.
We could add a simple redirect in the code and compile it. It would make further messing with the code unnecessary for menu related changes.

i don't see anything better in using a TSR (when NOT only changing variable values like a game-cheater, which is currently the easiest change in source)
patching the code at runtime is equaly error prone then doing it in source - because there is no difference
as long as you cleanly check what you code-change changes - that goes for the sourc-code as for the TSR changes, a TSR isn't some sort of magical working isolation - and yes im developed some TSRs and runtime patchers - but only because i did not got the source around

Daniel3D

#46
I know little about this subject. But it seems to me that reverse engineering the entire code will not happen anytime soon.
But knowing what we do about the code , we are able to make pretty good TSR's or runtime patches.
It is probably a better choice than changing the half understood source.

It may be a quick and dirty solution but it might increase the playability of the game.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on October 04, 2022, 07:20:41 PMI know little about this subject. But it seems to me that reverse engineering the entire code will not happen anytime soon.

TSR+runtime patching are a complete different story than reversing the entire code - completely unrelated comment

Quote from: Daniel3D on October 04, 2022, 07:20:41 PMBut knowing what we do about the code , we are able to make pretty good TSR's or runtime patches.
It is probably a better choice than changing the half understood source.
It may be a quick and dirty solution but it might increase the playability of the game.

the fixes you install with the TSR can be easier and safe be done in the source itself, the TSR does not help to prevent ANY of the technical problems (anything thats wrong in source-time is also wrong at runtime)
and the changes to the main source should be already separated by IFDEFs to keep it clean

a TSR isn't something that can magical changes the nature of the executable in
a way that modifications are more trival/easier to do, a runtime-approach makes it even more complex
in can do the very same inside of the source but much safer without playing around with non-symbolic offsets to patch etc.

but that is all based on missing knowledge about how assembling or executables work - too much guessing and assuming, it is absolutely clear whats needed and how time consuming it is, for every case we talked about (and porting to C is just one of 8 possible further steps) - but you have currently no chance (but your knowledge is already growing) to take the right decision, because that needs a deeper level of understanding, without trick and trial&error

im telling you the best approach, but you aren't able to understand it, you want to go further, ignoring my tips because they also fail very quick (due to missing konwledge etc. on your side) - as i told you before - reverse engineering is the prime class of development - all problems at one point combined :)

i hope to find more time in the future to help "finishing" the project

Daniel3D

I know there is a huge difference between a TSE and reverse engineering the entire code.
Doing it in code is better, but just as unsafe.

And I am very much aware of things i don't know. I am also terribly exited and inpatient..

I feel like a kid that's poking the fire to see the "fireflies"... bound to be burnt.

One question before I shut up about it for a while..
If one would redirect to code outside the source, could we then use memory outside the 640K? Like high memory or even ram? And could that code run in a higher resolution than 320x200?

it's a learning experience. I learn by doing best. And that includes breaking it over and over again..

I prefer one of the 8 paths you mentioned, and if that is not included a good rewrite of the engine is also fine by me.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

QuoteAnd I am very much aware of things i don't know. I am also terribly exited and inpatient..

me too, started this project with others over 10 years ago :)

QuoteOne question before I shut up about it for a while..

you don't need to shut up :)

QuoteIf one would redirect to code outside the source, could we then use memory outside the 640K?
Like high memory or even ram?

you mean extended-ram? because everything is ram - we are currently in "conventional" ram

here is a memory-map: https://www.phatcode.net/res/155/images/fig1-1.png

QuoteAnd could that code run in a higher resolution than 320x200?

your question is confusing:

code does not "run" in a resolution and the position and size were code gets loaded is unrelevant for the resolution

video-modes uses different "memory-layouts" for displaying pixels, some of them are easy some of them
needs you to splitt the color of a pixel over multiple planes by switching using grafics card registers for each draw, some needs banking - so parts of the video-ram needs to be transfered between grafics card and conventional ram - due to its size

stunts in MCGA/VGA mode is more or less easy Mode 13h, 320x200x256 colors, so every byte starting
at 0xA000:0 is a pixel with one of the 256 palett-colors

drawing a pixel in C in Mode 13h is this

//y = 0..199
//x = 0..320
uint8_t far* video_ram = MK_FPT(0xA000,0);
video_ram[y*200+x] = palett-color

the problem is now that somewhere in the code are these 320 and 200 values hidden
sometimes even not as the values itself but as 4*80 or something - everything is possible
linear block operations for moving texture etc. - so its not just looking for put-pixel, its just to slow for the video-output doing it like that

switching to a different video-mode is possible but you need to change the drawing routines
and their local buffers, and what else is resolution dependend, for pre-drawing etc. its never just put-pixel but also the algorithm data behind

for example VESA mode 640x480x256 seems to fit (it just doubles resolution) - but this mode needs that much ram (~300kb)
that you need to switch the banks (because stunts isn't a protected mode program that would alllow linear accessing) while drawing, the bank switch is a super-super-slow BIOS call in real-mode - so every pixel drawing, polygons drawing/filling routine needs to be fixed, and every trick based on "it will be ever 320x200" is now a problem and without - its a mess

and all graphics needs to be doubled or else they will not be drawn tiny but (due to x doubling) distorted

and the resulting grafic can contain holes, due to the current low-resolution line drawing and polygon filling can be a little unprecise
which getting more and more a problem when the resolution gets bigger

and also the collision detection code could be resolution dependend ....

it could be simple like everything is always drawn on polygons then not everything needs to get changed - but a analysis of the gfx engine is
needed for that, maybe only the driving in higher resolution could be possible first

its way more complex than switching the segment from byte to para alignment :)

Quoteit's a learning experience. I learn by doing best. And that includes breaking it over and over again..

you need to understand that there is stuff that can eventually break (that is also hard to test stuff) and stuff , when done right cannot break - not everything is trial&error, there are some part of this workload that can be done in a uncluttered fashion - and these are the parts we should not also break due to misunderstanding, for example changing segment alignment from byte to para is one of these clean things


and all that would be much more doable when having C code (still not super easy) so the biggest workload gives us the biggest win - as usual in the reversing world :/

FYI: someone does that with Duke Nukem 2: https://github.com/lethal-guitar/Duke2Reconstructed - a full C reverse to 100% binary compatiblity - im am so envious :)
The "War-Story" on Twitter with all the dirty details: https://twitter.com/lethal_guitar/status/1575123187360227335 - read the follow up posts

Daniel3D


I know a bit of how memory works. But just don't know the right terms.
I know that stunts in its present situation is locked in base (conventional) memory.

And stunts does not have a separate graphics, physics and collision engine but has those jumbled into one pile of code.
That tangle will be difficult to unravel even if the code is ported to c.
That will take time.

My question therefore was that, if we plug in external code (by whatever means we can do effectively) are we still restricted to the memory allocation and graphics limitations of STUNTS?

You are absolutely right about the best ways to do this. I'm just curious.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Daniel3D

#51
For example. One thing I would like to change on short-term is increasing the 32 car limit.

This is not easily changed in the source. I know what part of the code handles this. There is a load function that loads 32 cars. Setting a lower number works as expected. Setting a higher number creates an error when trying to load a car beyond 32.
That would imply that the memory allocated for this is fixed at 32 times the 4 characters of the car. Whatever space that takes is a multitude of 8 so it makes sense. And going beyond that the game tries to read data that is reserved for other things.

Changing what memory is used is not possible in its current state. So increasing it is not possible within the current source.

Can you make a hack for this?

My idea was writing a new main menu with a new car/opponent selector and a different track selector /editor. I want to make this to increase playability and maybe increase interest in both the competitions and the reverse engineering. Draw new people by showing off the things we have done.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

QuoteAnd stunts does not have a separate graphics, physics and collision engine but has those jumbled into one pile of code.

it isn't called a "engine" because of physical separation, and no developer mixing up such code
they could be still very separated in the assembler code (never analysed them)

QuoteThat tangle will be difficult to unravel even if the code is ported to c.

the C code amount would be 5 to 8 times fewer lines - that would help alot

the problem is: you've never built something like that/or even the simplest form of that (according to your posts) on your own
so you've got nearly no background to estimate anything, you're just assuming on a very very high level

QuoteMy question therefore was that, if we plug in external code (by whatever means we can do effectively)
are we still restricted to the memory allocation and graphics limitations of STUNTS?

this is also a very strange question - nothing in a computer will just enhanced the capatility of a program - only if the constraints are memory, hard disk space or cpu-power hunger like for example a database system got

yes we will still be restricted - because the code itself limits it to this constraints, someone wrote code that is constraint that way and the compile generated cpu-code based on that constraints to make it small and fast, its like a house build of concrete where every dependcy (offset) is fixed, there are dynamic parts in there that could be changed easier - but not because its a standard but how this specific thing in the game was implemented

but i don't know if it makes sense to explain stuff like that to you because even a senior-level C application developer (without hardware or assembler background) couldn't follow easily - could be that you getting it all wrong or in a different way as intended :( - not your fault

QuoteFor example. One thing I would like to change on short-term is increasing the 32 car limit.

This is not easily changed in the source. I know what part of the code handles this. There is a load function that loads 32 cars. Setting a lower number works as expected. Setting a higher number creates an error when trying to load a car beyond 32.
That would imply that the memory allocated for this is fixed at 32 times the 4 characters of the car. Whatever space that takes is a multitude of 8 so it makes sense. And going beyond that the game tries to read data that is reserved for other things.

Changing what memory is used is not possible in its current state. So increasing it is not possible within the current source.

that means the needed change isn't at one point but spreaded over several functions
you need to expand the space for the cars - that will move data and code - therefor moving of data, code should be
safe, which means segments should para aligned and all non-symbolic offsets should be found, every change will always come
back to that point

QuoteCan you make a hack for this?

i can possibly technicaly do it, but i have no time lurking through the code for maybe weeks (and i want to work more on stunts)



Daniel3D

Quote from: llm on October 05, 2022, 06:59:00 PMthe problem is: you've never built something like that/or even the simplest form of that (according to your posts) on your own
so you've got nearly no background to estimate anything, you're just assuming on a very very high level

That is very true.

In this case I'd like to be proven wrong..

I also assumed that multi-player would not be possible. But that kind of seems to be possible without much effort.
What can ww make of that with more effort?
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on October 05, 2022, 08:30:30 PMI also assumed that multi-player would not be possible. But that kind of seems to be possible without much effort.
What can ww make of that with more effort?

there is much possible for a full blown developer with time :)

the multiplay-stunts(https://github.com/kurtis2222/stuntsmp) by kurtis2221 is using the CheatEngine (or direct memory read/write) to look through the dosbox-exe into Stunts memory - its technically like my extension of the dosbox source (the code hooking, variable watching) working with a specific version of dosbox+stunts, and then he adds TCP/IP from outside to control the keys and set variables of the opponents, i don't think he is patching or changing the game size at all (but the project source is very small and readable - so work yourselfe through it), but his
solution only works because of the 32/64bit dosbox environment, doing that in pure DOS would be much more harder, im not to deep into it but i can technically explain what and how he is doing it on a very deep level :)

im also using dosbox for doing different stuff - because the 16bit environment is so limited that i better work in the 32bit code of dosbox to "help" stunts doing the stuff i want (first win: even if the game is in segmented-memory, my own 32bit code works in pure linear style, i can do things that are not possible in the pure stunts code, like writing data with size over 64k in a for loop, copy memory of that size etc., trace data from every point in code into a textfile ...) - but that is also only doable with a good background of coding skills which kurtis2221 obviously got

BUT don't get me wrong here extending dosbox eases SOME modifications/ideas but no per default - extending game features
that are usable/seeable in game are still not easy because dosbox will not help changing the code of the game - its only easier to overwrite
behavior (sometimes) - but i don't know how you can do it without software development knowledge
working on a disassembled C based game of that size without any deep knowledge about how programming works is just very hard

look at my super-simple: dosbox/stunts branch: https://github.com/LowLevelMahn/dosbox-staging/tree/main_stunts_tests/src/_stunts
im using that code for tracing all data that gets outputed to the sound driver - its super easy code and all knowledge one need
is the very-same as kurtis2221 uses - know the offsets of functions/variables + how to hook stuff

or my also simple AlphaWaves branch of dosbox: https://github.com/LowLevelMahn/dosbox-staging/tree/main_alpha_waves_tests/src/_alpha_waves
which uses my tiny "emulator" in the uncompress function: https://github.com/LowLevelMahn/dosbox-staging/blob/b89837740a5ab65fc28548440b8de3d7c3516a49/src/_alpha_waves/_alpha_waves.cpp#L773
and this is the C-Port of that routine: https://github.com/LowLevelMahn/dosbox-staging/blob/b89837740a5ab65fc28548440b8de3d7c3516a49/src/_alpha_waves/_alpha_waves.cpp#L495

most of the time these reverse engineering projects use serveral strategies combined to reach the ultimate goal - that is totaly
different to real C/C++ source based projects were this type of cumulated strategies just not needed at all

Daniel3D

Quote from: llm on October 05, 2022, 06:59:00 PMsafe, which means segments should para aligned and all non-symbolic offsets should be found, every change will always come
back to that point
"non-symbolic offset" Like these lines?
    mov     di, 55CAh       ; offset in dseg where uninitialized data starts
    mov     cx, 0AD20h      ; original size/end of dseg
Link to the code in Bitbucket
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on October 10, 2022, 10:37:39 AM"non-symbolic offset" Like these lines?
    mov     di, 55CAh       ; offset in dseg where uninitialized data starts
    mov     cx, 0AD20h      ; original size/end of dseg

yes stuff like that - could be that there are many of these - or just a few - but every of these in-ables the code moveablitity - or could make it harder

so more or less every magic value that is a offset - but not

add sp,some-value

that is for stack-cleanup

Daniel3D

Quote from: llm on October 10, 2022, 11:55:43 AM
Quote from: Daniel3D on October 10, 2022, 10:37:39 AM"non-symbolic offset" Like these lines?
    mov     di, 55CAh       ; offset in dseg where uninitialized data starts
    mov     cx, 0AD20h      ; original size/end of dseg

yes stuff like that - could be that there are many of these - or just a few - but every of these in-ables the code moveablitity - or could make it harder

so more or less every magic value that is a offset - but not

add sp,some-value

that is for stack-cleanup
Assuming that the hex value is a number that corresponds to the line it seems to be a little off.
But i guess that the start of the file should be excluded from the line count as that is compiler info.

Or am i missing the bat again  ;)
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on October 10, 2022, 12:55:19 PMAssuming that the hex value is a number that corresponds to the line it seems to be a little off.
But i guess that the start of the file should be excluded from the line count as that is compiler info.

the hex value does NOT coresponds to a line number, NEVER - the hex-value is an byte-offset from the image start (behind the exe header), it depends on the size of code that sits before and every asm command is of different size in binary

for example: this is a assembler routine (not from stunts) - on the left is the binary-offset, then the binary code and the corespondig asm source

IDA-Offset  | Binary code | Assembler source
            |             |
seg000:BDF4 |             |  sub_1BDF4  proc near
seg000:BDF4 |             |                                   
seg000:BDF4 | 06          |            push    es
seg000:BDF5 | 1E          |            push    ds
seg000:BDF6 | 56          |            push    si
seg000:BDF7 | 57          |            push    di
seg000:BDF8 | 8D 36 76 BC |            lea    si, ds:0BC76h
seg000:BDFC | B9 06 00    |            mov    cx, 6
seg000:BDFF |            |
seg000:BDFF |            |  loc_1BDFF:                       
seg000:BDFF | 83 C6 04    |            add    si, 4
seg000:BE02 | 2E 8B 04    |            mov    ax, cs:[si]
seg000:BE05 | 2E 0B 44 02 |            or      ax, cs:[si+2]
seg000:BE09 | 74 02      |            jz      short loc_1BE0D
seg000:BE0B | E2 F2      |            loop    loc_1BDFF
seg000:BE0D |            |
seg000:BE0D |            |  loc_1BE0D:                       
seg000:BE0D | 2E 89 1C    |            mov    cs:[si], bx
seg000:BE10 | 2E 89 7C 02 |            mov    cs:[si+2], di
seg000:BE14 | 5F          |            pop    di
seg000:BE15 | 5E          |            pop    si
seg000:BE16 | 1F          |            pop    ds
seg000:BE17 | 07          |            pop    es
seg000:BE18 | C3          |            retn
seg000:BE18 |            |  sub_1BDF4  endp

Shellstorm disassembly of the same Binary code without symbolic offsets

0x0000000000000000:  06            push es
0x0000000000000001:  1E            push ds
0x0000000000000002:  56            push si
0x0000000000000003:  57            push di
0x0000000000000004:  8D 36 76 BC    lea  si, [0xbc76]
0x0000000000000008:  B9 06 00      mov  cx, 6
0x000000000000000b:  83 C6 04      add  si, 4
0x000000000000000e:  2E 8B 04      mov  ax, word ptr cs:[si]
0x0000000000000011:  2E 0B 44 02    or  ax, word ptr cs:[si + 2]
0x0000000000000015:  74 02          je  0x19 <-- jmp offset
0x0000000000000017:  E2 F2          loop 0xb <-- jmp offset
0x0000000000000019:  2E 89 1C      mov  word ptr cs:[si], bx
0x000000000000001c:  2E 89 7C 02    mov  word ptr cs:[si + 2], di
0x0000000000000020:  5F            pop  di
0x0000000000000021:  5E            pop  si
0x0000000000000022:  1F            pop  ds
0x0000000000000023:  07            pop  es
0x0000000000000024:  C3            ret 

so "lea si, ds:0BC76h" is encoded in the exe as {8D 36 76 BC}

Daniel3D

Quote from: llm on October 10, 2022, 01:23:38 PMthe hex value does NOT coresponds to a line number, NEVER - the hex-value is an byte-offset from the image start (behind the exe header), it depends on the size of code that sits before and every asm command is of different size in binary
I was fearing that.

So to make a symbolic offset out of it you must first find the correct byte offset and locate it in the assembly code?

Looking at your example i guess it is not very difficult for you. But i understand why they are not all done.

If i find more (i now have an idea of what they look like) and they are not commented as such I'll make a note of it.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)