尝试在我自己的程序中注入库

问题描述 投票:0回答:1

我目前正在尝试将一个库注入我编写的程序中(出于学习目的,这只是出于好奇)。我想我设法做到了,但是看来我做的代码可能是切入点?

这是我编写的代码:我使用Visual Studio代码生成了一种hello-world dll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace InjectDll
{
    public class Inject
    {

        [DllImport("kernel32")]
        static extern bool AllocConsole();

        public Inject()
        {
            AllocConsole();
            Console.WriteLine("blablabla");
        }

        public string test()
        {
            AllocConsole();
            return "dll is injected";
        }
    }
}

然后我制作了一个基本程序,我想在这里测试我的注射=>

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace basicProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            while(true){
                Thread.Sleep(1000);
                Console.WriteLine("Hello world");
            }
        }
    }
}

所以现在我有了自己的dll和要尝试进行注入的程序。我只需要编写注入器,这就是我所做的=>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace injectorTest.Inject
{
    public enum DllInjectionResult
    {
        DllNotFound,
        GameProcessNotFound,
        InjectionFailed,
        Success
    }

    class Injector
    {

        static readonly IntPtr INTPTR_ZERO = (IntPtr)0;
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetModuleHandle(string lpModuleName);

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

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttribute, IntPtr dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

        //[DllImport("InjectDll.dll", CallingConvention = CallingConvention.StdCall)]


        private const string DLL_NAME = "hello.dll";
        private Process myProcess;
        private string myPath;
        public Injector()
        {

        }
        public  Injector(Process myProcess)
        {
            this.myProcess = myProcess;
            this.myPath = Path.GetDirectoryName(myProcess.MainModule.FileName);
        }

        private void checkDll()
        {
            if (!File.Exists(myPath + @"\hello.dll")) {

            }
        }

        public DllInjectionResult inject()
        {
            if (!File.Exists(myPath + "\\hello.dll"))
            {
                return DllInjectionResult.DllNotFound;
            }

            Console.WriteLine("process id : " + myProcess.Id);
            if (myProcess == null)
            {
                return DllInjectionResult.GameProcessNotFound;
            }

            if (!startInject((uint)myProcess.Id, myPath + "\\hello.dll"))
            {
               return DllInjectionResult.InjectionFailed;
            }
           return DllInjectionResult.Success;
        }

        private bool startInject(uint processId, string dllPath)
        {
            IntPtr handleProcess = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, processId);

              if (handleProcess == INTPTR_ZERO)
              {
                  return false;
              }

              IntPtr lpAddress = VirtualAllocEx(handleProcess, (IntPtr)null, (IntPtr)dllPath.Length, (0x1000 | 0x2000), 0X40);
              Console.WriteLine("lpaddr: " + lpAddress);

              if (lpAddress == INTPTR_ZERO)
              {
                  return false;
              }

              byte[] bytes = Encoding.ASCII.GetBytes(dllPath);

              if (WriteProcessMemory(handleProcess, lpAddress, bytes, (uint)bytes.Length, 0) == 0)
              {
                  return false;
              }

              IntPtr lpLLAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryW");


              if (lpLLAddress == INTPTR_ZERO)
              {
                  return false;
              }
              var remoteThread = CreateRemoteThread(handleProcess, (IntPtr)null, INTPTR_ZERO, lpLLAddress, lpAddress, 0, (IntPtr)null);
              if (remoteThread == INTPTR_ZERO)
              {
                  return false;
              }

              CloseHandle(handleProcess);

              return true;
        }


    }
}

我似乎无法通过ida(看着我尝试注入的helloworld程序)看到LoadLibraryW在我启动注入器时就触发了(然后我可以看到注入的dll的路径,但似乎没有失败)触发smthg。

似乎我丢失了某些东西(例如我的dll中的入口点?)。

c# dll code-injection dll-injection entry-point
1个回答
0
投票

一个普通的C / C ++ DLL将具有一个DllMain,该DllMain在调用LoadLibrary时执行,然后传递给switch语句,通常我们将代码放入DLL_PROCESS_ATTACH例中,该例将在注入时执行。

此等效项在C#/ CLR中不存在,但是您可以通过使用静态构造函数做一些棘手的事情来产生相同的效果。

创建一个类并初始化该类的对象,这将依次调用静态构造函数。像这样的东西:

class someClass
{
   //Static constructor
   static someClass()
   {
       Console.WriteLine("injected");
   }
 }
© www.soinside.com 2019 - 2024. All rights reserved.