Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
DInvoke — استدعاء أي رمز غير مُدار ديناميكيًا من رمز مُدار بدون استخدام PInvoke. | Kitploit
أدوات/GitHubGitHub/thewover/dinvoke
ما بعد الاستغلالالفريق الأحمرتطوير الحمولاتالهجوم العدائي
GitHubthewover/dinvoke

DInvoke

استدعاء أي رمز غير مُدار ديناميكيًا من رمز مُدار بدون استخدام PInvoke.

عرض المستودع
791112منذ 3 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

DInvoke

بديل ديناميكي لـ PInvoke على ويندوز. يحتوي DInvoke على بدائيات قوية يمكن دمجها بذكاء لاستدعاء كود غير مُدار ديناميكيًا من القرص أو من الذاكرة بدقة متناهية. يمكن استخدام هذا لأغراض عديدة مثل تحليل PE، وحلّ واجهات برمجة التطبيقات ديناميكيًا بذكاء، وتحميل إضافات PE ديناميكيًا في وقت التشغيل، وحقن العمليات، وتجنّب خطافات API.

الميزات:

  • استدعاء واجهات برمجة تطبيقات غير مُدارة ديناميكيًا دون استخدام PInvoke
  • بدائيات تتيح مراوغة استراتيجية لخطافات API
  • تعيين وحدات PE غير مُدارة يدويًا من كود مُدار
  • تعيين وحدات PE إلى أقسام مدعومة بوحدات تعسفية على القرص
  • واجهة برمجة تطبيقات معيارية لحقن العمليات
  • مكتبة متنامية من هياكل البيانات والمفوَّضين وأغلفة الدوال (شاركوا معنا :-)
  • دعم .NET الإصدار v3.5+

محاضرة المؤتمر (Staying # & Bringing Covert Injection Tradecraft to .NET): https://www.youtube.com/watch?v=FuxpMXTgV9s

منشورات المدونة:

  1. محاكاة العمليات السرية - الاستدعاء الديناميكي (تجنّب PInvoke وخطافات API): https://thewover.github.io/Dynamic-Invoke/
  2. قريبًا.

أُنشئ هذا المشروع في الأصل لصالح SharpSploit (https://github.com/cobbr/SharpSploit). وبإذن من المؤلفين، يُستضاف الآن هنا كمكتبة مستقلة وحزمة NuGet.

NuGet: https://www.nuget.org/packages/DInvoke/

مثال 1 - حلّ واجهات برمجة التطبيقات غير المُدارة المُصدَّرة

يوضح المثال أدناه كيفية استخدام DInvoke للعثور ديناميكيًا على دوال DLL المُصدَّرة واستدعائها.

  1. احصل على العنوان الأساسي لـ ntdll.dll. يتم تحميلها في كل عملية ويندوز عند تهيئتها، لذلك نعرف أنها ستكون محمّلة بالفعل. وبالتالي، يمكننا البحث بأمان في قائمة الوحدات المحمّلة في PEB للعثور على مرجع لها. وبمجرد العثور على عنوانها الأساسي من PEB، نطبع العنوان.
  2. استخدم GetLibraryAddress للعثور على دالة مُصدَّرة داخل ntdll.dll بالاسم.
  3. استخدم GetLibraryAddress للعثور على دالة مُصدَّرة داخل ntdll.dll بالترتيب (ordinal).
  4. استخدم GetLibraryAddress للعثور على دالة مُصدَّرة داخل ntdll.dll بتجزئة مفتاحية.
  5. بالنظر إلى العنوان الأساسي لـ ntdll.dll الذي وجدناه سابقًا، استخدم GetExportAddress للعثور على دالة مُصدَّرة داخل الوحدة في الذاكرة بالاسم.
root@kitploit:~

///Author: b33f (@FuzzySec, Ruben Boonen)
using System;

using DynamicInvoke = DInvoke.DynamicInvoke;

namespace SpTestcase
{
    class Program
    {

        static void Main(string[] args)
        {
            // Details
            String testDetail = @"
            #=================>
            # Hello there!
            # I find things dynamically; base
            # addresses and function pointers.
            #=================>
            ";
            Console.WriteLine(testDetail);

            // Get NTDLL base from the PEB
            Console.WriteLine("[?] Resolve Ntdll base from the PEB..");
            IntPtr hNtdll = DynamicInvoke.Generic.GetPebLdrModuleEntry("ntdll.dll");
            Console.WriteLine("[>] Ntdll base address : " + string.Format("{0:X}", hNtdll.ToInt64()) + "\n");

            // Search function by name
            Console.WriteLine("[?] Specifying the name of a DLL (\"ntdll.dll\"), resolve a function by walking the export table in-memory..");
            Console.WriteLine("[+] Search by name --> NtCommitComplete");
            IntPtr pNtCommitComplete = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", "NtCommitComplete", true);
            Console.WriteLine("[>] pNtCommitComplete : " + string.Format("{0:X}", pNtCommitComplete.ToInt64()) + "\n");

            Console.WriteLine("[+] Search by ordinal --> 0x260 (NtSetSystemTime)");
            IntPtr pNtSetSystemTime = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", 0x260, true);
            Console.WriteLine("[>] pNtSetSystemTime : " + string.Format("{0:X}", pNtSetSystemTime.ToInt64()) + "\n");

            Console.WriteLine("[+] Search by keyed hash --> 138F2374EC295F225BD918F7D8058316 (RtlAdjustPrivilege)");
            Console.WriteLine("[>] Hash : HMACMD5(Key).ComputeHash(FunctionName)");
            String fHash = DynamicInvoke.Generic.GetAPIHash("RtlAdjustPrivilege", 0xaabb1122);
            IntPtr pRtlAdjustPrivilege = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", fHash, 0xaabb1122);
            Console.WriteLine("[>] pRtlAdjustPrivilege : " + string.Format("{0:X}", pRtlAdjustPrivilege.ToInt64()) + "\n");

            // Search for function from base address of DLL
            Console.WriteLine("[?] Specifying the base address of DLL in memory ({0:X}), resolve function by walking its export table...", hNtdll.ToInt64());
            Console.WriteLine("[+] Search by name --> NtCommitComplete");
            IntPtr pNtCommitComplete2 = DynamicInvoke.Generic.GetExportAddress(hNtdll, "NtCommitComplete");
            Console.WriteLine("[>] pNtCommitComplete : " + string.Format("{0:X}", pNtCommitComplete2.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();
        }
    }
}

مثال 2 - استدعاء كود غير مُدار

في المثال أدناه، نستدعي أولاً OpenProcess بشكل طبيعي باستخدام PInvoke. بعد ذلك، سنستدعيها بعدة طرق باستخدام DInvoke لإثبات أن كل آلية تنفّذ الكود غير المُدار بنجاح وتتجنّب خطافات API.

root@kitploit:~

///Author: TheWover
using System;
using System.Runtime.InteropServices;

using Data = DInvoke.Data;
using DynamicInvoke = DInvoke.DynamicInvoke;
using ManualMap = DInvoke.ManualMap;

namespace SpTestcase
{
    class Program
    {

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(
            Data.Win32.Kernel32.ProcessAccessFlags processAccess,
            bool bInheritHandle,
            uint processId
        );

        static void Main(string[] args)
        {
            // Details
            String testDetail = @"
            #=================>
            # Hello there!
            # I demonstrate API Hooking bypasses
            # by calling OpenProcess via
            # PInvoke then DInvoke.
            # All handles are requested with
            # PROCESS_ALL_ACCESS permissions.
            #=================>
            ";
            Console.WriteLine(testDetail);

            //PID of current process.
            uint id = Convert.ToUInt32(System.Diagnostics.Process.GetCurrentProcess().Id);

            //Process handle
            IntPtr hProc;

            // Create the array for the parameters for OpenProcess
            object[] paramaters =
            {
                Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS,
                false,
                id
            };

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Call OpenProcess using PInvoke
            Console.WriteLine("[?] Call OpenProcess via PInvoke ...");
            hProc = OpenProcess(Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
            Console.WriteLine("[>] Process handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Call OpenProcess using GetLibraryAddress (underneath the hood)
            Console.WriteLine("[?] Call OpenProcess from the loaded module list using System.Diagnostics.Process.GetCurrentProcess().Modules ...");
            hProc = DynamicInvoke.Win32.OpenProcess(Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
            Console.WriteLine("[>] Process handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Search function by name from module in PEB
            Console.WriteLine("[?] Specifying the name of a DLL (\"kernel32.dll\"), search the PEB for the loaded module and resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            IntPtr pkernel32 = DynamicInvoke.Generic.GetPebLdrModuleEntry("kernel32.dll");
            IntPtr pOpenProcess = DynamicInvoke.Generic.GetExportAddress(pkernel32, "OpenProcess");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.DynamicFunctionInvoke(pOpenProcess, typeof(DynamicInvoke.Win32.Delegates.OpenProcess), ref paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Manually map kernel32.dll
            // Search function by name from module in PEB
            Console.WriteLine("[?] Manually map a fresh copy of a DLL (\"kernel32.dll\"), and resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            Data.PE.PE_MANUAL_MAP moduleDetails = ManualMap.Map.MapModuleToMemory("C:\\Windows\\System32\\kernel32.dll");
            Console.WriteLine("[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "OpenProcess", typeof(DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Map kernel32.dll using Module Overloading
            // Search function by name from module in PEB
            Console.WriteLine("[?] Use Module Overloading to map a fresh copy of a DLL (\"kernel32.dll\") into memory backed by another file on disk. Resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            moduleDetails = ManualMap.Overload.OverloadModule("C:\\Windows\\System32\\kernel32.dll");
            Console.WriteLine("[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "OpenProcess", typeof(DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            Console.WriteLine("[!] Test complete!");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

        }
    }
}


لاختبار أنّ هذا قد تجنّب الخطافات، سنستخدم أداة API Monitor v2 لخطف kernel32.dll!OpenProcess. ثم نشغّل العرض التوضيحي عبر API Monitor. يمكنك ملاحظة أيّ من استدعاءاتنا لـ OpenProcess تم التقاطها في الخطافات من خلال مراقبة تلك التي تُستدعى مع علامة PROCESS_ALL_ACCESS. وكما سترى، ينجح API Monitor في التقاط استدعاء API عندما يتم عبر PInvoke. لكنه لا ينجح عندما نستخدم DInvoke أو Manual Mapping. يمكنك مشاهدة الفيديو على Vimeo لرؤية ذلك عمليًا.

SharpSploit: تجاوز خطافات API عبر DInvoke وManual Mapping

الفضل

  • The Wover
  • FuzzySec (b33f)
  • cobbr
تنزيل الأداة