View previous topic :: View next topic |
Author |
Message |
predprey Master Cheater
Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Sun Oct 11, 2015 6:13 pm Post subject: Auto Assembler adding extra nop on jmp? |
|
|
When enabling a script such as the one below which uses a label, auto assembler adds 4 nop opcode after the jmp command. This was using x64 CE on a x64 application. An example script is like the one below:
Code: | [ENABLE]
aobscan(INJECT,XX XX XX XX XX)
alloc(newmem,$1000)
label(code)
label(return)
newmem:
jmp code
code:
jmp return
INJECT:
jmp newmem
return:
registersymbol(INJECT)
[DISABLE]
INJECT:
db XX XX XX XX XX
unregistersymbol(INJECT)
dealloc(newmem) |
Enabling the above script would result in a jump to newmem with the following code:
Code: | jmp code
nop
nop
nop
nop
jmp return |
Is the extra nop added for optimization purposes on x64? Or is it an unintended bug by auto assembler?
Last edited by predprey on Sun Oct 11, 2015 7:02 pm; edited 1 time in total |
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Oct 11, 2015 6:50 pm Post subject: |
|
|
It is added because the instructions you overwrite with your injection take up that many bytes.
If it didn't NOP those, the JMP back to RETURN would be in the middle of one of those overwritten instructions.
Your computer would then run as if that was the beginning of some instruction, likely crashing.
|
|
Back to top |
|
 |
predprey Master Cheater
Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Sun Oct 11, 2015 7:02 pm Post subject: |
|
|
sorry, forgot to change the "jmp code" under INJECT: to "jmp newmem". so I think what you meant was the original code XX XX XX XX XX would become XX XX 90 90 90. I was referring to the injected code under newmem, where instead of Code: | jmp code
jmp return
| it adds the 4 (redundant) nop in between both jumps
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Oct 11, 2015 7:12 pm Post subject: |
|
|
That is what I was referring to as well.
Look at the code at your injection site when you activate the script.
It overwrites multiple instructions.
The number of bytes you write must match the number of bytes the previous instructions used.
|
|
Back to top |
|
 |
predprey Master Cheater
Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Sun Oct 11, 2015 7:46 pm Post subject: |
|
|
ok here's a more "complete" script to make things clearer
Code: | [ENABLE]
aobscanmodule(WeaponsAOB,fftype0hd.exe,03 FD 3B 3D 12 84 62 00) // should be unique
alloc(WeaponsAOB_newmem,1024,"fftype0hd.exe"+30E3E)
label(WeaponsAOB_code)
label(WeaponsAOB_return)
label(WeaponsAOB_backup)
WeaponsAOB_newmem:
add edi,ebp
cmp edi,63
jge WeaponsAOB_code
mov edi,63
WeaponsAOB_code:
//cmp edi,[fftype0hd.exe+659258]
cmp edi,0
jmp WeaponsAOB_return
WeaponsAOB_backup:
readmem(WeaponsAOB,8)
WeaponsAOB:
jmp WeaponsAOB_newmem
nop
nop
nop
WeaponsAOB_return:
registersymbol(WeaponsAOB)
registersymbol(WeaponsAOB_backup)
[DISABLE]
WeaponsAOB:
//db 03 FD 3B 3D 12 84 62 00
readmem(WeaponsAOB_backup,8)
unregistersymbol(WeaponsAOB_backup)
unregistersymbol(WeaponsAOB)
dealloc(WeaponsAOB_newmem)
{
// ORIGINAL CODE - INJECTION POINT: "fftype0hd.exe"+30E3E
"fftype0hd.exe"+30E20: 48 83 C2 04 - add rdx,04
"fftype0hd.exe"+30E24: 41 3B C9 - cmp ecx,r9d
"fftype0hd.exe"+30E27: 7C EC - jnge fftype0hd.exe+30E15
"fftype0hd.exe"+30E29: EB 03 - jmp fftype0hd.exe+30E2E
"fftype0hd.exe"+30E2B: 4C 8B D2 - mov r10,rdx
"fftype0hd.exe"+30E2E: 4D 85 D2 - test r10,r10
"fftype0hd.exe"+30E31: 74 4B - je fftype0hd.exe+30E7E
"fftype0hd.exe"+30E33: 41 0F B7 7A 02 - movzx edi,word ptr [r10+02]
"fftype0hd.exe"+30E38: 66 41 89 32 - mov [r10],si
"fftype0hd.exe"+30E3C: 8B CF - mov ecx,edi
// ---------- INJECTING HERE ----------
"fftype0hd.exe"+30E3E: 03 FD - add edi,ebp
"fftype0hd.exe"+30E40: 3B 3D 12 84 62 00 - cmp edi,[fftype0hd.exe+659258]
// ---------- DONE INJECTING ----------
"fftype0hd.exe"+30E46: 7F 0A - jg fftype0hd.exe+30E52
"fftype0hd.exe"+30E48: 66 41 89 1A - mov [r10],bx
"fftype0hd.exe"+30E4C: 8B 3D 06 84 62 00 - mov edi,[fftype0hd.exe+659258]
"fftype0hd.exe"+30E52: 3B 3D 04 84 62 00 - cmp edi,[fftype0hd.exe+65925C]
"fftype0hd.exe"+30E58: 0F 4F 3D FD 83 62 00 - cmovg edi,[fftype0hd.exe+65925C]
"fftype0hd.exe"+30E5F: 66 41 89 7A 02 - mov [r10+02],di
"fftype0hd.exe"+30E64: C6 05 E5 83 62 00 01 - mov byte ptr [fftype0hd.exe+659250],01
"fftype0hd.exe"+30E6B: 45 84 F6 - test r14l,r14l
"fftype0hd.exe"+30E6E: 75 0E - jne fftype0hd.exe+30E7E
"fftype0hd.exe"+30E70: 3B F9 - cmp edi,ecx
} |
activating that would result in this at the injection site which i believe is what you are referring to where the original instructions are nopped so as not to disturb the offsets in memory.
Code: | WeaponsAOB - E9 BDF1FAFF - jmp 7FF620410000
fftype0hd.exe+30E43- 90 - nop
fftype0hd.exe+30E44- 90 - nop
fftype0hd.exe+30E45- 90 - nop |
meanwhile at the code cave, auto assembler writes these instructions
Code: | 7FF620410000 - 01 EF - add edi,ebp
7FF620410002 - 83 FF 63 - cmp edi,63
7FF620410005 - 7D 09 - jnl 7FF620410010
7FF620410007 - 90 - nop
7FF620410008 - 90 - nop
7FF620410009 - 90 - nop
7FF62041000A - 90 - nop
7FF62041000B - BF 63000000 - mov edi,00000063
7FF620410010 - 83 FF 00 - cmp edi,00
7FF620410013 - E9 2E0E0500 - jmp fftype0hd.exe+30E46 |
what i'm confused is why it adds the 4 nop when they are not written in the script. sorry for the unclear post but thanks for replying repeatedly lol
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Oct 11, 2015 7:55 pm Post subject: |
|
|
Oh, the extra NOPs inside the code cave.
I believe that has to do with timing.
CE is reserving enough space for the maximum size of a JMP.
It isn't until the later code gets assembled that CE knows the true size.
So when it goes back and assembles the proper JMP, it NOPs all the extra bytes.
|
|
Back to top |
|
 |
