Page 1 of 1

Script causes crash only sometimes, for certain people

Posted: Mon May 15, 2017 4:50 pm
by arlight1
I've got a strange issue/bug with one of my scripts. I made a 100% accuracy hack in Mass Effect. What's weird is that only like 1/5 times the script will cause the game to crash. Not entirely sure why. I can get it working on my PC most of the time. On other people game, it will also crash 1/5 times. Anyone know why it would happen? It's a fairly straightforward script. It crashed when enabled.

Code: Select all

[ENABLE]
aobscanmodule(crossSpreadReplace,MassEffectAndromeda.exe,F3 0F 58 F9 F3 0F 11 BB ?? ?? ?? ?? 0F 28 7C 24 ?? 48)
globalalloc(crossSpreadOriginalWhole,12)
globalalloc(crossSpreadOriginalOffset,4)

crossSpreadOriginalWhole:
  readmem(crossSpreadReplace,12) // Read the entire two instructions to be replaced

crossSpreadOriginalOffset:
  readmem(crossSpreadReplace+8,4) // Read just the '??' bytes

crossSpreadReplace: // Write the new instruction to replace previous two. MOV [rbx+??],#0 and two NOPs for equal bytes replaced 
  db C7 83
  readmem(crossSpreadOriginalOffset,4)
  db 00 00 00 00 90 90

registersymbol(crossSpreadReplace)

[DISABLE]
crossSpreadReplace:
  readmem(crossSpreadOriginalWhole,12) // Replace with original two instructions

unregistersymbol(crossSpreadReplace)

Re: Script causes crash only sometimes, for certain people

Posted: Mon May 15, 2017 6:17 pm
by Squall8
Did you check to see if the instruction you used is shared?

Re: Script causes crash only sometimes, for certain people

Posted: Mon May 15, 2017 7:04 pm
by arlight1
Squall8 wrote:
Mon May 15, 2017 6:17 pm
Did you check to see if the instruction you used is shared?
It is shared. By a few other addresses. However over-writing them doesn't seem to do anything. Previous versions of the script simply insert code to jump and over-write all address to #0. Never experienced a crash then, and never got reports of crashed. Only when I modified it to re-write in-line with the function did the crashing begin.

Re: Script causes crash only sometimes, for certain people

Posted: Mon May 15, 2017 8:54 pm
by Squall8
EDIT:
Sorry messed up earlier. Corrected my mistake.
/-----------------------------------------------------------------------------------/
Is the instruction you're trying to manipulate the one changing after a restart?

I haven't really messed with readmem at all, but from what I understand, readmem needs an address/symbol and/or offset plus the size in bytes as a parameter, which you have done. I just think you may have set up your script wrong.

I would try this:

Code: Select all

aobscanmodule(crossSpreadReplace,MassEffectAndromeda.exe,F3 0F 58 F9 F3 0F 11 BB ?? ?? ?? ?? 0F 28 7C 24 ?? 48)
alloc(saveaob,18)
registersymbol(crossSpreadReplace)
registersymbol(saveaob)


saveaob:
readmem(crossSpreadReplace,18)

crossSpreadReplace+8:
//your code here

[disable]
crossSpreadReplace:
readmem(saveaob,18)
unregister(blah)
dealloc(blah)

Again I could be phrasing that wrong but its still worth a try. Let me know if that helped.

Re: Script causes crash only sometimes, for certain people

Posted: Thu May 18, 2017 2:34 pm
by arlight1
Squall8 wrote:
Mon May 15, 2017 8:54 pm
EDIT:
Sorry messed up earlier. Corrected my mistake.
/-----------------------------------------------------------------------------------/
Is the instruction you're trying to manipulate the one changing after a restart?

I haven't really messed with readmem at all, but from what I understand, readmem needs an address/symbol and/or offset plus the size in bytes as a parameter, which you have done. I just think you may have set up your script wrong.

I would try this:

Code: Select all

aobscanmodule(crossSpreadReplace,MassEffectAndromeda.exe,F3 0F 58 F9 F3 0F 11 BB ?? ?? ?? ?? 0F 28 7C 24 ?? 48)
alloc(saveaob,18)
registersymbol(crossSpreadReplace)
registersymbol(saveaob)


saveaob:
readmem(crossSpreadReplace,18)

crossSpreadReplace+8:
//your code here

[disable]
crossSpreadReplace:
readmem(saveaob,18)
unregister(blah)
dealloc(blah)

Again I could be phrasing that wrong but its still worth a try. Let me know if that helped.
Thanks for this Squall. Turn out your premise is correct. The order you allocate/write to memory DOES matter in CE. It is problematic to have readmem and allocating that same readmem you do in the same script. You can do nested scripts and that prevents crashing. The reason there were crashes only some of the time was because that readmem that's based on saving the original bytes was empty. The first readmem that saves the bytes hadn't yet allocated and saved them in time for the next readmem to pull from the bytes and place them in the assembly code. This could be a CE bug, considering how you view its implementation, but more than likely just something the users have to be aware of when creating scripts in the future.

Re: Script causes crash only sometimes, for certain people

Posted: Thu May 18, 2017 2:46 pm
by arlight1
SunBeam wrote:
Thu May 18, 2017 2:40 pm
Here's my take on this: when you allocate memory with CE, make sure you specify the PROCESS: I've seen several pieces of code above (alloc(name,size)) with no game .exe specified. There are situations when CE allocates the memory outside the process and any subsequent scripts using references to the allocation will fail to find the symbol and won't enable. Or get enabled and crashes occur.
Holy shit, I'm so glad you mentioned this! I'm having a problem dereferencing a pointer right now with a cheat I'm making! I first do:

Code: Select all

codeDirect:
  add [rax+08],edi
  mov [saveScoreLoc],rax
  cmp byte ptr [rsp+000000B0],00
  jmp returnDirect

saveScoreLoc:
  dd 0x0
to save the pointer of rax, which [rax+08] is the player's score in a game.

Then in a seperate part of that script I try to do

Code: Select all

maxLevel:
  push ecx
  lea ecx,[appliedMaxLevel+08]
  cmp dword ptr [appliedMaxLevel],ecx // Check if insant lvl 20 has been applied once already
  jge maxLevelApplied
  pop ecx
but when I break and trace what's being written to ecx, the value is simply zero. If I simply do

Code: Select all

maxLevel:
  push ecx
  lea ecx, [appliedMaxLevel]
  cmp dword ptr [appliedMaxLevel],ecx // Check if insant lvl 20 has been applied once already
  jge maxLevelApplied
  pop ecx
I get ecx simply being the address of the memory location. I can't dereference it at all to show the original player value I stored. But when I add a pointer in the CE table manually and type in the memory location with offset, I'm able to dereference it properly and get it to show the player score...what gives?
Image

Re: Script causes crash only sometimes, for certain people

Posted: Thu May 18, 2017 4:35 pm
by arlight1
SunBeam wrote:
Thu May 18, 2017 3:53 pm
First up, make sure the hook where you store saveScoreLoc is accessed (used) before maxLevel is run. it's possible that code with maxLevel gets run (called) from other locations as well.
Yup! It is! maxLevel script is a child script to the saveScoreLoc. saveScoreLoc must be run before a value will be assigned, of course. Otherwise, it's just ?? or no data.