mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
152 lines
4.1 KiB
NASM
152 lines
4.1 KiB
NASM
.CODE
|
|
|
|
start:
|
|
|
|
MY_FUNC PROC
|
|
call func
|
|
ret
|
|
func:
|
|
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
|
|
;TODO save the QUEEN (and the registers !)
|
|
mov rax, 5050505050505050h ; libname
|
|
mov r11, rax
|
|
mov rax, 5151515151515151h ; function name
|
|
mov r12, rax
|
|
;String pushed !
|
|
mov rax, GS:[60h] ; PEB
|
|
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 rdi, rcx
|
|
call strlen
|
|
mov rdi, rcx ; set RDI to good value
|
|
mov rcx, rax
|
|
mov rsi, r11
|
|
repe cmpsw ;cmp with current dll name (unicode)
|
|
test rcx, rcx
|
|
jz dll_found
|
|
mov rdx, [rdx]
|
|
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
|
|
ret
|
|
strlen:; arg in RDI
|
|
push rcx
|
|
xor rax, rax
|
|
xor rcx, rcx
|
|
dec rcx
|
|
repne scasw
|
|
not rcx
|
|
dec rcx
|
|
mov rax, rcx
|
|
pop rcx
|
|
ret
|
|
MY_FUNC ENDP
|
|
END
|
|
|
|
|