转自:http://blog.csdn.net/qq276592716/article/details/6760283
WSADuplicateSocket这个函数网上有少部分人问它的用法,其实它就是
int WSADuplicateSocket(__in   SOCKET s,__in   DWORD dwProcessId,__out  LPWSAPROTOCOL_INFO lpProtocolInfo
);

很明显就是把s,processId里面的部分值copy到ProtocolInfo里面,如果是指针就copy地址~

下面转载一篇关于这个函数的好文`

有过脱机外挂编写经历的童鞋们大概都会遇到一个很纠结的问题,现在大多数游戏都要求客户端每几秒给服务器发送一个数据包以确定是否掉线,这样一来在调试程序的时候,无论是对客户端的逆向调试,还是对自己外挂的调试,一旦下了断点程序暂停后,如果不能在短短的几秒中恢复程序运行,那么游戏就会掉线。

在彩虹岛中,心跳包的发送间隔是10秒,我发誓这个问题困扰了我两年。。

比较容易想到的是,看有没有办法能直接截取数据链路层的raw packets,再看看有没有API,或者直接操作网卡驱动来模拟封包。然而这对计算机网络知识要求很高,并且貌似Windows下raw packets的操作很少很少,并且有各种各样的安全限制(防止有人乱发包)。这个设想至今没有能够实现。

今天上课时突然想到一个点子。socket在Windows中是个文件句柄(不严格的),那么是否子进程能够继承这个句柄而做到由子进程来按时发送心跳包。这样就不会造成调试时“心跳暂停”了。

Google以后发现,socket是可以通过DuplicateHandle复制后继承的。但是MSDN给出了一种更好的多进程共享socket的方法,那就是使用WSADuplicateSocket。

查阅MSDN:http://msdn.microsoft.com/en-us/library/ms741565(VS.85).aspx

利用WSADuplicateSocket,socket更是一种共享,而不简单是继承了,亦即任何的进程之间均可共享socket。使用的方法也很简单,源进程对要共享的socket调用WSADuplicateSocket,将返回的WSAPROTOCOL_INFO结构体传递给目标进程,然后目标进程用这个结构体调用WSASocket创建一个新的socket描述符,这个socket即指向原来的socket。

需要注意的是,每次生成的WSAPROTOCOL_INFO结构只能用于创建一次共享socket。另外就是不要Windows并没有对共享socket有IO访问控制的机制,这意味这如果在新的socket上调用recv,那么原程序就没法再recv了;如果两个程序同时调用了send而没有执行同步机制,那么send的数据也将会是乱掉的。事实上,无论在linux还是Windows上,socket的共享目的主要在于父进程accept连接,然后子进程负责通讯。

我在LibCHD中写了个测试,在Socket类的connect和disconnect中分别加入以下代码:

//Connect
#ifdef USE_HELPER_PING
    PROCESS_INFORMATION ProcessInformation;
    char cmdLine[128];
    sprintf(cmdLine, "pinghelper.exe %d %d", GetCurrentProcessId(), (int)&ProtocolInfo);
    STARTUPINFO si = {sizeof(STARTUPINFO)};
    CreateProcess(NULL, cmdLine, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &si, &ProcessInformation);
    hPingProcess = ProcessInformation.hProcess;
    WSADuplicateSocket(m_fd, ProcessInformation.dwProcessId, &ProtocolInfo);
    ResumeThread(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hThread);
#endif
//Disconnect
#ifdef USE_HELPER_PING
    TerminateProcess(hPingProcess, -1);
    CloseHandle(hPingProcess);
#endif

然后新建一个工程,命名为pinghelper,代码如下:

#include <WinSock2.h>
#include <Windows.h>
#include <ShellAPI.h>
INT WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
    DWORD PID;
    WSAPROTOCOL_INFO *lpRemoteProtocolInfo;
    WSAPROTOCOL_INFO LocalProtocolInfo;
    WSADATA wsaData;
    int argc;
    WCHAR **argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    PID = _wtoi(argv[1]);
    lpRemoteProtocolInfo = (WSAPROTOCOL_INFO *)_wtoi(argv[2]);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    ReadProcessMemory(hProcess, lpRemoteProtocolInfo, &LocalProtocolInfo, sizeof(WSAPROTOCOL_INFO), NULL);
    WSAStartup(0x202, &wsaData);
    SOCKET fd = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, &LocalProtocolInfo, 0, 0);
    while (WaitForSingleObject(hProcess, 10000) == WAIT_TIMEOUT)
    {
        char Data[12] = {12, 0, 3 ,0, 0, 0, 0, 0, 0, 0, 0, 0};
        send(fd, Data, 12, 0);
    }
    closesocket(fd);
    WSACleanup();
    CloseHandle(hProcess);
    return 0;
}

这样就实现了即便暂停程序的运行,依然能够保持与服务器的连接。

在客户端程序里也可以通过Dll注入来做到逆向时不掉线,甚至能做到将正在运行的游戏“替换”成脱机外挂,然后将游戏关掉而不掉线。

从Google的结果来看,目前外挂开发中鲜有共享socket的技术文档,仅仅在某几个Pascal写的脱机外挂的源代码中出现过。希望这篇文章能给大家一些帮助

关于WSADuplicateSocket的理解相关推荐

  1. 关于WSADuplicateSocket的理解~(整理)

    WSADuplicateSocket这个函数网上有少部分人问它的用法,其实它就是 Copy int WSADuplicateSocket( __in SOCKET s, __in DWORD dwPr ...

  2. 通用解题法——回溯算法(理解+练习)

    积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...

  3. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  4. Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)

    1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...

  5. java局部变量全局变量,实例变量的理解

    java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...

  6. 智能文档理解:通用文档预训练模型

    预训练模型到底是什么,它是如何被应用在产品里,未来又有哪些机会和挑战? 预训练模型把迁移学习很好地用起来了,让我们感到眼前一亮.这和小孩子读书一样,一开始语文.数学.化学都学,读书.网上游戏等,在脑子 ...

  7. 熵,交叉熵,散度理解较为清晰

    20210511 https://blog.csdn.net/qq_35455503/article/details/105714287 交叉熵和散度 自己给自己编码肯定是最小的 其他的编码都会比这个 ...

  8. mapreduce理解_大数据

    map:对不同的数据进行同种操作 reduce:按keys 把数据规约到一起 看这篇文章请出去跑两圈,然后泡一壶茶,边喝茶,边看,看完你就对hadoop 与MapReduce的整体有所了解了. [前言 ...

  9. 文件句柄和文件描述符的区别和理解指针

    句柄是Windows用来标识被应用程序所建立或使用的对象的唯一整数,Windows使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等.Windows句柄有点象C语言中的文件句柄. ...

最新文章

  1. 基于Base64的图片转字符串-java和C#互通问题
  2. Flex Java Servlet 实现简单图片编辑
  3. Shiro Spring 集成xml配置
  4. PyTorch1.4安装(Anaconda3 + Python3.6 + cpu版本)
  5. java系统找不到文件_java编译系统找不到指定文件
  6. 倍福BECKHOFF PLC:自动化编程笔记
  7. 【后缀数组+???】BZOJ3654 图样图森破
  8. Mac系统下Typora配置阿里云图床+上传工具PicGo安装
  9. java生成树形Excel_java poi导出树形结构到excel文件
  10. SOFA BOLT源码解析之设计要点-网络IO
  11. Teams app 开发最佳实践
  12. QLV格式怎么在线转换成MP4转换器
  13. STM32第二课(cubemx,clk,gpio,)
  14. 基金A类和C类的科普贴
  15. Kotlin: Java 6 废土中的一线希望
  16. 剑指 Offer 51-60
  17. Python+Pycharm的安装
  18. ​内嵌物理知识神经网络(PINN)是个坑吗?
  19. itunes cannot read the contents of the iphone
  20. android-pedometer

热门文章

  1. VR项目添加键盘鼠标控制
  2. 率土之滨鸿蒙团,关于率土之滨几个顶级大盟的实力分析
  3. 气动旋转接头如何使用
  4. 硅谷钢铁侠被送上法庭,特斯拉换帅在即?
  5. 淘客基地:关于【淘客CMS优惠券商城】域名被限制通知
  6. Unity相机漫游脚本FreeCamera.CS
  7. linux安装驱动bz2,Linux系统中安装Razer驱动
  8. 华硕主板Z390识别不到M2固态硬盘
  9. iOS图片打马赛克的实现方式--------终极解决方案
  10. vue 使用cesium