让代码更简单

[微信HOOK]C#给微信注入C++的dll文件

重要:本文最后更新于2022-08-12 21:34:53,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

这篇文章名字有点绕,不大好理解,简单来说就是C++派出了一名间谍,C#将这名间谍送进了敌人内部,并给了间谍一个合法使用敌人资源的身份。至于为什么C#不派自己的人去,那是因为C#的间谍送入敌方就不干活,哈哈哈。用程序的术语来说就是没有程序入口,无法主动执行任务!

[微信HOOK]C#给微信注入C++的dll文件

[微信HOOK]C#给微信注入C++的dll文件

首先使用C++写个dll,里面只有一个socket连接操作,代码如下:

复制
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")



#pragma unmanaged
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);

//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
#pragma warning(disable:4996)
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
serv_addr.sin_port = htons(5468); //端口

char buf[1024] = "success";
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

编译上面的代码生成dll文件,然后使用下面的C#代码注入微信,别问我为什么不用C++注入,不是更简单吗?我只想说,C++不是人用的,非常强大,但太TM难用了。

引入命名空间

复制
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

代码有点乱,将就看吧

复制
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public delegate void updata(String arg, int i);
Socket mysocket = null;
Dictionary<String, Socket> mydic = new Dictionary<string, Socket>();
Dictionary<String, Thread> mythread = new Dictionary<string, Thread>();
public Form1()
{
InitializeComponent();
}
//声明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 IntPtr CreateRemoteThread(IntPtr hwnd, int attrib, int size, int address, int par, int flags, int threadid);
[DllImport("KERNEL32.DLL ")]
public static extern int CloseHandle(IntPtr handle);

[DllImport("user32.dll", EntryPoint = "FindWindow")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);

//************************************************************
// 函数说明: 向进程注入DLL
//************************************************************
private int InjectDll(Process myProcess)
{
//获取当前工作目录下的dll
string dllfile = "F:\\vs porject\\cppdll\\CppDll\\Debug\\call.dll";
if (!File.Exists(dllfile))
{
MessageBox.Show("DLL文件丢失");
return 0;
}
//获取微信Pid

//检测dll是否已经注入
if (CheckIsInject(myProcess.Id))
{
//在微信进程中申请内存
Int32 AllocBaseAddress = VirtualAllocEx(myProcess.Handle, 0, dllfile.Length + 1, 4096, 4);
if (AllocBaseAddress == 0)
{
MessageBox.Show("内存分配失败", "错误");
return 0;
}
//写入dll路径到微信进程
if (WriteProcessMemory(myProcess.Handle, AllocBaseAddress, dllfile, dllfile.Length + 1, 0) == 0)
{
MessageBox.Show("DLL写入失败", "错误", 0);
return 0;
}
Int32 loadaddr = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (loadaddr == 0)
{
MessageBox.Show("取得LoadLibraryA的地址失败");
return 0;
}
IntPtr ThreadHwnd = CreateRemoteThread(myProcess.Handle, 0, 0, loadaddr, AllocBaseAddress, 0, 0);
if (ThreadHwnd == IntPtr.Zero)
{
MessageBox.Show("创建远程线程失败");
return 0;
}
CloseHandle(ThreadHwnd);
}
else
{
MessageBox.Show("dll已经注入,请退出所有微信重新注入!", "提示");
return 0;
}
return myProcess.Id;
}
//************************************************************
// 函数说明: 检测是否已经注入dll
//************************************************************
private bool CheckIsInject(int wxProcessid)
{
Process[] mProcessList = Process.GetProcesses(); //取得所有进程

foreach (Process mProcess in mProcessList) //遍历进程
{
if (mProcess.Id == wxProcessid)
{

ProcessModuleCollection myProcessModuleCollection = mProcess.Modules;
ProcessModule myProcessModule;
for (int i = 0; i < myProcessModuleCollection.Count; i++)
{
myProcessModule = myProcessModuleCollection[i];
if (myProcessModule.ModuleName == "CppDll.dll")
{
return false;
}
}
}

}
return true;
}

