| samuri25404 Grandmaster Cheater
 
  Reputation: 7 
 Joined: 04 May 2007
 Posts: 955
 Location: Why do you care?
 
 | 
			
				|  Posted: Tue Jan 29, 2008 10:19 pm    Post subject: [C#] Static Dll Injector |   |  
				| 
 |  
				| REEDIT: The Dll Injector has been fixed! 
 I've created a static dll injector class (if you didn't get by the title, :p).
 
 So, here it is:
 
 
  	  | Code: |  	  | using System;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
 //This is used to actually inject the specific DLL into the selected process
 
 namespace InjectMe
 {
 public static class Inject
 {
 private static class WINAPI
 {
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern IntPtr OpenProcess(
 UInt32 dwDesiredAccess,
 Int32 bInheritHandle,
 UInt32 dwProcessId);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern Int32 CloseHandle(
 IntPtr hObject);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern IntPtr GetProcAddress(
 IntPtr hModule,
 string lpProcName);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern IntPtr GetModuleHandle(
 string lpModuleName);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern IntPtr VirtualAllocEx(
 IntPtr hProcess,
 IntPtr lpAddress,
 IntPtr dwSize,
 uint flAllocationType,
 uint flProtect);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern Int32 WriteProcessMemory(
 IntPtr hProcess,
 IntPtr lpBaseAddress,
 byte[] buffer,
 uint size,
 out IntPtr lpNumberOfBytesWritten);
 
 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern IntPtr CreateRemoteThread(
 IntPtr hProcess,
 IntPtr lpThreadAttribute,
 IntPtr dwStackSize,
 IntPtr lpStartAddress,
 IntPtr lpParameter,
 uint dwCreationFlags,
 IntPtr lpThreadId);
 
 public static class VAE_Enums
 {
 public enum AllocationType
 {
 MEM_COMMIT = 0x1000,
 MEM_RESERVE = 0x2000,
 MEM_RESET = 0x80000,
 }
 
 public enum ProtectionConstants
 {
 PAGE_EXECUTE = 0X10,
 PAGE_EXECUTE_READ = 0X20,
 PAGE_EXECUTE_READWRITE = 0X40,
 PAGE_EXECUTE_WRITECOPY = 0X80,
 PAGE_NOACCESS = 0X01
 }
 }
 }
 
 public static bool DoInject(
 Process pToBeInjected,
 string sDllPath,
 out string sError)
 {
 IntPtr hwnd = IntPtr.Zero;
 if (!CRT(pToBeInjected, sDllPath, out sError, out hwnd)) //CreateRemoteThread
 {
 //close the handle, since the method wasn't able to get to that
 if (hwnd != (IntPtr)0)
 WINAPI.CloseHandle(hwnd);
 return false;
 }
 int wee = Marshal.GetLastWin32Error();
 return true;
 }
 
 private static bool CRT(
 Process pToBeInjected,
 string sDllPath,
 out string sError,
 out IntPtr hwnd)
 {
 sError = String.Empty; //in case we encounter no errors
 
 IntPtr hndProc = WINAPI.OpenProcess(
 (0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation
 //write, and read
 1,
 (uint)pToBeInjected.Id);
 
 hwnd = hndProc;
 
 if (hndProc == (IntPtr)0)
 {
 sError = "Unable to attatch to process.\n";
 sError += "Error code: " + Marshal.GetLastWin32Error();
 return false;
 }
 
 IntPtr lpLLAddress = WINAPI.GetProcAddress(
 WINAPI.GetModuleHandle("kernel32.dll"),
 "LoadLibraryA");
 
 if (lpLLAddress == (IntPtr)0)
 {
 sError = "Unable to find address of \"LoadLibraryA\".\n";
 sError += "Error code: " + Marshal.GetLastWin32Error();
 return false;
 }
 
 IntPtr lpAddress = WINAPI.VirtualAllocEx(
 hndProc,
 (IntPtr)null,
 (IntPtr)sDllPath.Length, //520 bytes should be enough
 (uint)WINAPI.VAE_Enums.AllocationType.MEM_COMMIT |
 (uint)WINAPI.VAE_Enums.AllocationType.MEM_RESERVE,
 (uint)WINAPI.VAE_Enums.ProtectionConstants.PAGE_EXECUTE_READWRITE);
 
 if (lpAddress == (IntPtr)0)
 {
 if (lpAddress == (IntPtr)0)
 {
 sError = "Unable to allocate memory to target process.\n";
 sError += "Error code: " + Marshal.GetLastWin32Error();
 return false;
 }
 }
 
 byte[] bytes = CalcBytes(sDllPath);
 IntPtr ipTmp = IntPtr.Zero;
 
 WINAPI.WriteProcessMemory(
 hndProc,
 lpAddress,
 bytes,
 (uint)bytes.Length,
 out ipTmp);
 
 if (Marshal.GetLastWin32Error() != 0)
 {
 sError = "Unable to write memory to process.";
 sError += "Error code: " + Marshal.GetLastWin32Error();
 return false;
 }
 
 IntPtr ipThread = WINAPI.CreateRemoteThread(
 hndProc,
 (IntPtr)null,
 (IntPtr)0,
 lpLLAddress,
 lpAddress,
 0,
 (IntPtr)null);
 
 if (ipThread == (IntPtr)0)
 {
 sError = "Unable to load dll into memory.";
 sError += "Error code: " + Marshal.GetLastWin32Error();
 return false;
 }
 
 return true;
 }
 
 private static byte[] CalcBytes(string sToConvert)
 {
 byte[] bRet = System.Text.Encoding.ASCII.GetBytes(sToConvert);
 return bRet;
 }
 }
 }
 
 | 
 
 I've created a sample application using this class.
 
 Here's a screenshot:
 
 [img=http://img169.imageshack.us/img169/3048/picthingtq3.png][/img]
 
 Basically, you load the app, browse to your dll, select your application, and click inject.
 
 ~~
 
 Here's the code for the Main form:
 
 
  	  | Code: |  	  | using System;
 using System.Diagnostics;
 using System.ComponentModel;
 using System.Windows.Forms;
 
 namespace InjectMe
 {
 public partial class MainUI : Form
 {
 public MainUI()
 {
 InitializeComponent();
 }
 
 public static Process pApplication = null;
 public static string  sApplication = String.Empty;
 
 private void BtnBrowseDll_Click(object sender, EventArgs e)
 {
 OpenFileDialog ofd = new OpenFileDialog();
 ofd.Filter = "Dynamic Link Library|*.dll";
 ofd.FileOk += new CancelEventHandler(dll_FileOk);
 ofd.ShowDialog();
 }
 
 private void dll_FileOk(object sender, CancelEventArgs e)
 {
 OpenFileDialog ofd = (OpenFileDialog)sender;
 TxtDllPath.Text = ofd.FileName;
 
 //now dispose of the object
 
 ofd.Dispose();
 }
 
 private void BtnBrowseApp_Click(object sender, EventArgs e)
 {
 ProcFrm pf = new ProcFrm();
 pf.ShowDialog(this);
 TxtApp.Text = sApplication; //It will wait for pf to close, and before pf
 //closes, it will have set sApplication
 }
 
 private void BtnInject_Click(object sender, EventArgs e)
 {
 string sError = String.Empty;
 if (!Inject.DoInject(pApplication, TxtDllPath.Text, out sError))
 MessageBox.Show("The following error occured while injecting the \n" +
 "dll into the application: \n" +
 sError);
 }
 }
 }
 
 | 
 
 Here's the code to the Process Form:
 
 
  	  | Code: |  	  | using System;
 using System.Diagnostics;
 using System.Windows.Forms;
 
 //This class is used to select the process to inject the dll into
 
 namespace InjectMe
 {
 public partial class ProcFrm : Form
 {
 public ProcFrm()
 {
 InitializeComponent();
 }
 
 private void ProcFrm_Load(object sender, EventArgs e)
 {
 //populate the list box with all the running processes
 
 string sLstItem = String.Empty;
 
 foreach (Process p in Process.GetProcesses())
 {
 sLstItem = p.Id.ToString();
 sLstItem = sLstItem.PadLeft(8, '0');
 sLstItem = sLstItem + " " + p.ProcessName;
 LstProcs.Items.Add(sLstItem);
 }
 
 //now sort
 
 LstProcs.Sorted = true; //Some event handler somewhere sorts
 //the list box when this is changed to true
 }
 
 private void LstProcs_DoubleClick(object sender, EventArgs e)
 {
 BtnSelect_Click(null, null); //=D
 }
 
 private void BtnSelect_Click(object sender, EventArgs e)
 {
 if (LstProcs.SelectedIndex == -1)
 return;
 
 string sPID = String.Empty;
 string[] saData = ((string)LstProcs.Items[LstProcs.SelectedIndex]).Split(' ');
 sPID = saData[0]; //it'll be "xxxxxxxx procname"
 int iPID = int.Parse(sPID);
 
 MainUI.pApplication = Process.GetProcessById(iPID);
 
 if (MainUI.pApplication != null)
 MainUI.sApplication = MainUI.pApplication.ProcessName;
 
 this.Close(); //done with this form
 }
 }
 }
 
 | 
 
 CREDITS
 
 Wiccaan:
 
 For creating a post about the Dll stuff on Extalia. Since I'm no good at C++, I had to use his code to make a sample Dll to inject into minesweeper
 
 MSDN:
 
 For helping out with all the API crap. =)
 
 Me:
 
 For working on this so much. =P
 _________________
 
 |  |