Online Code Sharing
 
HomePortalCalendarFAQSearchMemberlistUsergroupsRegisterLog in

Share | 
 

 [C#] Static Dll Injector

View previous topic View next topic Go down 
AuthorMessage
Admin
Admin


Posts : 34
Join date : 2011-10-12

PostSubject: [C#] Static Dll Injector   Wed Oct 12, 2011 11:59 am

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
Back to top Go down
View user profile http://tcell.topicboard.net
 
[C#] Static Dll Injector
View previous topic View next topic Back to top 
Page 1 of 1
 Similar topics
-
» How could I pass datafile as parameter to dataProvider
» How to test dynamic ids using Selenium
» Webdriver code for dropdown selection is not working
» Diy Skimmer mezzei injector
» Becket injector skimmer

Permissions in this forum:You cannot reply to topics in this forum
Tcell Coding :: General Programing :: C# Scripting-
Jump to: