-
Member
Question about ShellCode inject
Code:
import pymem
from keystone import *
def assemble_asm(asm_code):
ks = Ks(KS_ARCH_X86, KS_MODE_64)
return ks.asm(asm_code, as_bytes=True)[0]
if __name__ == '__main__':
game_pm = pymem.Pymem("wowclassic.exe")
fun_addr = 0x15B2BD0 # logout
shell_code = assemble_asm(f'''
mov edi, 1
mov esi, 1
mov edx, 0
mov rax, {fun_addr}
call rax
''')
remote_shell_code_addr = game_pm.allocate(len(shell_code))
game_pm.write_bytes(remote_shell_code_addr, shell_code, len(shell_code))
shell_thread_handle = game_pm.start_thread(remote_shell_code_addr)
game_pm.free(remote_shell_code_addr)
game_pm.inject_python_interpreter()
game_pm.inject_python_shellcode(f'''
import ctypes
ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)({fun_addr})(1,1,0)
''')
i call "logout" by two ways:remote shellcode and Injected python.dll
shellcode don't work and after run, shellcode's first byte change to 0x3C, injected python.dll works well
my asm code is not right?
-
Originally Posted by
yezack
Code:
import pymem
from keystone import *
def assemble_asm(asm_code):
ks = Ks(KS_ARCH_X86, KS_MODE_64)
return ks.asm(asm_code, as_bytes=True)[0]
if __name__ == '__main__':
game_pm = pymem.Pymem("wowclassic.exe")
fun_addr = 0x15B2BD0 # logout
shell_code = assemble_asm(f'''
mov edi, 1
mov esi, 1
mov edx, 0
mov rax, {fun_addr}
call rax
''')
remote_shell_code_addr = game_pm.allocate(len(shell_code))
game_pm.write_bytes(remote_shell_code_addr, shell_code, len(shell_code))
shell_thread_handle = game_pm.start_thread(remote_shell_code_addr)
game_pm.free(remote_shell_code_addr)
game_pm.inject_python_interpreter()
game_pm.inject_python_shellcode(f'''
import ctypes
ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)({fun_addr})(1,1,0)
''')
i call "logout" by two ways:remote shellcode and Injected python.dll
shellcode don't work and after run, shellcode's first byte change to 0x3C, injected python.dll works well
my asm code is not right?
There's a lot of missing context here, so it's difficult to help you, but I can tell you that 0x3C on its own is typically the byte for return, which means your function would instantly return on call.
-
Member
that's full code.
game_pm.start_thread(remote_shell_code_addr) is pymem's function,create a remote thread in game process
game_pm.inject_python_shellcode Run python code by remote python.dll(another way to remote call)
-
Member
Code:
import pymem
game_pm = pymem.Pymem("wowclassic.exe")
game_pm.inject_python_interpreter()
game_pm.inject_python_shellcode(f'''
import ctypes
ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)(0x15B2BD0)(1,1,0)
''')
Minimalist code to call a function(logout) by python
-
Contributor
Originally Posted by
yezack
Code:
import pymem
from keystone import *
def assemble_asm(asm_code):
ks = Ks(KS_ARCH_X86, KS_MODE_64)
return ks.asm(asm_code, as_bytes=True)[0]
if __name__ == '__main__':
game_pm = pymem.Pymem("wowclassic.exe")
fun_addr = 0x15B2BD0 # logout
shell_code = assemble_asm(f'''
mov edi, 1
mov esi, 1
mov edx, 0
mov rax, {fun_addr}
call rax
''')
remote_shell_code_addr = game_pm.allocate(len(shell_code))
game_pm.write_bytes(remote_shell_code_addr, shell_code, len(shell_code))
shell_thread_handle = game_pm.start_thread(remote_shell_code_addr)
game_pm.free(remote_shell_code_addr)
game_pm.inject_python_interpreter()
game_pm.inject_python_shellcode(f'''
import ctypes
ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)({fun_addr})(1,1,0)
''')
i call "logout" by two ways:remote shellcode and Injected python.dll
shellcode don't work and after run, shellcode's first byte change to 0x3C, injected python.dll works well
my asm code is not right?
When a thread is created and executed, and doesn't have a backing module the first byte is replaced to 0x3C. That's why it worked from the python.dll, as it is a mapped in module that exists in the space. You can create a proxy to call from. Somewhere in another module pointing to the outside, which you then put your shellcode in to execute. That, or create the thread with the shellcode accounting for the first byte being 0x3C and then modifying rcx to be +1 on the context
-
Post Thanks / Like - 1 Thanks
Hazzbazzy (1 members gave Thanks to scizzydo for this useful post)
-
Member
It's the TLS callback that is checking the start address of your thread and instantly setting it to ret when you are not starting it within the .text section of the game. If you want to execute your jit assembly shell code you either have to hook something or hijack a thread or start the thread at some jump instruction in the .text section and change the thread context to jump to your shell code.
-
Post Thanks / Like - 1 Thanks
Hazzbazzy (1 members gave Thanks to darheroc for this useful post)
-
Contributor
Originally Posted by
darheroc
It's the TLS callback that is checking the start address of your thread and instantly setting it to ret when you are not starting it within the .text section of the game. If you want to execute your jit assembly shell code you either have to hook something or hijack a thread or start the thread at some jump instruction in the .text section and change the thread context to jump to your shell code.
Not necessarily true for the only options I did state 2 other methods too.
It's also for more than just the games .text, as you can successfully call LoadLibrary for example, and that's not in the games .text
Last edited by scizzydo; 01-31-2024 at 05:43 PM.
-
Member
Originally Posted by
scizzydo
Not necessarily true for the only options
I did state 2 other methods too.
It's also for more than just the games .text, as you can successfully call LoadLibrary for example, and that's not in the games .text
Your first method is to inject a dll to call your injected shell code. Yea or you just run the code within the dll when you are already injecting a dll? I don't see the point of this method, why would you even compile assembly during runtime then.
I haven't tried your second method, only thing i tried is having a nop at the start of the shell code and starting the thread at +1. This resulted in Wow crashing. Have you actually tried this method or is it just theory, because I would assume that the TLS callback kills the thread before you can suspend it.
-
Contributor
Originally Posted by
darheroc
Your first method is to inject a dll to call your injected shell code. Yea or you just run the code within the dll when you are already injecting a dll? I don't see the point of this method, why would you even compile assembly during runtime then.
I haven't tried your second method, only thing i tried is having a nop at the start of the shell code and starting the thread at +1. This resulted in Wow crashing. Have you actually tried this method or is it just theory, because I would assume that the TLS callback kills the thread before you can suspend it.
I'm going to take part of your response as a lack of understanding being why you're narrow minded on it... However. I never once said anything about injecting a DLL... I will requote it again... maybe this time read it fully
You can create a proxy to call from. Somewhere in another module pointing to the outside, which you then put your shellcode in to execute.
I'm not here to feed answers, but inspire ideas to get people thinking outside the box. In regards to the second method listed.... If only there was a flag or something to creating a thread that would create a thread suspended... hmmmmmmm...
Both methods do work. There are others I have in theory, which I can test, and hint on, however I personally do the method #1 with a proxy, as after injection I reuse it for many other things too. These are less invasive methods also and don't require hooking things, or modifying the binary outside of a memory allocation for the code to be written.
-
Post Thanks / Like - 1 Thanks
Razzue (1 members gave Thanks to scizzydo for this useful post)
-
Member
Originally Posted by
scizzydo
I'm going to take part of your response as a lack of understanding being why you're narrow minded on it... However. I never once said anything about injecting a DLL... I will requote it again... maybe this time read it fully
I'm not here to feed answers, but inspire ideas to get people thinking outside the box. In regards to the second method listed.... If only there was a flag or something to creating a thread that would create a thread suspended... hmmmmmmm...
Both methods do work. There are others I have in theory, which I can test, and hint on, however I personally do the method
#1 with a proxy, as after injection I reuse it for many other things too. These are less invasive methods also and don't require hooking things, or modifying the binary outside of a memory allocation for the code to be written.
Your response could be more precise, as it currently leaves room for multiple interpretations, including my own, which I believe is also valid based on your quote.
I'm aware that a thread can be created in a suspended state, but my assumption was that the TLS callback terminates it, hence why I asked if you have tried it.
However, I think we should conclude this discussion here. It seems challenging to engage in a constructive conversation with you, as it feels like the focus shifts towards proving superiority rather than exchanging ideas.