• x64dbg 实现插件Socket反向通信


    编写一个带有socket通信功能的插件,x64dbg运行后,用户点击链接按钮可直接连接到外部的python中,python作为服务端,当x64dbg内部出现某个事件后,自动将消息推送到外部python脚本上,实现反向传参的目的。

    首先编写插件端代码,代码中直接初始化套接字,用户服务端启动后点击connect按钮链接到服务端,链接成功后,一但调试器加载了程序则自动触发CBINITDEBUG(CBTYPE cbType, PLUG_CB_INITDEBUG* info)回调函数,并通过socket将参数送出到外部。

    #include "pluginmain.h"
    #include <Windows.h>
    #include <process.h>
    
    #pragma comment(lib,"ws2_32.lib")
    #define IP "127.0.0.1"
    #define PORT 9999
    
    int pluginHandle;
    HWND hwndDlg;
    int hMenu;
    int hMenuDisasm;
    int hMenuDump;
    int hMenuStack;
    
    WSADATA WSAData;
    SOCKET sock;
    struct sockaddr_in ClientAddr;
    
    // 在这里初始化插件数据。
    bool pluginInit(PLUG_INITSTRUCT* initStruct)
    {
    	// 返回false以取消加载插件。
    	return true;
    }
    
    // 在此处取消初始化插件数据。
    void pluginStop()
    {
    }
    
    // 在这里做GUI/菜单相关的事情。
    void pluginSetup()
    {
    }
    
    // 导出函数
    extern "C" __declspec(dllexport) void plugsetup(PLUG_SETUPSTRUCT* setupStruct);
    extern "C" __declspec(dllexport) bool pluginit(PLUG_INITSTRUCT* initStruct);
    
    // 导出自定义的两个功能
    extern "C" __declspec(dllexport) void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info);
    extern "C" __declspec(dllexport) void CBINITDEBUG(CBTYPE cbType, PLUG_CB_INITDEBUG* info);
    
    // 菜单回调函数(初始化时自动发送套接字)附加进程触发
    void CBINITDEBUG(CBTYPE cbType, PLUG_CB_INITDEBUG* info)
    {
    	send(sock, (char *)&info, 1024, 0);
    	_plugin_logprintf("size = %d \n", sizeof(PLUG_CB_INITDEBUG));
    	_plugin_logprintf("func = %s \n", info->szFileName);
    }
    
    // --------------------------------------------------------------------
    // 基础功能
    // --------------------------------------------------------------------
    
    // 命令触发: 开启Socket的命令
    bool ConnectSocket(int argc, char **argv)
    {
    	_plugin_logprintf("start socket \n");
    
    	if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
    	{
    		ClientAddr.sin_family = AF_INET;
    		ClientAddr.sin_port = htons(PORT);
    		ClientAddr.sin_addr.s_addr = inet_addr(IP);
    	}
    
    	sock = socket(AF_INET, SOCK_STREAM, 0);
    	int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
    	return Ret;
    }
    
    // 命令触发: 关闭Socket的命令
    bool CloseSocket(int argc, char **argv)
    {
    	_plugin_logprintf("stop socket \n");
    
    	send(sock, "SocketClose", 11, 0);
    	closesocket(sock);
    	WSACleanup();
    	return true;
    }
    
    // 菜单被点击触发此回调
    void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info)
    {
    	switch (info->hEntry)
    	{
    	case 1:
    		ConnectSocket(0, 0);
    		break;
    	case 2:
    		CloseSocket(0, 0);
    		break;
    	}
    }
    
    PLUG_EXPORT bool pluginit(PLUG_INITSTRUCT* initStruct)
    {
    	initStruct->pluginVersion = PLUGIN_VERSION;
    	initStruct->sdkVersion = PLUG_SDKVERSION;
    	strncpy_s(initStruct->pluginName, PLUGIN_NAME, _TRUNCATE);
    	pluginHandle = initStruct->pluginHandle;
    
    	// 插件初始化
    	const char *name = "LyScriptCallBack";
    	memset(initStruct->pluginName, 0, 128);
    	memcpy(initStruct->pluginName, name, strlen(name));
    
    	return pluginInit(initStruct);
    }
    
    PLUG_EXPORT bool plugstop()
    {
    	pluginStop();
    	return true;
    }
    
    PLUG_EXPORT void plugsetup(PLUG_SETUPSTRUCT* setupStruct)
    {
    	hwndDlg = setupStruct->hwndDlg;
    	hMenu = setupStruct->hMenu;
    	hMenuDisasm = setupStruct->hMenuDisasm;
    	hMenuDump = setupStruct->hMenuDump;
    	hMenuStack = setupStruct->hMenuStack;
    
    	// 增加连接选项
    	char sub_connect[] = "Connect";
    	_plugin_menuaddentry(setupStruct->hMenu, 1, sub_connect);
    
    	// 添加关闭连接选项
    	char sub_close[] = "CloseConnect";
    	_plugin_menuaddentry(setupStruct->hMenu, 2, sub_close);
    
    	// 注册ConnectSocket开启Socket命令
    	_plugin_registercommand(pluginHandle, "ConnectSocket", ConnectSocket, true);
    
    	// 注册CloseSocket关闭Socket命令
    	_plugin_registercommand(pluginHandle, "CloseSocket", CloseSocket, true);
    
    	pluginSetup();
    }
    

    客户端则负责接收参数,收到后直接使用MyStruct(Structure)类,格式化为特定结构体,并输出内部成员参数。

    import socket
    import struct
    from ctypes import *
    
    ip_addr=("localhost",9999)
    
    server = socket.socket()
    server.bind(ip_addr)
    server.listen(5)
    
    class MyStruct(Structure):
        _pack_ = 1
        _fields_ = [
            ("szFileName", c_char * 256)
        ]
    
        def unpack(self,buffer):
            (self.szFileName) = struct.unpack("< 256s",buffer)
    
    while True:
        conn,addr=server.accept()
        print(addr)
    
        while True:
            try:
                recv_data = str(conn.recv(8192), encoding="utf-8")
    
                if len(recv_data) == 11 and recv_data == "SocketClose":
                    conn.close()
                    print("close")
                else:
                    recv_struct = MyStruct()
                    recv_struct.unpack(recv)
                    print(recv_struct.szFileName)
    
            except Exception:
                break
                server.close()
    

    首先运行python脚本让其侦听特定端口,然后再x64dbg中点击connect链接按钮,链接成功后即可看到输出信息。

  • 相关阅读:
    PIE-Basic 频率域滤波
    使用CefSharp前端后台交换
    CefSharp F12打开DevTools查看console js和c#方法互相调用
    js和C#互相调用
    C# 矢量图EMF 总结
    key
    关于IdentityServer4不使用MVC页面进行登录(跨域发送验证请求)的一些问题(前后端分离的验证)
    C#版的省份编码字典
    EFCore显示加载模式下,自动包含导航属性(只包含第一层的导航属性)的方法
    EFCore批量实现全局查询筛选器
  • 原文地址:https://www.cnblogs.com/LyShark/p/16580044.html
Copyright © 2020-2023  润新知