
D/Invoke implementation in Nim
Implementazione D/Invoke in Nim
Tutti i binari Nim tipicamente espongono le stesse 58-60 funzioni API di Windows:
Tutte le altre funzioni API di Windows vengono tipicamente risolte a runtime tramite GetProcAddress e LoadLibraryA come menzionato in OffensiveNim o in questo post del blog.
Quindi, non è possibile nascondere (completamente) gli import delle API tramite DInvoke in Nim, a meno che qualcuno, ad esempio, usi questa implementazione di DInvoke per modificare il compilatore Nim per l'uso di DInvoke invece di Dynlib.
Parsare manualmente le funzioni dalla PEB invece di usare GetProcAddress e LoadLibraryA è comunque più stealth del comportamento predefinito di Nim. Per evitare anche l'inline hooking, ad esempio, sarebbe necessario il mapping manuale di una copia pulita della DLL, come menzionato nel post sul blog di TheWovers su DInvoke:
Questo, comunque, non è ancora implementato qui. Attualmente sto usando solo LdrLoadDll per caricare nuove DLL in memoria.
Questo progetto è stato fortemente ispirato dal codice D/Invoke di NanoDump.
La funzione può quindi essere usata così:
const
KERNEL32_DLL* = "kernel32.dll"
const
OpenProcess_FuncName * = "OpenProcess"
type
OpenProcess_t* = proc (dwDesiredAccess: DWORD, bInheritHandle: WINBOOL, dwProcessId: DWORD): HANDLE {.stdcall.}
MyOpenProcess = cast[OpenProcess_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, FALSE)), OpenProcess_FuncName, 0)))
echo "[*] Calling OpenProcess via D/Invoke"
let pHandle = MyOpenProcess(
PROCESS_ALL_ACCESS,
false,
cast[DWORD](https://github.com/s3cur3th1ssh1t/nim_dinvoke/blob/HEAD/processID)
)
Nei miei test ho riscontrato comportamenti strani per alcune funzioni API, che richiedono casi speciali per trovare l'indirizzo relativo corretto. La mia confusione si può trovare nei commenti. Forse è anche solo il mio stile di codifica pessimo - chi lo sa.
L'esempio, quando ha successo, appare come segue: