Skip to content

Instantly share code, notes, and snippets.

@odzhan
Last active October 31, 2022 22:05
Show Gist options
  • Select an option

  • Save odzhan/ce9782ccdde352de4fba744116aef756 to your computer and use it in GitHub Desktop.

Select an option

Save odzhan/ce9782ccdde352de4fba744116aef756 to your computer and use it in GitHub Desktop.
Invoke Win32 API for Windows on ARM64
area .drectve, drectve
export call_api
; The following are 64-Bit offsets.
TEB_ProcessEnvironmentBlock equ 0x00000060
TEB_LastErrorValue equ 0x00000068
PEB_Ldr equ 0x00000018
PEB_LDR_DATA_InLoadOrderModuleList equ 0x00000010
LDR_DATA_TABLE_ENTRY_DllBase equ 0x00000030
IMAGE_DOS_HEADER_e_magic equ 0x0000003C
IMAGE_EXPORT_DIRECTORY_Characteristics equ 0x00000000
IMAGE_EXPORT_DIRECTORY_TimeDateStamp equ 0x0004
IMAGE_EXPORT_DIRECTORY_MajorVersion equ 0x0008
IMAGE_EXPORT_DIRECTORY_MinorVersion equ 0x000A
IMAGE_EXPORT_DIRECTORY_Name equ 0x0000000C
IMAGE_EXPORT_DIRECTORY_Base equ 0x00000010
IMAGE_EXPORT_DIRECTORY_NumberOfFunctions equ 0x00000014
IMAGE_EXPORT_DIRECTORY_NumberOfNames equ 0x00000018
IMAGE_EXPORT_DIRECTORY_AddressOfFunctions equ 0x0000001C
IMAGE_EXPORT_DIRECTORY_AddressOfNames equ 0x00000020
IMAGE_EXPORT_DIRECTORY_AddressOfNameOrdinals equ 0x00000024
area .text, code, arm64
call_api proc
; save parameters, except for x0, which won't be used.
stp x1, x2, [sp, -64]!
stp x3, x4, [sp, 16]
stp x5, x6, [sp, 32]
stp x7, x8, [sp, 48]
; Ldr = (PPEB_LDR_DATA)NtCurrentTeb()->ProcessEnvironmentBlock->Ldr;
mov x1, xpr
ldr x2, [x1, TEB_ProcessEnvironmentBlock]
ldr x2, [x2, PEB_Ldr]
; end = (PLIST_ENTRY)&Ldr->InLoadOrderModuleList;
add x2, x2, PEB_LDR_DATA_InLoadOrderModuleList
; nxt = end->Flink;
ldr x3, [x2] ; read first entry
nxt_dll
cmp x3, x2 ; while (nxt != end)
bne load_dll
add sp, sp, 64 ; fixup stack
ret ; return to caller
load_dll
; bx = e->DllBase
ldr x4, [x3, LDR_DATA_TABLE_ENTRY_DllBase]
ldr x3, [x3] ; nxt = nxt->Flink
; nt = VA(PIMAGE_NT_HEADERS, bx, ((PIMAGE_DOS_HEADER)e->DllBase)->e_lfanew);
ldr w5, [x4, IMAGE_DOS_HEADER_e_magic]
add x5, x4, w5, uxtw #0
; va = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
; if (!va) continue;
ldr w5, [x5, #0x88]
cbz w5, nxt_dll
; exp = VA(PIMAGE_EXPORT_DIRECTORY, bx, va);
add x5, x4, w5, uxtw #0
; cnt = exp->NumberOfNames;
; if (!cnt) continue;
ldr w6, [x5, IMAGE_EXPORT_DIRECTORY_NumberOfNames]
cbz w6, nxt_dll
; dll = VA(PCHAR, bx, exp->Name);
ldr w7, [x5, IMAGE_EXPORT_DIRECTORY_Name]
add x7, x4, w7, uxtw #0
mov w8, #0 ; dx = 0
hash_dll
; while (*dll) c = *dll++, c = (c >= 'A' && c <= 'Z') ? (c | 32) : c, dx += c, dx = R(dx, 8);
ldrsb x9, [x7], 1
cbz x9, exit_hash_dll
sub x10, x9, 'A'
orr x11, x9, 32
cmp x10, 26
csel x9, x11, x9, cc
add w8, w8, w9
ror w8, w8, 8
b hash_dll
exit_hash_dll
; aon = VA(PDWORD, bx, exp->AddressOfNames);
ldr w9, [x5, IMAGE_EXPORT_DIRECTORY_AddressOfNames]
add x9, x4, w9, uxtw #0
mov x10, #0
nxt_api
mov x11, #0
; api = VA(PCHAR, bx, aon[i]);
ldr w12, [x9, w10 uxtw #2]
add x12, x4, w12 uxtw #0
hash_api
; while (*api) ax += *api++, ax = R(ax, 8);
ldrsb x13, [x12], 1
cbz x13, exit_hash_api
add w11, w11, w13
ror w11, w11, 8
b hash_api
exit_hash_api
add w11, w11, w8 ;
ldr w12, [x1, TEB_LastErrorValue]
cmp w11, w12 ; if ((ax + dx) == hx)
beq load_api
add w10, w10, 1 ; i++
cmp w10, w6 ; i < cnt
bne nxt_api
b nxt_dll
load_api
; aof = VA(PDWORD, bx, exp->AddressOfFunctions);
ldr w1, [x5, IMAGE_EXPORT_DIRECTORY_AddressOfFunctions]
add x1, x4, x1
; ono = VA(PDWORD, bx, exp->AddressOfNameOrdinals);
ldr w2, [x5, IMAGE_EXPORT_DIRECTORY_AddressOfNameOrdinals]
add x2, x4, x2
; pfn = VA(PVOID, bx, aof[ono[i]]);
ldrh w2, [x2, w10 uxtw #1] ; read ordinal
ldr w1, [x1, x2 lsl #2] ; read address of function rva
add x9, x4, w1, uxtw #0 ; add base
; load parameters saved on stack
ldp x1, x2, [sp], 16
ldp x3, x4, [sp], 16
ldp x5, x6, [sp], 16
ldp x7, x8, [sp], 16
; execute API and return to original caller.
br x9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment