
D/Invoke implementation in Nim
تنفيذ D/Invoke في Nim
عادةً ما تكشف جميع ملفات Nim الثنائية عن نفس دوال Windows API البالغ عددها 58-60:
عادةً ما يتم حل جميع دوال Windows API الأخرى في وقت التشغيل عبر GetProcAddress وLoadLibraryA كما ذُكر في OffensiveNim أو هذا المنشور.
لذا، ليس من الممكن إخفاء استيرادات API (تمامًا) عبر DInvoke في Nim، إلا إذا استخدم شخص ما على سبيل المثال تنفيذ DInvoke هذا لتعديل مترجم Nim لاستخدام DInvoke بدلاً من Dynlib.
لا يزال تحليل الدوال يدويًا من PEB بدلاً من استخدام GetProcAddress وLoadLibraryA أكثر خفاءً من سلوك Nim الافتراضي. لتجنب inline hooking أيضًا، على سبيل المثال، سيكون من الضروري إجراء تعيين يدوي (manual mapping) لنسخة DLL جديدة كما ذُكر في منشور مدونة TheWovers DInvoke:
هذا - مع ذلك - غير مُطبَّق هنا بعد. أستخدم حاليًا LdrLoadDll فقط لتحميل ملفات DLL جديدة في الذاكرة.
هذا المشروع مستوحى بشكل كبير من كود D/Invoke الخاص بـ NanoDump.
يمكن بعد ذلك استخدام الدالة بهذه الطريقة:
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)
)
في اختباراتي، واجهت سلوكيات غريبة لبعض دوال API التي تحتاج إلى حالات خاصة للعثور على العنوان النسبي الصحيح. يمكن العثور على حيرتي في التعليقات. ربما يكون ذلك أيضًا مجرد أسلوب البرمجة الرديء الخاص بي - من يعلم.
المثال، عند نجاحه، يبدو كما يلي: