简体   繁体   中英

Injecting c++ dll into an exe using c#

Why my C# code didn't inject dll into an exe but the program show me the message box "Injected!" ? The .dll it self is coded with c++ , and the exe is coded with C++ and i'm trying to inject with my C# code, How it not working ? This is my injector method

[DllImport("kernel32")]
public static extern IntPtr CreateRemoteThread(
  IntPtr hProcess,
  IntPtr lpThreadAttributes,
  uint dwStackSize,
  UIntPtr lpStartAddress, // raw Pointer into remote process
  IntPtr lpParameter,
  uint dwCreationFlags,
  out IntPtr lpThreadId
);

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
    UInt32 dwDesiredAccess,
    Int32 bInheritHandle,
    Int32 dwProcessId
    );

[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(
IntPtr hObject
);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool VirtualFreeEx(
    IntPtr hProcess,
    IntPtr lpAddress,
    UIntPtr dwSize,
    uint dwFreeType
    );

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern UIntPtr GetProcAddress(
    IntPtr hModule,
    string procName
    );

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(
    IntPtr hProcess,
    IntPtr lpAddress,
    uint dwSize,
    uint flAllocationType,
    uint flProtect
    );

[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    string lpBuffer,
    UIntPtr nSize,
    out IntPtr lpNumberOfBytesWritten
);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(
    string lpModuleName
    );

[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
internal static extern Int32 WaitForSingleObject(
    IntPtr handle,
    Int32 milliseconds
    );

public Int32 GetProcessId(String proc)
{
    Process[] ProcList;
    ProcList = Process.GetProcessesByName(proc);
    return ProcList[0].Id;
}

public void InjectDLL(IntPtr hProcess, String strDLLName)
{
    IntPtr bytesout;

    // Length of string containing the DLL file name +1 byte padding
    Int32 LenWrite = strDLLName.Length + 1;
    // Allocate memory within the virtual address space of the target process
    IntPtr AllocMem = (IntPtr)VirtualAllocEx(hProcess, (IntPtr)null, (uint)LenWrite, 0x1000, 0x40); //allocation pour WriteProcessMemory

    // Write DLL file name to allocated memory in target process
    WriteProcessMemory(hProcess, AllocMem, strDLLName, (UIntPtr)LenWrite, out bytesout);
    // Function pointer "Injector"
    UIntPtr Injector = (UIntPtr)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");

    if (Injector == null)
    {
        MessageBox.Show(" Injector Error! \n ");
        // return failed
        return;
    }

    // Create thread in target process, and store handle in hThread
    IntPtr hThread = (IntPtr)CreateRemoteThread(hProcess, (IntPtr)null, 0, Injector, AllocMem, 0, out bytesout);
    // Make sure thread handle is valid
    if (hThread == null)
    {
        //incorrect thread handle ... return failed
        MessageBox.Show(" hThread [ 1 ] Error! \n ");
        return;
    }
    // Time-out is 10 seconds...
    int Result = WaitForSingleObject(hThread, 10 * 1000);
    // Check whether thread timed out...
    if (Result == 0x00000080L || Result == 0x00000102L || Result == 0xFFFFFFFF)
    {
        /* Thread timed out... */
        MessageBox.Show(" hThread [ 2 ] Error! \n ");
        // Make sure thread handle is valid before closing... prevents crashes.
        if (hThread != null)
        {
            //Close thread in target process
            CloseHandle(hThread);
        }
        return;
    }
    // Sleep thread for 1 second
    Thread.Sleep(1000);
    // Clear up allocated space ( Allocmem )
    VirtualFreeEx(hProcess, AllocMem, (UIntPtr)0, 0x8000);
    // Make sure thread handle is valid before closing... prevents crashes.
    if (hThread != null)
    {
        //Close thread in target process
        CloseHandle(hThread);
    }
    // return succeeded
    return;
}

And then i try to running some program and inject it with my dll

private void metroButton2_Click(object sender, EventArgs e)
{
    String strDLLName = @"spd.dll";
    String strProcessName = "app";
    System.Diagnostics.Process.Start("app.exe", "!#@$$$!");                                   
    Int32 ProcID = GetProcessId(strProcessName);
    if (ProcID >= 0)
    {
        IntPtr hProcess = (IntPtr)OpenProcess(0x1F0FFF, 1, ProcID);
        if (hProcess == null)
        {
            MessageBox.Show("OpenProcess() Failed!");
            return;
        }
        else
        {
            InjectDLL(hProcess, strDLLName);
            MessageBox.Show("Injected!");  
        }

    }

}

It show me the output : "Injected!" but on .exe the .dll is not injected What should i do ? Giving more Thread.Sleep before Inject / After running the .exe ? Any help will be appreciated!

Take note that C++ 's NULL (0) is not the same as C# 's null . The equivalent you are looking for is IntPtr.Zero .


Take GetProcAddress function for example :

Return value

If the function succeeds, the return value is the address of the exported function or variable.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Source: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx

This NULL here is a c++ macro which is defined as :

#define NULL 0

null is not equal to IntPtr.Zero , but (IntPtr)null is equal to IntPtr.Zero .

I know this is shamefully , many of my stackoverflow question answered by myself, the idea is always come late (after i post the question) so this is the answer The injector above is working correctly , and why the injector didn't inject it ? yes this is like my thought before , the injector not injected dll successfully because of i need to give Thread.Sleep(1000) after start the app and before injecting the .dll , and using Worker, Like this :

void worker_DoWork2(object sender, DoWorkEventArgs e)
        {
            System.Diagnostics.Process.Start("app.exe", "!#@$$$!");

        }

public void metroButton2_Click(object sender, EventArgs e)
        {
            var worker2 = new BackgroundWorker();
            worker2.DoWork += new DoWorkEventHandler(worker_DoWork2);
            worker2.RunWorkerAsync();

            Thread.Sleep(1000);

            String strDLLName = "spd.dll";
            String strProcessName = "app";    
            Int32 ProcID = GetProcessId(strProcessName);
            if (ProcID >= 0)
            {
                IntPtr hProcess = (IntPtr)OpenProcess(0x1F0FFF, 1, ProcID);
                if (hProcess == null)
                {
                    return;
                }
                else
                {
                    InjectDLL(hProcess, strDLLName);
                }  
            }
            Application.Exit();
        }

Now the injector work successfully , and i need to run this application with administrator privilege. Thank you !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM