Last active
October 31, 2022 22:05
-
-
Save odzhan/ce9782ccdde352de4fba744116aef756 to your computer and use it in GitHub Desktop.
Invoke Win32 API for Windows on ARM64
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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