C#中的DLL注入
來源:互聯網
上載者:User
C#中的DLL注入
事實上dll注入很簡單,無非就是調用virtualAllocEx,WriteProcessMemory,OpenProcess,CreateRemoteThread等API函數,因為我是學c#的,所以也想看一下c#這方面的文章,但在網上找了半天,沒有找到一篇,也許是c#剛興起的緣故,學c#的並不多,沒辦法,只好自己移植一下,因為凡是用到API函數,所有的編程的語言都是相同的,這就為我們的移植帶來了方便,學c#的一般應該對API的調用概念很淡,因為c#通常不會去調用API函數,因為這些已經被封裝了,在vb,vc 等語言中要結束一個進程,首先就必須要得到這個進程的控制代碼,然後才能進行相應的關閉進程等操作,得到控制代碼要用到OpenProcess API函數,結束進程要用到TerminateProcess API函數,但是在c#中你根本不需要知道這些API函數就能完成同樣的功能,所以你要是想瞭解一下API的相關知識,學一點vb是一個很好的選擇。好了!下面就開始我們的c# dll注入之旅吧!
首先需要加入以下API函數:
[DllImport(kernel32.dll)]
public static extern int VirtualAllocEx(IntPtr hwnd, int lpaddress, int size, int type, int tect);
[DllImport(kernel32.dll)]
public static extern int WriteProcessMemory(IntPtr hwnd, int baseaddress, string buffer, int nsize, int filewriten );
[DllImport(kernel32.dll)]
public static extern int GetProcAddress(int hwnd, string lpname);
[DllImport(kernel32.dll)]
public static extern int GetModuleHandleA(string name);
[DllImport(kernel32.dll)]
public static extern int CreateRemoteThread(IntPtr hwnd, int attrib, int size, int address, int par, int flags, int threadid);
C#聲明API比較複雜,因為是調用非託管的dll,所以要用到DllImport來調用非託管的dll,他還有很多屬性在這就不多說了,網上有很介紹,可以去查一下,不過c#調用自身的變得動態連結程式庫是倒是很方便,直接加個引用就ok了,調用dll要用的一個引用:using System.Runtime.InteropServices;這個不要忘了加上,下面是編好的所有代碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace dllinject
{
public partial class Form1 : Form
{
[DllImport(kernel32.dll)] //聲明API函數
public static extern int VirtualAllocEx(IntPtr hwnd, int lpaddress, int size, int type, int tect);
[DllImport(kernel32.dll)]
public static extern int WriteProcessMemory(IntPtr hwnd, int baseaddress, string buffer, int nsize, int filewriten );
[DllImport(kernel32.dll)]
public static extern int GetProcAddress(int hwnd, string lpname);
[DllImport(kernel32.dll)]
public static extern int GetModuleHandleA(string name);
[DllImport(kernel32.dll)]
public static extern int CreateRemoteThread(IntPtr hwnd, int attrib, int size, int address, int par, int flags, int threadid);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int ok1;
//int ok2;
//int hwnd;
int baseaddress;
int temp=0;
int hack;
int yan;
string dllname;
dllname = c:\\dll.dll;
int dlllength;
dlllength = dllname.Length 1;
Process[] pname = Process.GetProcesses(); //取得所有進程
foreach (Process name in pname) //遍曆進程
{
//MessageBox.Show(name.ProcessName.ToLower());
if (name.ProcessName.ToLower().IndexOf(notepad) != -1) //所示記事本,那麼下面開始注入
{
baseaddress = VirtualAllocEx(name.Handle, 0, dlllength , 4096, 4); //申請記憶體空間
if (baseaddress == 0) //返回0則操作失敗,下面都是
{
MessageBox.Show(申請記憶體空間失敗!!);
Application.Exit();
}
ok1 = WriteProcessMemory(name.Handle, baseaddress, dllname, dlllength, temp); //寫記憶體
if (ok1 == 0)
{
MessageBox.Show(寫記憶體失敗!!);
Application.Exit();
}
hack = GetProcAddress(GetModuleHandleA(Kernel32), LoadLibraryA); //取得loadlibarary在kernek32.dll地址
if (hack == 0)
{
MessageBox.Show(無法取得函數的進入點!!);
Application.Exit();
}
yan = CreateRemoteThread(name.Handle, 0, 0, hack, baseaddress, 0, temp); //建立遠程線程。
if (yan == 0)
{
MessageBox.Show(建立遠程線程失敗!!);
Application.Exit();
}
else
{
MessageBox.Show(已成功注入dll!!);
}
}
}
}
}