private void button1_Click_1(object sender, EventArgs e)
{
if (FindWindow("WeChatLoginWndForPC", null) != IntPtr.Zero)
{
MessageBox.Show("当前有微信登录窗口,请关闭后再注入");
return;
}
Process myProcess = new Process();
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("D:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe");
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();

while (FindWindow("WeChatLoginWndForPC", null) == IntPtr.Zero)
{
System.Threading.Thread.Sleep(500);
}
int pid= InjectDll(myProcess);
MessageBox.Show("pid:"+pid);
}

private void button2_Click(object sender, EventArgs e)
{
byte[] strmes = Encoding.UTF8.GetBytes(textBox1.Text.ToString());
String clent = comboBox1.Text;
mydic[clent].Send(strmes);
textBox2.Text += textBox1.Text;
textBox1.Text = "";
}

private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("等待连接");
comboBox1.SelectedIndex = comboBox1.Items.IndexOf("等待连接");
String ipadress = "127.0.0.1";
int prots = 5468;
mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipsa = IPAddress.Parse(ipadress);
IPEndPoint ipenp = new IPEndPoint(ipsa, prots);
mysocket.Bind(ipenp);
mysocket.Listen(10);
Thread thread1 = new Thread(new ThreadStart(waitconnet));
thread1.IsBackground = true;
thread1.Start();
}
public void waitconnet()
{
updata ipda = new updata(updataui);
while (true)
{
Socket socketconn = mysocket.Accept();
mydic.Add(socketconn.RemoteEndPoint.ToString(), socketconn);
Invoke(ipda, socketconn.RemoteEndPoint.ToString(), 1);
ParameterizedThreadStart pts = new ParameterizedThreadStart(mesgthread);
Thread threadmes = new Thread(pts);
threadmes.IsBackground = true;
threadmes.Start(socketconn);
mythread.Add(socketconn.RemoteEndPoint.ToString(), threadmes);
}
}
public void mesgthread(object socketpra)
{
updata upd = new updata(updataui);
int ststics = 0;
Socket socketrec = socketpra as Socket;
while (true)
{
byte[] argmesg = new byte[1024 * 1024];
int length = -1;
try
{
length = socketrec.Receive(argmesg);
String getstr = Encoding.Default.GetString(argmesg, 0, length);
Invoke(upd, getstr , 0);
}
catch (Exception ex)
{
if (ststics == 0)
{
mydic.Remove(socketrec.RemoteEndPoint.ToString());
mythread.Remove(socketrec.RemoteEndPoint.ToString());
Invoke(upd, socketrec.RemoteEndPoint.ToString(), 2);
Invoke(upd, socketrec.RemoteEndPoint.ToString() + ex.ToString(), 0);
}
ststics = 1;
}
Thread.Sleep(100);
}

}
public void updataui(String arg, int i)
{
if (i == 0)
{
textBox2.Text += arg;
}
else if (i == 1)
{

comboBox1.Items.Add(arg);
comboBox1.SelectedIndex = comboBox1.Items.IndexOf(arg);
}
else if (i == 2)
{
comboBox1.Items.Remove(arg);


if (comboBox1.Items.Count < 1)
{
comboBox1.Items.Add("等待连接");
comboBox1.SelectedIndex = comboBox1.Items.IndexOf("等待连接");
}
else
{
String keys = comboBox1.Items[comboBox1.Items.Count - 1].ToString();
comboBox1.SelectedIndex = comboBox1.Items.IndexOf(keys);
}
// comboBox1.Items.Remove (arg);
// comboBox1.SelectedIndex=1;
}

}

}
}

效果就是这样,间谍已经成功进入敌方内部,就等窃取机密了,通过下面代码发回机密内容即可。

复制
send(sock, buf, strlen(buf)+1, 0);

下章将如何读取微信内存数据。

感觉很棒!可以赞赏支持我哟~

2 打赏

评论 (1)

登录后评论
学习了
QQ咨询 邮件咨询 狗哥推荐