这篇文章名字有点绕,不大好理解,简单来说就是C++派出了一名间谍,C#将这名间谍送进了敌人内部,并给了间谍一个合法使用敌人资源的身份。至于为什么C#不派自己的人去,那是因为C#的间谍送入敌方就不干活,哈哈哈。用程序的术语来说就是没有程序入口,无法主动执行任务!
首先使用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);
下章将如何读取微信内存数据。
评论 (1)