diff --git a/doc/NtCreateThreadStub_64b.asm b/doc/NtCreateThreadStub_64b.asm deleted file mode 100644 index e05b13c..0000000 --- a/doc/NtCreateThreadStub_64b.asm +++ /dev/null @@ -1,139 +0,0 @@ -.CODE - -start: - -MY_FUNC PROC - push rax ;Padding for calling alligned on 16 bytes + ret value - push rax - push rbx - push rcx - push rdx - push rsi - push rdi - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - mov rax, 0h - push rax - mov rax, 7845646165726854h - push rax - mov rax, 657461657243744eh - push rax - mov r11, rsp ;R11 NtCreateThreadEx - mov rbx, 41797261h - push rbx - mov rbx, 7262694c64616f4ch - push rbx - mov r12, rsp ;R12 : LoadLib - ;String pushed ! - ;mov rax, 0x60 - ;GS mov rax, [rax] ;PEB! - mov rax, GS:[60h] - mov rax, [rax + 6 * 4] ; RAX = ldr (+ 6 for 64 cause of 2 ptr) - mov rax, [rax + 8 * 4] ; RAX on the first elt of the list (first module) - mov rdx, rax -a_dest: - mov rax, rdx - mov rbx, [rax + 4 * 8] ;RBX : first base ! (base of current module) - and rbx, rbx ;If no more Module : not fail = fail - jz a_fail - mov rcx, [rax + 10 * 8] ;RCX = NAME (UNICODE_STRING.Buffer) - - mov rcx, [rcx] ;GET WCHAR - cmp ecx, 74006eh ;ntdll if : ecx == 74006eh (nt unicode) - jz dll_found - mov rdx, [rax] - jmp a_dest -a_fail: - push 42424242h - ret -dll_found: ;Cool ! : here rbx = base - mov eax, [rbx + 15 * 4] ;rax = PEBASE RVA - add rax, rbx ;RAX = PEBASE - add rax, 24 ;OPTIONAL HEADER - mov ecx, [rax + 112] ;rcx = RVA export dir - add rcx, rbx ;rcx = export_dir - mov rax, rcx ;RAX = export_dir - push rax ;Save it for after function search - ; EBX = BASE | EAX = EXPORT DIR - mov ecx, [rax + 6 * 4] - mov r13, rcx ;r13 = NB names - mov edx, [rax + 8 * 4] ; EDX = names array RVA - add rdx, rbx - xor rcx, rcx - search_loop: - mov esi, [rdx + rcx * 4] ;Get function name RVA - add rsi, rbx ;Get name addr - push rcx ;Save current index (could use x64 register) - mov rdi, r11 - mov rcx, 17 ;We know we want NtCreateThreadEx - repe cmpsb ;cmp with current export - mov eax, ecx - pop rcx ;Restore current function index - inc rcx - test eax, eax - jnz search_loop ;If not found not handled : WTF GetProcAddress not in Kernel32... - ; Func found ! - dec rcx - ; rcx is offset of the name, need to find the offset of the function - pop rax ;Restore export_dir addr - mov edx, [rax + 9 * 4] ;EDX = AddressOfNameOrdinals RVX - add rdx, rbx ;AddressOfNameOrdinals + base - mov cx, [rdx + rcx * 2] ; ecx = Ieme ordinal (short array) - and rcx, 0ffffh - mov edx, [rax + 7 * 4] ; AddressOfFunctions RVA - add rdx, rbx ; AddressOfFunctions + base - mov edx, [rdx + rcx * 4] ;functions[ecx] -> functions[ordinals[i]] - add rdx, rbx - mov r13, rdx ; r13 : REAL FUNC ADD - - - ; room for the thread handle - push 0 - mov rcx, rsp ; arg1 - mov rdx, 1fffffh ; arg2 - mov r8, 0h ; arg3 - mov r9, 4040404040404040h ; arg4 (handle) - - mov rax, 0h - push rax ; arg11 - push rax ; arg10 - push rax ; arg9 - push rax ; arg8 - push rax ; arg7 - mov rax, 4242424242424242h - push rax ; arg6 (param) - mov rax, 4141414141414141h - push rax ; arg5 (addr) - - ; reserve space for register (calling convention) - push r9 - push r8 - push rdx - push rcx - call r13 - ; Write return value in first stack value pushed - mov [rsp + 29 * 8], rax - ; TODO CLEAN stack :D - add rsp, 8 * 8 - add rsp, 32 + 8 - add rsp, 32 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdi - pop rsi - pop rdx - pop rcx - pop rbx - pop rax - pop rax ; Return value - -MY_FUNC ENDP -END \ No newline at end of file diff --git a/native_exec/native_function.py b/native_exec/native_function.py index ac80e04..e228636 100644 --- a/native_exec/native_function.py +++ b/native_exec/native_function.py @@ -292,7 +292,7 @@ def create_function(code, types): # Return First argument for 32 bits code raw_code = x86.MultipleInstr() -raw_code += x86.Mov('EAX', x86.create_displacement(base='ESP', disp=4)) +raw_code += x86.Mov('EAX', x86.mem('[ESP + 4]')) raw_code += x86.Ret() get_callback_address_32 = create_function(raw_code.get_code(), [ctypes.c_void_p]) diff --git a/syswow64.py b/syswow64.py index a814471..d706409 100644 --- a/syswow64.py +++ b/syswow64.py @@ -1,6 +1,8 @@ import struct import ctypes +import codecs import windows +import windows.k32testing as kernel32proxy import windows.native_exec.simple_x64 as x64 from generated_def.winstructs import * @@ -8,33 +10,6 @@ from generated_def.winstructs import * CS_32bits = 0x23 CS_64bits = 0x33 -# See assembly into doc/NtCreateThreadStub_64b.asm -Pretty_NtCreateThreadStub = """ -50 50 53 51 52 56 57 41 50 41 51 41 52 41 53 41 -54 41 55 48 C7 C0 00 00 00 00 50 48 B8 54 68 72 -65 61 64 45 78 50 48 B8 4E 74 43 72 65 61 74 65 -50 4C 8B DC 48 C7 C3 61 72 79 41 53 48 BB 4C 6F -61 64 4C 69 62 72 53 4C 8B E4 65 48 8B 04 25 60 -00 00 00 48 8B 40 18 48 8B 40 20 48 8B D0 48 8B -C2 48 8B 58 20 48 23 DB 74 14 48 8B 48 50 48 8B -09 81 F9 6E 00 74 00 74 0B 48 8B 10 EB E0 68 42 -42 42 42 C3 8B 43 3C 48 03 C3 48 83 C0 18 8B 48 -70 48 03 CB 48 8B C1 50 8B 48 18 4C 8B E9 8B 50 -20 48 03 D3 48 33 C9 8B 34 8A 48 03 F3 51 49 8B -FB 48 C7 C1 11 00 00 00 F3 A6 8B C1 59 48 FF C1 -85 C0 75 E3 48 FF C9 58 8B 50 24 48 03 D3 66 8B -0C 4A 48 81 E1 FF FF 00 00 8B 50 1C 48 03 D3 8B -14 8A 48 03 D3 4C 8B EA 6A 00 48 8B CC 48 C7 C2 -FF FF 1F 00 49 C7 C0 00 00 00 00 49 B9 40 40 40 -40 40 40 40 40 48 C7 C0 00 00 00 00 50 50 50 50 -50 48 B8 42 42 42 42 42 42 42 42 50 48 B8 41 41 -41 41 41 41 41 41 50 41 51 41 50 52 51 41 FF D5 -48 89 84 24 E8 00 00 00 48 83 C4 40 48 83 C4 28 -48 83 C4 20 41 5D 41 5C 41 5B 41 5A 41 59 41 58 -5F 5E 5A 59 5B 58 58 -""" -NtCreateThreadStub = Pretty_NtCreateThreadStub.replace(" ", "").replace("\n", "").decode('hex') - def genere_return_32bits_stub(ret_addr): ret_32b = x64.MultipleInstr() ret_32b += x64.Mov('RCX', (CS_32bits << 32) + ret_addr) @@ -46,6 +21,7 @@ def genere_return_32bits_stub(ret_addr): dummy_jump = "\xea" + struct.pack("