为什么我的类文件在内存中启动时不执行?

时间:2016-10-25 15:05:46

标签: c# .net winforms dll inject

所以我有一个非常基本的cs文件,它是一个.dll文件。

我正在使用Process Hacker手动注入我的NotePad进程.. 此时它应该执行它并运行MessageBox正确吗? (纠正我,如果我错了那个)

起初我认为我的喷油器有问题,但似乎是dll。 (随意通过下面的注射器检查) (这是我第一次尝试创建一个dll文件)

我是否需要以某种方式制作Dll钩子,或者它是否真的很简单?

DLL。

using System;
using System.Windows.Forms;


namespace SomeName
{
    public class Class1
    {
        public static void Main()
        {
            MessageBox.Show("Lets try this");
        }
    }

}

注射器

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FormDLLInjection
{
    public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();
        }

        [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;
        }

        private void injectBtn_Click(object sender, EventArgs e)
        {
            String strDLLName = @"DllPath"; // here you put the dll you want, only the path.
            String strProcessName = "notepad"; //here you will put the process name without ".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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  

为什么我的类文件在内存中启动时不执行?

遗憾的是,您无法将.NET程序集注入到本身没有首先加载CLR的本机进程中。当您尝试从本机进程加载托管DLL时,.NET不会神奇地做到这一点。后者的唯一例外是托管代码是作为COM对象公开的。

现在你的代码实际上可能导致记事本尝试加载你的.dll,但是由于缺少DllMain(Windows希望它在此时成为本机DLL)将失败。

作为 cdkMoose' 的后续评论,即使您将其DllMain称为“{1}},评论也是默认MainDllMain存在于托管程序集EXPORTS表中,因为它没有。有additional steps用于手动公开托管方法,使其显示为本机进程可识别的EXPORT条目。

这一切都没有意义吗?

让我们假设NotePad之前的prepared a CLR environment与SQL Server完全相同。它看起来像这样:

e.g.

HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;

// build runtime
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, 
    IID_PPV_ARGS(&pClrRuntimeHost));

// start runtime
hr = pClrRuntimeHost->Start();

然后在这种情况下,NotePad或SQL不会将LoadLibraryA用于您的程序集,而是:

eg.

// execute managed assembly
DWORD pReturnValue;
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
    L"T:\\FrameworkInjection\\_build\\debug\\anycpu\\InjectExample.exe", 
    L"InjectExample.Program", 
    L"EntryPoint", 
    L"hello .net runtime", 
    &pReturnValue);

...假设您的.NET程序集正在公开static int EntryPoint(String pwzArgument)

结论

所以关注:

  • 是否应将其称为MainDllMain
  • 在托管代码中构建和公开EXPORT条目

......我们不必担心因为:

  1. 本机进程必须首先准备CLR环境
  2. 托管CLR的原生流程无法关注您所谓的static方法
  3. CLR不需要EXPORTS
  4. 本机代码使用本机CLR API加载和运行程序集(而不是直接调用LoadLibrary
  5. 在您注入代码之前,

    本机进程must load the CLR first