Jump to content
  • 0

How to make JMP/BR Opcode Injections in ARM64


Question

Posted

Hello scientists,

I am trying to make Opcode Injections for a game runs in ARM64 Device. 

In order to do that I have to use BR (Branch to Register). But I am currently getting error in GG and says : failed to organize arm64 opcode (movz x0, #0xE000).

I already allocated memory page it starts from address 78D26AE000 and here is the ARM64 Assembly Code I want to use :

movz x0, #0xE000
movk x0, #0x6AE0, LSL #16
movk x0, #0x78D2, LSL #32
br x0

The reason Im doing this because I want to inject this ARM64 Assembly Opcode in the game :

mov w0,w21

So I can check if W21 is equals to (0xB0FF) then change it to (0xB0CC) using this ARM64 Assembly Opcode :

cmp w21, #0xb0ff       
b.ne continue 
mov w21, #0xb0cc
continue:
// the remaining code.

Any helps or is there a better way to do it?

Kind regards. 

6 answers to this question

Recommended Posts

  • 0
Posted (edited)

[ @GuyLian ]
---

Quote

failed to organize arm64 opcode (movz x0, #0xE000)

Have you tried to change it as Hex (not as ~A8) ?
---

Quote

I already allocated memory page it starts from address 78D26AE000 and here is the ARM64 Assembly Code I want to use

Have you tried with mov?

mov x0, #0xE000
movk x0, #0x6AE0, LSL #16
movk x0, #0x78D2, LSL #32

---

Quote

So I can check if W21 is equals to (0xB0FF) then change it to (0xB0CC) using this ARM64 Assembly Opcode :

Can you tell me what you're trying to achieve?

---

Edited by kiynox
  • 0
Posted
11 hours ago, kiynox said:

Can you tell me what you're trying to achieve?

 

Hello @kiynox 

Thanks for your reply.

So basically I have this ARM64 Code :

mov w0,w21

I want to change W21 value if it's equals to (0xB0FF) then change it to (0xB0CC) that's it.

I am new to Game Guardian and it's powerful tool and I enjoy using it. I will be very thankful If you can help me 🙂

  • 1
Posted

[ @GuyLian ]
---

Quote

I want to change W21 value if it's equals to (0xB0FF) then change it to (0xB0CC) that's it.

The reason I ask you is because:

  • Software/Hardware sets the register value at current state, meaning that you need to change all/specific instruction that does "mov w21, 0xB0FF" to "mov w21, 0xB0CC"
  • Since the value on the register is often changing (based on current execution), meaning that you need to always hook the register/watch any changes into register. You can't done this using Game Guardian, it is only for Memory editing not debugging. You need to use Memory Debugging app like GDB or Ghidra.
  • Your ARM64 Assembly OPCode: ("cmp w21, #0xb0ff ...") will not affect anything since it is not being executed. Beside using Memory Debugger, you can also create seperate thread within the App (Like Mod Menu) to always constantly check for Register value. Although this is bad, constantly checking register means that it is resource extensive and the thread will likely killed by the OS. Yes, Android have auto-prevention that will shut threads/apps that resource extensive (Phantom processes).

---
Albeit, constantly checking Register value is bad in general and not doable in Game Guardian for reasons above. Better just changing any "mov w21, 0xB0FF" instruction into "mov w21, 0xB0CC".

  • 0
Posted

Hello @GuyLian Yes game guardian fails to assemble quite a lot of opcodes especially those which involve immediate values.

Option 1: To circumvent a similar situation I had in the past patching Payback 2 in an armv7-a device(though im sure it will work here too) , you could patch the binary(lib.so or whatever) before opening the game so that you can use an external assembler.

Option 2: Try to use an alternative command e.g

instead of 

mov w0, w21

you could use 

add w0, w21, wzr

Adjusting to specific needs.

Option 3: Try to break the commands down even further because I think gamegurdian fails to assemble it into specific immediate number. E.g 

mov w1, #2000

but it failed to assemble so i had to

mov w1, #1990

which worked so the code had to be changed to

mov w1, #1990
add w1, w1, #10

 

Remember to reinsert all replaced code into the destination after you are done

  • 0
Posted (edited)

[ @Silento ]
---
OP wants 2 things: constantly check register value & load allocated memory. So I will cover more about loading memory allocation, since we don't know yet what this memory allocation holds, either instruction/strings:

  • - If it's single instruction, then the OP is in right direction using mov pair (mov, movk, movz), to load immediate address. If it's fails, then you can use ADRP/ADD pair or using Offset/PC relative address, as most instruction doesn't support immediate address.
ldr x0, 0x100 --Offset/PC relative (ldr address to our target address)

---

Edited by kiynox
  • 0
Posted (edited)

@kiynox

I kind of thought the OP wanted to branch to the code cave to insert his altering code and he failed to do so because game guardian failed to assemble his first branching opcode.

If I'm right then yes you are right. The OP should use the ADRP/ADD pair. Why didn't I thjnk of it in my past encounter? That would have made it a lot easier in my case instead of doing it the hard way as my first reply.

 

 

Edited by Silento
Elaboration

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.