
D/Invoke implementation in Nim
Implementación de D/Invoke en Nim
Todos los binarios de Nim normalmente exponen las mismas 58-60 funciones de la API de Windows:
Todas las demás funciones de la API de Windows se resuelven normalmente en tiempo de ejecución mediante GetProcAddress y LoadLibraryA, como se menciona en OffensiveNim o en esta entrada de blog.
Por lo tanto, no es posible ocultar las importaciones de la API (por completo) mediante DInvoke en Nim, a menos que alguien, por ejemplo, utilice esta implementación de DInvoke para modificar el compilador de Nim y así usar DInvoke en lugar de Dynlib.
Analizar manualmente las funciones desde el PEB en lugar de usar GetProcAddress y LoadLibraryA sigue siendo más sigiloso que el comportamiento predeterminado de Nim. Para evitar también el inline hooking, por ejemplo, sería necesario el mapeo manual de una copia nueva de la DLL, como se menciona en la entrada de blog sobre DInvoke de TheWover:
Esto, sin embargo, no está implementado aquí aún. Actualmente solo estoy usando LdrLoadDll para cargar nuevas DLL en memoria.
Este proyecto se inspiró en gran medida en el código D/Invoke de NanoDump.
La función se puede usar entonces de la siguiente manera:
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)
)
En mis pruebas me enfrenté a comportamientos extraños en algunas funciones de la API, que necesitan casos especiales para encontrar la dirección relativa correcta. Mi confusión se puede encontrar en los comentarios. Quizás eso también sea solo mi pésimo estilo de programación - quién sabe.
El ejemplo, cuando se ejecuta con éxito, se ve de la siguiente manera: