Discuss 64 bit ASM injection

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

constipatedgoblin

Newbie
Full Member
May 26, 2017
5
52
0
Hello , I recently discovered this community and decided to start a thread about what it is I am currently trying to do. I apologize in advance if this should be in a different forum section and bear with me as english is not my native tongue.
So back in the day when I used to hack games (mostly single player titles) there is this particular method I used to follow. Through debugging I would isolate a specific assembly instruction which I would then overwrite with a jump to memory I had allocated. Execution would continue there where I would first push all registers onto the stack using 'pushad', do whatever it is I wanted to do in there and then pop all the registers back to their original state and jump back to the game's own code.
For the past couple days I've been preoccupied with Skyrim Special Edition and it is the first time I am working with a 64 bit game. I have noticed a bunch of new registers and to my surprise x86_64 assembly does not have a pushad instruction so in order for me to do this I am guessing I am going to have to push all the registers one by one. I've also noticed there are these so called segment registers which I am not sure if I am supposed to save or not and I have read that in 64 bit mode they cannot be pushed so I'd have to first move them into a regular register and then push to the stack.
I was wondering if anyone here had experience with 64 bit games and ASM injection, any pointers and/or suggestions would be appreciated.
 

V-X

Newbie
Dank Tier Donator
Jan 12, 2014
15
1,918
0
I have a few threads that may pique your interest, as for pushing all registers in 64 bit, there isn't any way to my knowledge to do it without doing it individually as stated, usually, people make a pushad macro and just use that. Here's a snippet for x64 pushad
[ASM];**************************************************************************************
;PUSHAQ: Emulates the 'pushaq instruction' under long mode.
;
; Input: --
;
; Output: --
;
;**************************************************************************************
align 8
macro PUSHAQ
{
;Save registers to the stack.
;--------------------------------

push rax ;save current rax
push rbx ;save current rbx
push rcx ;save current rcx
push rdx ;save current rdx
push rbp ;save current rbp
push rdi ;save current rdi
push rsi ;save current rsi
push r8 ;save current r8
push r9 ;save current r9
push r10 ;save current r10
push r11 ;save current r11
push r12 ;save current r12
push r13 ;save current r13
push r14 ;save current r14
push r15 ;save current r15

} ;end of macro definition

;**************************************************************************************
;POPAQ: Emulates the 'popaq instruction' under long mode.
;
; Input: --
;
; Output: --
;
;**************************************************************************************
align 8

macro POPAQ
{
;Restore registers from the stack.
;--------------------------------

pop r15 ;restore current r15
pop r14 ;restore current r14
pop r13 ;restore current r13
pop r12 ;restore current r12
pop r11 ;restore current r11
pop r10 ;restore current r10
pop r9 ;restore current r9
pop r8 ;restore current r8
pop rsi ;restore current rsi
pop rdi ;restore current rdi
pop rbp ;restore current rbp
pop rdx ;restore current rdx
pop rcx ;restore current rcx
pop rbx ;restore current rbx
pop rax ;restore current rax

} ;end of macro definition[/ASM]
 

constipatedgoblin

Newbie
Full Member
May 26, 2017
5
52
0
One more question, for now. I will be using the cmp instruction to compare a register with 0, shouldn't I push the flags up the stack as well before it ?
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,298
37,938
269
If you'd like, sure. But unless you've replaced an instruction that modifies the zf and theres no other ones ahead, and there's a conditional instruction; then there's really no point.
 

constipatedgoblin

Newbie
Full Member
May 26, 2017
5
52
0
What can you tell me about the size of jmp instructions ?
If I remember correctly back in the day when I was working on 32 bit games jmp's used to always take up 5 bytes. Right now the jmp I use to overwrite the original code seems to be taking up 14 bytes, is it always going to be like that regardless of the address I jump to or could the size vary depending on where exactly I am jumping ?
 
Last edited:

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
What can you tell me about the size of jmp instructions ?
If I remember correctly back in the day when I was working on 32 bit games jmp's used to always take up 5 bytes. Right now the jmp I use to overwrite the original code seems to be taking up 14 bytes, is it always going to be like that regardless of the address I jump to or could the size vary depending on where exactly I am jumping ?
Yes, size matters.
There are basically 4 types of jumps:
EB XX: relative jump (signed byte)
E9 XX XX XX XX: relative jump (signed 4 byte)
FF 25 XX XX XX XX (...) XX XX XX XX XX XX XX XX: absolute jump (unsigned 8 byte), first four bytes point relative to the 8 bytes which contain the actual address
Jumping to a register like mob rax, 177384 and then jmp rax takes 12 bytes
 

constipatedgoblin

Newbie
Full Member
May 26, 2017
5
52
0
FF 25 XX XX XX XX (...) XX XX XX XX XX XX XX XX: absolute jump (unsigned 8 byte), first four bytes point relative to the 8 bytes which contain the actual address
Jumping to a register like mob rax, 177384 and then jmp rax takes 12 bytes
Could you elaborate on what you mean by the first four bytes pointing relative to the 8 bytes that contain the address ?
When using Cheat Engine's auto assembler it seems those first 4 bytes are always 0s
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
Yes, because it's directly behind the actual jump instructions:

This is basically "jmp qword ptr [kernel32.dll+506]" but cheat engine just shows it this way.

Here's an example of how it looks if the offset isn't 0:

In this case the actual jump instruction is at kernel32.dll+512 and the offset is 2 bytes.
That means that the address is stored at kernel32.dll+512 +6 (instruction size) +2 (offset) = kernel32.dll+51A (as you can see in the green text in the first line).
 

constipatedgoblin

Newbie
Full Member
May 26, 2017
5
52
0
Now a question regarding how you guys handle code injections, do you write inline assembly and then copy the memory over to the target application or do you write down the byte sequences directly and copy them instead ?
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
I use byte arrays like this:
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods