ghost2238 / sfall-asm Goto Github PK
View Code? Open in Web Editor NEWUse binary patches with sfall without doing a lot of tedious manual work.
Use binary patches with sfall without doing a lot of tedious manual work.
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.
//! 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 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.
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.
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
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
http://ref.x86asm.net/coder32.html#xE8 - E8/E9 encoding
https://www.felixcloutier.com/x86/jmp - Different jumps
//! 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
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.
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:
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
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.
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
Yay, nay, meh?
00480C90 | 6666:90 | nop |
00480C93 | 33FF | xor edi,edi |
It's time for a --malloc
option now that we have a few key things implemented in SSL meaning we can calculate relative jumps during runtime with ease.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.