
D/Invoke의 Nim 구현
Nim에서의 D/Invoke 구현
모든 Nim 바이너리는 일반적으로 동일한 58-60개의 Windows API 함수를 노출합니다:
다른 모든 Windows API 함수는 일반적으로 OffensiveNim 또는 이 블로그 게시물에서 언급된 것처럼 런타임에 GetProcAddress와 LoadLibraryA를 통해 해석됩니다.
따라서 누군가가 예를 들어 이 DInvoke 구현을 사용하여 Dynlib 대신 DInvoke를 사용하도록 Nim 컴파일러를 수정하지 않는 한, Nim에서 DInvoke를 통해 API 가져오기를 (완전히) 숨기는 것은 불가능합니다.
GetProcAddress와 LoadLibraryA를 사용하는 대신 PEB에서 함수를 수동으로 파싱하는 것은 기본 Nim 동작보다 여전히 더 은밀합니다. 또한 인라인 후킹을 피하려면 예를 들어 TheWovers DInvoke 블로그 게시물에서 언급된 것처럼 새 DLL 복사본의 수동 매핑이 필요할 것입니다:
이것은 - 그러나 - 여기서 아직 구현되지 않았습니다. 저는 현재 새 DLL을 메모리에 로드하기 위해 LdrLoadDll만 사용하고 있습니다.
이 프로젝트는 NanoDump D/Invoke 코드에서 크게 영감을 받았습니다.
그런 다음 함수는 다음과 같이 사용할 수 있습니다:
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/main/processID)
)
제 테스트에서는 올바른 상대 주소를 찾기 위해 특별한 처리가 필요한 일부 API 함수에서 이상한 동작이 발생했습니다. 제 혼란은 주석에서 확인할 수 있습니다. 어쩌면 그것은 단지 제 형편없는 코딩 스타일 때문일 수도 있습니다 - 누가 알겠어요.
성공적으로 실행되면 예시는 다음과 같습니다: