Repository navigation
Expand file tree
/
Copy pathShellCodeLoader.cs
More file actions
181 lines (167 loc) · 8.97 KB
/
Copy pathShellCodeLoader.cs
File metadata and controls
181 lines (167 loc) · 8.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
/*
|| AUTHOR Arsium ||
|| github : https://github.com/arsium ||
|| Please let this credit for all the time I worked on ||
*/
namespace ShellCodeLoader
{
public class ShellCodeLoader : IDisposable
{
private byte[] ShellCode;
private IntPtr ptr;
/// <summary>
/// Default is false.
/// </summary>
public bool Asynchronous { get; set; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void ShellCodeCaller();
public ShellCodeLoader(byte[] shellCode)
{
this.ShellCode = shellCode;
Asynchronous = false;
}
public void LoadWithNT()
{
if (this.Asynchronous)
{
Task.Run(() =>
{
this.ptr = IntPtr.Zero;
uint RegionSize = (uint)ShellCode.Length;
Imports.NtAllocateVirtualMemory(Imports.GetCurrentProcess(), ref ptr, IntPtr.Zero, ref RegionSize, Imports.TypeAlloc.MEM_COMMIT | Imports.TypeAlloc.MEM_RESERVE, Imports.PageProtection.PAGE_EXECUTE_READWRITE);
UIntPtr bytesWritten;
Imports.NtWriteVirtualMemory(Imports.GetCurrentProcess(), ptr, ShellCode, (UIntPtr)ShellCode.Length, out bytesWritten);
Imports.PageProtection flOld = new Imports.PageProtection();
Imports.NtProtectVirtualMemory(Imports.GetCurrentProcess(), ref ptr, ref RegionSize, Imports.PageProtection.PAGE_EXECUTE_READ, ref flOld);
ShellCodeCaller load = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ShellCodeCaller));
load();
Imports.NtFreeVirtualMemory(Imports.GetCurrentProcess(), ref ptr, ref RegionSize, Imports.FreeType.MEM_RELEASE);
});
}
else
{
this.ptr = IntPtr.Zero;
uint RegionSize = (uint)ShellCode.Length;
Imports.NtAllocateVirtualMemory(Imports.GetCurrentProcess(), ref ptr, IntPtr.Zero, ref RegionSize, Imports.TypeAlloc.MEM_COMMIT | Imports.TypeAlloc.MEM_RESERVE, Imports.PageProtection.PAGE_EXECUTE_READWRITE);
UIntPtr bytesWritten;
Imports.NtWriteVirtualMemory(Imports.GetCurrentProcess(), ptr, ShellCode, (UIntPtr)ShellCode.Length, out bytesWritten);
Imports.PageProtection flOld = new Imports.PageProtection();
Imports.NtProtectVirtualMemory(Imports.GetCurrentProcess(), ref ptr, ref RegionSize, Imports.PageProtection.PAGE_EXECUTE_READ, ref flOld);
ShellCodeCaller load = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ShellCodeCaller));
load();
Imports.NtFreeVirtualMemory(Imports.GetCurrentProcess(), ref ptr, ref RegionSize, Imports.FreeType.MEM_RELEASE);
}
}
public void LoadWithKernel32()
{
if (this.Asynchronous)
{
Task.Run(() =>
{
this.ptr = Imports.VirtualAlloc(IntPtr.Zero, (IntPtr)ShellCode.Length, Imports.TypeAlloc.MEM_COMMIT | Imports.TypeAlloc.MEM_RESERVE, Imports.PageProtection.PAGE_EXECUTE_READWRITE);
uint RegionSize = (uint)ShellCode.Length;
UIntPtr writtenBytes;
Imports.WriteProcessMemory(Imports.GetCurrentProcess(), ptr, ShellCode, (UIntPtr)ShellCode.Length, out writtenBytes);
Imports.PageProtection flOld;
Imports.VirtualProtect(ptr, RegionSize, Imports.PageProtection.PAGE_EXECUTE_READ, out flOld);
ShellCodeCaller load = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ShellCodeCaller));
load();
Imports.VirtualFree(ptr, (uint)0, Imports.FreeType.MEM_RELEASE);
});
}
else
{
this.ptr = Imports.VirtualAlloc(IntPtr.Zero, (IntPtr)ShellCode.Length, Imports.TypeAlloc.MEM_COMMIT | Imports.TypeAlloc.MEM_RESERVE, Imports.PageProtection.PAGE_EXECUTE_READWRITE);
uint RegionSize = (uint)ShellCode.Length;
UIntPtr writtenBytes;
Imports.WriteProcessMemory(Imports.GetCurrentProcess(), ptr, ShellCode, (UIntPtr)ShellCode.Length, out writtenBytes);
Imports.PageProtection flOld;
Imports.VirtualProtect(ptr, RegionSize, Imports.PageProtection.PAGE_EXECUTE_READ, out flOld);
ShellCodeCaller load = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ShellCodeCaller));
load();
Imports.VirtualFree(ptr, (uint)0, Imports.FreeType.MEM_RELEASE);
}
}
private static class Imports
{
internal const String KERNEL32 = "kernel32.dll";
internal const String NTDLL = "ntdll.dll";
[DllImport(NTDLL, SetLastError = true, ExactSpelling = true)]
public static extern uint NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref uint RegionSize, TypeAlloc AllocationType, PageProtection Protect);
[DllImport(NTDLL, SetLastError = true, ExactSpelling = true)]
public static extern uint NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, byte[] buffer, UIntPtr bufferSize, out UIntPtr written);
[DllImport(NTDLL, SetLastError = true, ExactSpelling = true)]
public static extern uint NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref uint numberOfBytes, PageProtection newProtect, ref PageProtection oldProtect);
[DllImport(NTDLL, SetLastError = true, ExactSpelling = true)]
public static extern uint NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref uint RegionSize, FreeType FreeType);
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr VirtualAlloc(IntPtr address, IntPtr numBytes, TypeAlloc commitOrReserve, PageProtection pageProtectionMode);
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr VirtualFree(IntPtr lpAddress, uint dwSize, FreeType FreeType);
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, PageProtection flNewProtect, out PageProtection lpflOldProtect);
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out UIntPtr lpNumberOfBytesWritten);
public enum PageProtection : uint
{
PAGE_EXECUTE = 0x10,
PAGE_EXECUTE_READ = 0x20,
PAGE_EXECUTE_READWRITE = 0x40,
PAGE_EXECUTE_WRITECOPY = 0x80,
PAGE_NOACCESS = 0x01,
PAGE_READONLY = 0x02,
PAGE_READWRITE = 0x04,
PAGE_WRITECOPY = 0x08,
PAGE_TARGETS_INVALID = 0x40000000,
PAGE_TARGETS_NO_UPDATE = 0x40000000,
PAGE_GUARD = 0x100,
PAGE_NOCACHE = 0x200,
PAGE_WRITECOMBINE = 0x400
}
public enum TypeAlloc : uint
{
MEM_COMMIT = 0x00001000,
MEM_RESERVE = 0x00002000,
MEM_RESET = 0x00080000,
MEM_RESET_UNDO = 0x1000000,
MEM_LARGE_PAGES = 0x20000000,
MEM_PHYSICAL = 0x00400000,
MEM_TOP_DOWN = 0x00100000,
MEM_WRITE_WATCH = 0x00200000
}
public enum FreeType : uint
{
MEM_DECOMMIT = 0x00004000,
MEM_RELEASE = 0x00008000,
MEM_COALESCE_PLACEHOLDERS = 0x00000001,
MEM_PRESERVE_PLACEHOLDER = 0x00000002
}
}
private bool _disposed = false;
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
// Public implementation of Dispose pattern callable by consumers.
public void Dispose() => Dispose(true);
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
_disposed = true;
GC.SuppressFinalize(this);
}
}
}