Giter Club home page Giter Club logo

sfall-asm's People

Contributors

ghost2238 avatar wipe2238 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

sfall-asm's Issues

Generation of assert patches

Write some code to generate assert patches. This will be useful for checking that some code region is exactly what we expect it to be.

Will be useful in cases like this: https://github.com/rotators/Fo1in2/blob/master/Fallout2/Fallout1in2/Mapper/source/scripts/headers/voodoo.h#L255-L256 - Since we aim to be compatible with future sfall versions, if this specific hook ever changes, we can avoid applying the patch and display a loud message instead of overwriting some unknown code.

Malloc improvements

//! NAME ???

//! SSL !//
call VOODOO_MakeCall(0x442c22, VOODOO_???__patch);
call VOODOO_WriteNop(0x442c22+5);
//! ASM !//
/// hook
[patch]  | 60            | pushad
// <insert crazy asm here>
00000000 | 61            | popad
/// restore
00000000 | 8915 CC865100 | mov dword ptr ds:[<_game_user_wants_to_quit>],edx
00000000 | C3            | ret

Just a stub, as i'm not quite sure where pointers array should be stored.

This is almost same thing as sfall::LoadGameHook::OnGameReset(), except there is no check if map has been loaded or not; it will be called when leaving main menu as well. So far can't find better place to free() malloc-patches.

Address extraction too fragile

Address extraction might fail on patches which contain extra data about addresses

$ ==>    100288B4 <f2_res.main_loop> | 8917    | mov dword ptr ds:[edi],edx | 
$+2      100288B6                    | 83C7 04 | add edi,0x4 | ย 

Easy to fix but i'm currently in a middle of another SSLCode rework and far from successful compilation. Leaving it here if you're bored or as reminder after i'm done with my mess.

Allow updating header with user code

I though i'd like having auto-generated code in separate header, but it's been only few hours and i already meh at it :p

Needs adding --update=[filename] which will look for part of file which can be overwritten (between ^/[/]+[\t ]+sfall-asm-(begin|end)[\t ]+/[/]+$ tags), leaving other parts of file unchanged.

Switch to using `$` in global variables

Apparently $ can be used in variables names and variable $name is perfectly fine in CAH. Which is great actually, as none of scripts uses such naming (and probably never will) so we can be sure variables we add to scripts global scope won't conflict with regular variables (even if we use very generic names).

TODO after FO1@2 v1.1 release

06:38 < lexx> great, tp to mariposa crashes the game
06:38 < lexx> tp to anywhere crashes the game
06:39 < lexx> i bet it#s related to you peoples voodoo stuff again
06:40 < lexx> ok updating latest scripts fixed it.. your luck

(Spoiler: i have no idea what could cause it so i'm happy it autofixed itself ๐Ÿ˜…)

Make patches address independant

To further support rotators/Fo1in2#41, make it possible to write patches that are not hardcoded to specific memory addresses.

For operations such as E8 (CALL) or E9 (JMP) which use rel16/32 addresses we need to mark these with some meta syntax containing the absolute address within the module so that we can while generating the patch calculate the relative offset from some current address (based on what's being set as the base address).

The alternative is to use far CALL/JMP, either FF /4 or FF /5 in the patches instead. Since this uses the reg/op field byte, I think this not a great solution if there's a lot of jumps in the code.

Right now, the memory address 0 denotes an incremented address that continues from a previously specific address. Maybe we can use [<identifier>] for both memory variables and absolute addresses.

The memory variables would then be resolved by using some CLI arguments, perhaps --memory-args="patch_code=0x41AE86;"

It might also be a good idea to implement some patchset files where you set one memory address, e.g. main_selfrun as proposed in rotators/Fo1in2#41 (comment), specify which patches you want, then the correct sfall script code is generated with aligned memory addresses that don't collide. This allows doing length checks to avoid using more code memory than available.

Using dialog_money_fix.asm as a basis for this example since it's short:

00447ACD     | E9 [patch_code] | jmp [patch_code]
[patch_code] | 60              | pushad
00000000     | E8 [0x446D30]   | call fallout2.gdProcessUpdate_
00000000     | 61              | popad
00000000     | E8 [0x4D6DAC]   | call fallout2.win_show_
00000000     | E9 [0x447AD2]   | jmp fallout2.447AD2

References

http://ref.x86asm.net/coder32.html#xE8 - E8/E9 encoding
https://www.felixcloutier.com/x86/jmp - Different jumps

VOODOO_Alloc called too early

//! NAME some

//! SSL !//
$addr := "macarena";
display_msg("ayyy " + $addr + "!");
//! ASM !//
/// hook
[[code]] | 60 | pushad
00000000 | 61 | popad
#define VOODOO_ID_some_code  1

#define VOODOO_some \
              begin                                             \
               $addr := "macarena";                             \
               $addr := VOODOO_Alloc(VOODOO_ID_some_code, 2);   \
               display_msg("ayyy " + $addr + "!");              \
               /* hook */                                       \
               write_byte($addr,   0x60); /* pushad */          \
               write_byte($addr+1, 0x61); /* popad */           \
              end                                               \
              noop

Not sure what's going on here, but it seems VOODOO_Alloc is always called on 2nd line of body, even if there's custom ssl present. Scenario above shows what can possibly go wrong, if macro needs temporary var and decides to use $addr

Surround macros with begin/end when needed

Now that most of voodoo is going to be generated from patchfiles, it's probably a good idea to add begin/end automagically to macros when needed.

Counting writes is easy now (just add counter in first Lines iteration, where macro body width is calculated), and adding begin/end is already there for --procedure option. Low hanging fruit and prevents bugs like rotators/Fo1in2#36 in future.

Asm utility code

If we want to stay sane while being sfall vanilla compatible, we need a few utility functions that can also be depended on in patches, meaning they can be called with a E8 [util::VirtualProtect] (after pushing appropriate args)

I have two functions in mind right now which are connected:

GetSfallFuncAddress - Get address to sfall::SomeFunc+0x1207

Something similar to:

0041AE06 | 2EA1 70464C00    | mov eax,cs:[4C4670]
/// Calculate where ddraw.sfall::wmAreaMarkVisitedState_hack+0x51 is
0041AE0C | BA C5464C00      | mov edx,fallout2.4C46C5
0041AE11 | 01D0             | add eax,edx
0041AE13 | 89C6             | mov esi,eax

Would be used like this:

push [jmp/call offset + 1] 
004C466F | E9 AC451702 
              ^------ this is the address that we need to push, the one after a jmp/call instruction
push [offset in the sfall handler func that we are interested in, for instance 0x51]
call [utility.GetSfallFuncAddress]
// Now the result is in eax, as expected

VirtualProtect

We can find the address of Kernel32's VirtualProtect by using the location of a known HRP hook in Fallout2.exe, since we know all the addresses relative to some hook that we can assume will always be there, we can easily find VirtualProtect and call it with pushed args.

This is needed for patches modifying sfall code.

Meta code

While we are doing all this in a code generation mode, why not just drop the need to write manual asm and allow the use of some meta function convention like <util::GetSfallFuncAddress(0x4C4670, 0x51)> in the patches.

Which generates the following code:

push 0x4C4670
push 0x51
call [rel_address to util::GetSfallFuncAddress]

Not a huge difference in this case, but might be useful for other things.

More useful is util::SetSfallCode(0x4C4670, 0x51, 0x0) - which will generate code bytes with the same functionality as no_location_radius.asm

In the end, it doesn't even...

Yay, nay, meh?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.