下面的代碼,同時安裝勾子會出錯,現在的代碼只能勾一個函數
private void Form1_Load(object sender, EventArgs e)
{
send_Hook.Install("ws2_32.dll", "send", Marshal.GetFunctionPointerForDelegate(new sendCallback(sendProc)));
send_Hook.Install("ws2_32.dll", "recv", Marshal.GetFunctionPointerForDelegate(new recvCallback(toProc)));
}
怎麼才能即可接截Send,也可Recv
這裡是完整代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;
using api_hook;
namespace api_hook_封包學習
{
public partial class Form1 : Form
{
[DllImport("ws2_32.dll")]
static extern int send(int s, byte[] buf, int len, int flag);
[DllImport("ws2_32.dll")]
static extern int recv(int s, byte[] buf, int len, int flag);
APIHOOK send_Hook = new APIHOOK();
delegate int sendCallback(int s, IntPtr buf, int len, int flag);
delegate int recvCallback(int s, IntPtr buf, int len, int flag);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
send_Hook.Install("ws2_32.dll", "send", Marshal.GetFunctionPointerForDelegate(new sendCallback(sendProc)));
send_Hook.Install("ws2_32.dll", "recv", Marshal.GetFunctionPointerForDelegate(new recvCallback(toProc)));
}
int sendProc(int s, IntPtr buf, int len, int flag)
{
byte[] buffer = new byte[len];
Marshal.Copy(buf, buffer, 0, len); //讀封包數據,讀取後可進行條件修改,攔截,轉發等,記得處理後調用發送
send_Hook.Suspend(); //暫停攔截,轉交系統調用
int ret = send(s, buffer, len, flag); //發送數據,此處可進行攔截
send_Hook.Continue(); //恢復HOOK
return ret;
}
int toProc(int s, IntPtr buf, int len, int flag)
{
byte[] buffer = new byte[len];
Marshal.Copy(buf, buffer, 0, len); //讀封包數據
send_Hook.Suspend(); //暫停攔截,轉交系統調用
int ret = recv(s, buffer, len, flag); //發送數據,此處可對包進行處理操作
send_Hook.Continue(); //恢復HOOK
return ret;
}
private void button1_Click(object sender, EventArgs e)//按下時加載網頁進行測試數據
{
webBrowser1.Navigate("http://baidu.com");
}
}
//APIHOOK關鍵代碼類
public class APIHOOK
{
#region Api聲明
[DllImport("Kernel32.dll", EntryPoint = "GetModuleHandleA", CharSet = CharSet.Ansi)]
static extern IntPtr GetModuleHandle(
string lpModuleName
);
[DllImport("Kernel32.dll")]
static extern bool VirtualProtect(
IntPtr lpAddress,
int dwSize,
int flNewProtect,
ref int lpflOldProtect
);
[DllImport("Kernel32.dll", EntryPoint = "lstrcpynA", CharSet = CharSet.Ansi)]
static extern IntPtr lstrcpyn(
byte[] lpString1,
byte[] lpString2,
int iMaxLength
);
[DllImport("Kernel32.dll")]
static extern IntPtr GetProcAddress(
IntPtr hModule,
string lpProcName
);
[DllImport("Kernel32.dll")]
static extern bool FreeLibrary(
IntPtr hModule
);
#endregion
#region 常量定義表
const int PAGE_EXECUTE_READWRITE = 0x40;
#endregion
#region 變量表
IntPtr ProcAddress;
int lpflOldProtect = 0;
byte[] OldEntry = new byte[5];
byte[] NewEntry = new byte[5];
IntPtr OldAddress;
#endregion
public APIHOOK() { }
public APIHOOK(string ModuleName, string ProcName, IntPtr lpAddress)
{
Install(ModuleName, ProcName, lpAddress);
}
public bool Install(string ModuleName, string ProcName, IntPtr lpAddress)
{
IntPtr hModule = GetModuleHandle(ModuleName); //取模塊句柄
if (hModule == IntPtr.Zero) return false;
ProcAddress = GetProcAddress(hModule, ProcName); //取入口地址
if (ProcAddress == IntPtr.Zero) return false;
if (!VirtualProtect(ProcAddress, 5, PAGE_EXECUTE_READWRITE, ref lpflOldProtect)) return false; //修改內存屬性
Marshal.Copy(ProcAddress, OldEntry, 0, 5); //讀取前5字節
NewEntry = AddBytes(new byte[1] { 233 }, BitConverter.GetBytes((Int32)((Int32)lpAddress - (Int32)ProcAddress - 5))); //計算新入口跳轉
Marshal.Copy(NewEntry, 0, ProcAddress, 5); //寫入前5字節
OldEntry = AddBytes(OldEntry, new byte[5] { 233, 0, 0, 0, 0 });
OldAddress = lstrcpyn(OldEntry, OldEntry, 0); //取變量指針
Marshal.Copy(BitConverter.GetBytes((double)((Int32)ProcAddress - (Int32)OldAddress - 5)), 0, (IntPtr)(OldAddress.ToInt32() + 6), 4); //保存JMP
FreeLibrary(hModule); //釋放模塊句柄
return true;
}
public void Suspend()
{
Marshal.Copy(OldEntry, 0, ProcAddress, 5);
}
public void Continue()
{
Marshal.Copy(NewEntry, 0, ProcAddress, 5);
}
public bool Uninstall()
{
if (ProcAddress == IntPtr.Zero) return false;
Marshal.Copy(OldEntry, 0, ProcAddress, 5);
ProcAddress = IntPtr.Zero;
return true;
}
static byte[] AddBytes(byte[] a, byte[] b)
{
ArrayList retArray = new ArrayList();
for (int i = 0; i < a.Length; i++)
{
retArray.Add(a[i]);
}
for (int i = 0; i < b.Length; i++)
{
retArray.Add(b[i]);
}
return (byte[])retArray.ToArray(typeof(byte));
}
}
}
是因為你的ws2_32.dll裡面已經封裝了Recv的方法,當你加載第二個的時候沖突了。也就是函數沖定義