peddroelm Advanced Cheater Reputation: 0
Joined: 03 Oct 2014 Posts: 84
|
Posted: Thu Mar 29, 2018 2:32 am Post subject: Clarifications on unrandomizer for noobs (such as myself :P) |
|
|
Context:
Working on reverse engineering various damage related game mechanics on Last Remnant (most games of today really) one inevitably has to deal with the randomization functions the game uses.
Last Remnant is a particularly offensive example since it makes extensive use of RNG / dice rolls behind the scenes .. (and the player base, even 10+ years after release, still has no clue what even the base attributes for the characters do )
Unrandomizer does a few array of bytes signature searches [for EXECUTABLE CODE ] for various randomizer functions typically used by the industry :
https://github.com/cheat-engine/cheat-engine/blob/master/Cheat%20Engine/unrandomizer.pas
DELPHI, VC++, msvcrt.rand, ibasic random
and does a replace for the begining of the function code with opcodes(4 bytes) for
mov eax, value_to_be_returned_HEX //
ret
Right click on the activated randomizer shows the memory addresses for the found and replaced functions.
Adding those addresses manually in the table ( type array of bytes; size 4) and then right clicking on the value and 'Dissasemble this memory region' will take you right at the edited code (
mov eax, value_to_be_returned_HEX
ret )
{many people in the returned google searches complained about editing the 4 byte value at the addresses listed by the unradomizer button and crashing the game. Yup editing executable code with and immediate value will do that (crash) every time. Unrandomizer doesn't just change a constant - it changes in opcodes for CODE that returns a constant. If you want do edit it Dissasemble this memory region' and use the assembler code section of the memory view window NOT 'browse this memory region' for the 'Data view' section of the memory view window}
One could set execution breakpoints on this instruction and run the interesting action in game (even JUST THE NUMBER of dice rolls performed by a sequence of actions = nr of breakpoint hits can be very VALUABLE INFORMATION) .
And if one needs the randomizer to return a specific sequence of values ..one can change the returned value after each breakpoint hit .. {I suppose CE could even do pop -up text inputbox for each RNG function call to ask for the value to be returned}
Also useful once you figure which RNG call in a sequence of RNG calls for a sequence of actions in game is damage randomization you can step trough on that one -> should place you very near damage calculation code .. might offer a chance to figure out new things that way ..
ex:
Code: | addressbp1=0x12844F80 // put in the address of RNG function modified by unmodifier
timevar = 0
function debugger_onBreakpointBP1()
RNGreturnedNR= inputQuery('Input RNG Pop-UP', 'enter the RNG value to return INTEGER', 0)
//
// change opcode at addressbp1 into:
// move eax, RNGreturnedNR
// ret
// how ?!
debug_continueFromBreakpoint(co_run)
return 1
end
debug_setBreakpoint(addressbp1, 4, bptWrite , debugger_onBreakpointBP1)
|
also is it already too late ? (instruction already executed ?)
//////// even between the combat turns the RNG breakpoint fires constantly in TLR .. Probably to decide what iddle animations to play while iddle .. Also during the attack animations .. HUNDREDS OF RNG calls per weapon swing
Need to find better place to move the breakpoint ..
|
|