predprey Master Cheater
Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Sun Oct 11, 2015 8:59 pm Post subject: |
|
|
doesn't compilers encounter this same problem of not knowing the number of bytes the instruction is going to take up? can't auto assembler just employ the same solution that is used to overcome this?
|
|
Back to top |
|
 |
Rydian Grandmaster Cheater Supreme
Reputation: 31
Joined: 17 Sep 2012 Posts: 1358
|
Posted: Mon Oct 12, 2015 1:55 am Post subject: |
|
|
You're injecting on an instruction that only takes up 2 bytes.
"fftype0hd.exe"+30E3E: 03 FD
An arbitrary jump takes up 5 bytes. So it needs to overwrite more than 2 bytes in order to put the jump there.
So it needs to overwrite the next instruction as well so that it has enough space to put the jump in.
"fftype0hd.exe"+30E3E: 03 FD
"fftype0hd.exe"+30E40: 3B 3D 12 84 62 00
So it's overwriting two instructions, which total to 8 bytes "removed". But it only needs 5 of those bytes.
So it overwrites the last three bytes with nops, because those bytes DO exist, and they have to be something.
Leaving "half" of the instruction (the bytes asis) would just be garbage assembly that would crash the program.
'Cause CE's not about to go re-adjust the entire damn program's memory.
A compiler has access to WAY more information than a debugger. TONS of data is LOST on compilation.
CE can't use data it doesn't have to know which jumps need to lead where at which time.
EDIT: And it's not just jumps. Some data might be read in as an address to start a read of data or something like that.
There's way too many unknowns, and arbitrarily moving data around causing problems everywhere is... well, it's known.
It's so heavily known that it's actually the reason that the nop instruction exists in like, every architecture ever.
_________________
Last edited by Rydian on Mon Oct 12, 2015 1:58 am; edited 1 time in total |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25806 Location: The netherlands
|
Posted: Mon Oct 12, 2015 1:58 am Post subject: |
|
|
that's the way ce's assembler works
forward jumps are unknown locations so it reserves the max amount of memory needed for the jmp (in 64 it thats 12 bytes)
you can override that behaviour by using jmp short xxxxxxxx
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
predprey Master Cheater
Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Mon Oct 12, 2015 10:41 am Post subject: |
|
|
ok that explains it, thanks
|
|
Back to top |
|
 |
|