Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
DInvoke — Invoquer dynamiquement du code non managé arbitraire à partir de code managé sans PInvoke. | Kitploit
Outils/GitHubGitHub/thewover/dinvoke
Post-ExploitationRed TeamingDéveloppement de Charges UtilesAttaque Adversariale
GitHubthewover/dinvoke

DInvoke

Invoquer dynamiquement du code non managé arbitraire à partir de code managé sans PInvoke.

Voir le dépôt
791112il y a 3 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

DInvoke

Remplaçant dynamique de PInvoke sur Windows. DInvoke contient des primitives puissantes qui peuvent être combinées intelligemment pour invoquer dynamiquement du code non managé depuis le disque ou la mémoire avec une précision minutieuse. Cela peut être utilisé à de nombreuses fins, comme l'analyse de PE, la résolution intelligente d'API dynamiques, le chargement dynamique de plugins PE au moment de l'exécution, l'injection de processus et l'évitement des hooks d'API.

Fonctionnalités :

  • Invoquer dynamiquement des API non managées sans PInvoke
  • Primitives permettant une évasion stratégique des hooks d'API
  • Mapper manuellement des modules PE non managés à partir de code managé
  • Mapper des modules PE dans des sections adossées à des modules arbitraires sur disque
  • API modulaire d'injection de processus
  • Bibliothèque croissante de structures de données, de délégués et de wrappers de fonctions (partagez :-)
  • Support .NET v3.5+

Conférence (Rester # et apporter les techniques d'injection furtive à .NET) : https://www.youtube.com/watch?v=FuxpMXTgV9s

Articles de blog :

  1. Émulation d'opérations furtives - Invocation dynamique (Éviter PInvoke et les hooks d'API) : https://thewover.github.io/Dynamic-Invoke/
  2. Bientôt disponible.

Ce projet a été initialement créé pour SharpSploit (https://github.com/cobbr/SharpSploit). Avec la permission des auteurs, il est maintenant hébergé ici en tant que bibliothèque autonome et package NuGet.

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

Exemple 1 - Résolution d'API non managées exportées

L'exemple ci-dessous montre comment utiliser DInvoke pour trouver et appeler dynamiquement des exports d'une DLL.

  1. Obtenir l'adresse de base de ntdll.dll. Elle est chargée dans chaque processus Windows lors de son initialisation, nous savons donc qu'elle sera déjà chargée. Ainsi, nous pouvons rechercher en toute sécurité la liste des modules chargés dans le PEB pour y trouver une référence. Une fois son adresse de base trouvée depuis le PEB, nous affichons l'adresse.
  2. Utiliser GetLibraryAddress pour trouver un export dans ntdll.dll par nom.
  3. Utiliser GetLibraryAddress pour trouver un export dans ntdll.dll par ordinal.
  4. Utiliser GetLibraryAddress pour trouver un export dans ntdll.dll par hachage à clé.
  5. Étant donné l'adresse de base de ntdll.dll trouvée précédemment, utiliser GetExportAddress pour trouver un export dans le module en mémoire par nom.
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();
        }
    }
}

Exemple 2 - Invocation de code non managé

Dans l'exemple ci-dessous, nous appelons d'abord OpenProcess normalement avec PInvoke. Ensuite, nous l'appelons de plusieurs manières en utilisant DInvoke pour démontrer que chaque mécanisme exécute avec succès le code non managé et contourne les hooks d'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();

        }
    }
}


Pour tester que cela a contourné les hooks, nous utiliserons l'outil API Monitor v2 pour hameçonner kernel32.dll!OpenProcess. Ensuite, nous exécuterons la démo via API Monitor. Vous pouvez observer lesquels de nos appels à OpenProcess ont été interceptés par les hooks en surveillant ceux qui sont appelés avec le flag PROCESS_ALL_ACCESS. Comme vous le verrez, API Monitor intercepte avec succès l'appel API lorsqu'il est effectué avec PInvoke. Cependant, il n'y parvient PAS lorsque nous utilisons DInvoke ou le mappage manuel. Vous pouvez regarder la vidéo sur Vimeo pour le voir en action.

SharpSploit : Contournement des hooks d'API via DInvoke et le mappage manuel

Crédits

  • The Wover
  • FuzzySec (b33f)
  • cobbr
Télécharger l’outil