Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[C#] Static Dll Injector

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming -> General programming+
View previous topic :: View next topic  
Author Message
samuri25404
Grandmaster Cheater
Reputation: 7

Joined: 04 May 2007
Posts: 955
Location: Why do you care?

PostPosted: Tue Jan 29, 2008 10:19 pm    Post subject: [C#] Static Dll Injector Reply with quote

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

_________________
Wiccaan wrote:

Oh jeez, watchout I'm a bias person! Locked.


Auto Assembly Tuts:
In Depth Tutorial on AA
Extended
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming -> General programming+ All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites