Code:
class Injector
{
private string _dll = AppDomain.CurrentDomain.BaseDirectory + "Soup.dll";
public bool IsModuleInjected(int pid, string moduleName)
{
var process = Process.GetProcessById(pid);
foreach (ProcessModule module in process.Modules)
{
if (!module.FileName.Equals(_dll)) continue;
return true;
}
return false;
}
public bool Inject(int pid)
{
var process = Process.GetProcessById(pid);
if (IsModuleInjected(pid, _dll)) {
return false;
}
var hProcess = OpenProcess(ProcessAccessFlags.All, false, process.Id);
if (hProcess == IntPtr.Zero)
{
return false;
}
var allocAddress = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)Encoding.Unicode.GetByteCount(_dll.ToCharArray())+1, AllocationType.Commit, MemoryProtection.ReadWrite);
if (allocAddress == IntPtr.Zero) {
return false;
}
if (!WriteProcessMemory(hProcess, allocAddress, Encoding.Unicode.GetBytes(_dll),
Encoding.Unicode.GetByteCount(_dll.ToCharArray()), out _))
{
return false;
}
var moduleHandle = GetModuleHandle("kernel32.dll");
if (moduleHandle == IntPtr.Zero) {
return false;
}
var procAddress = GetProcAddress(moduleHandle, "LoadLibraryW");
if (procAddress == IntPtr.Zero) {
return false;
}
var hRemoteThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, procAddress, allocAddress, 0, IntPtr.Zero);
if (hRemoteThread == IntPtr.Zero) {
return false;
}
var result = WaitForSingleObject(hRemoteThread, int.MaxValue);
if (!VirtualFreeEx(hProcess, allocAddress, Encoding.Unicode.GetByteCount(_dll)+1, AllocationType.Decommit))
{
return false;
}
if (!CloseHandle(hProcess))
{
return false;
}
if (!IsModuleInjected(pid, _dll)) return false;
return true;
}
public bool Eject(int pid)
{
var process = Process.GetProcessById(pid);
ProcessModule targetModule = null;
foreach (ProcessModule module in process.Modules)
{
if (module.FileName.Equals(_dll))
{
targetModule = module;
}
}
if (targetModule == null)
{
return false;
}
var hProcess = OpenProcess(ProcessAccessFlags.All, false, process.Id);
if (hProcess == IntPtr.Zero)
{
return false;
}
var moduleHandle = GetModuleHandle("kernel32.dll");
if (moduleHandle == IntPtr.Zero)
{
return false;
}
var procAddress = GetProcAddress(moduleHandle, "FreeLibrary");
if (procAddress == IntPtr.Zero)
{
return false;
}
var hRemoteThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, procAddress, targetModule.BaseAddress, 0, IntPtr.Zero);
if (hRemoteThread == IntPtr.Zero)
{
return false;
}
WaitForSingleObject(hRemoteThread, 10 * 1000);
if (!IsModuleInjected(pid, _dll))
{
return true;
}
return false;
}
public bool Call(int pid)
{
var process = Process.GetProcessById(pid);
ProcessModule targetModule = null;
foreach (ProcessModule module in process.Modules)
{
if (module.FileName.Equals(_dll))
{
targetModule = module;
}
}
if (targetModule == null)
{
return false;
}
var hProcess = OpenProcess(ProcessAccessFlags.All, false, process.Id);
if (hProcess == IntPtr.Zero)
{
return false;
}
var hLoaded = LoadLibraryEx(_dll, IntPtr.Zero, LoadLibraryFlags.DontResolveDllReferences);
if (hLoaded == IntPtr.Zero) {
return false;
}
var procAddress = GetProcAddress(hLoaded, "ShowMessage");
if (procAddress == IntPtr.Zero)
{
return false;
}
var offset = (ulong)procAddress - (ulong)hLoaded;
if (!FreeLibrary(hLoaded))
{
return false;
}
var hRemoteThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, IntPtr.Add(targetModule.BaseAddress, (int)offset), IntPtr.Zero, 0, IntPtr.Zero);
if (hRemoteThread == IntPtr.Zero)
{
return false;
}
WaitForSingleObject(hRemoteThread, 10 * 1000);
if (CloseHandle(hProcess)) return true;
return false;
}
}
My DLL is plain and simple.