使用已存在的SOCKET连接发送封包 (有附加分)

Game4s 2008-11-19 02:02:23
已知某程序A 建立了远程SOCKET连接

程序B如何使用该SOCKET连接发送数据?
(也就是‘冒充’程序A发送数据)

简单说明流程和相关函数/API即可。

如有示例代码且正确者另加分。
...全文
594 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jmxb123 2008-11-23
  • 打赏
  • 举报
回复
会话截持嘛
以前见过个telnet的会话截持程序 如A telnet到C上 B就可以在不知道C机器密码的情况下,用这个东西就可以代替了A telnet到C上 可能有限制条件 忘了

04或者05年某期的X档案上有一篇精典的文章 用过这个工具 可惜忘记文档名称了
作者是 无敌和冷枫

全凭记忆了 可能有误
willflyz 2008-11-22
  • 打赏
  • 举报
回复
学习一下.
etomahawk 2008-11-22
  • 打赏
  • 举报
回复
注入到进程之后,随便拦截那个SOCKET API(有socket句柄),然后获取它的SOCKET句柄,就可以调用send/sendto发送了。

WPE可以实现到这个,你去研究研究。
jb123456 2008-11-22
  • 打赏
  • 举报
回复
把获得的连接 thread 发送给b程序,b就可以用这个参数 send
outer2000 2008-11-21
  • 打赏
  • 举报
回复
别看这是封包这一问题,但是涉及的技术范围很广范,实现的方式也很多(比如说APIHOOK,VXD,Winsock2都可以实现),在这里我们不可能每种技术和方法都涉及,所以我在这里以Winsock2技术作详细讲解,就算作抛砖引玉。
由于大多数读者对封包类编程不是很了解,我在这里就简单介绍一下相关知识:
APIHooK:
由于Windows的把内核提供的功能都封装到API里面,所以大家要实现功能就必须通过API,换句话说就是我们要想捕获数据封包,就必须先要得知道并且捕获这个API,从API里面得到封包信息。
VXD:
直接通过控制VXD驱动程序来实现封包信息的捕获,不过VXD只能用于win9X。
winsock2:
winsock是Windows网络编程接口,winsock工作在应用层,它提供与底层传输协议无关的高层数据传输编程接口,winsock2是winsock2.0提供的服务提供者接口,但只能在win2000下用。
好了,我们开始进入winsock2封包式编程吧。
在封包编程里面我准备分两个步骤对大家进行讲解:1、封包的捕获,2、封包的发送。
首先我们要实现的是封包的捕获:
Delphi的封装的winsock是1.0版的,很自然winsock2就用不成。如果要使用winsock2我们要对winsock2在Delphi里面做一个接口,才可以使用winsock2。
1、如何做winsock2的接口?
1)我们要先定义winsock2.0所用得到的类型,在这里我们以WSA_DATA类型做示范,大家可以举一仿三的来实现winsock2其他类型的封装。
我 们要知道WSA_DATA类型会被用于WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer;,大家会发现WSData是引用参数,在传入参数时传的是变量的地址,所以我们对WSA_DATA做以下封装:
const
WSADESCRIPTION_LEN = 256;
WSASYS_STATUS_LEN = 128;
type
PWSA_DATA = ^TWSA_DATA;
WSA_DATA = record
wVersion: Word;
wHighVersion: Word;
szDescription: array[0..WSADESCRIPTION_LEN] of Char;
szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
iMaxSockets: Word;
iMaxUdpDg: Word;
lpVendorInfo: PChar;
end;
TWSA_DATA = WSA_DATA;
2)我们要从WS2_32.DLL引入winsock2的函数,在此我们也是以WSAStartup为例做函数引入:
function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall;

implementation

const WinSocket2 = 'WS2_32.DLL';
function WSAStartup; external winsocket name 'WSAStartup';

通过以上方法,我们便可以对winsock2做接口,下面我们就可以用winsock2做封包捕获了,不过首先要有一块网卡。因为涉及到正在运作的网络游戏安全问题,所以我们在这里以IP数据包为例做封包捕获,如果下面的某些数据类型您不是很清楚,请您查阅MSDN:
1)我们要起动WSA,这时个要用到的WSAStartup函数,用法如下:
INTEGER WSAStartup(
wVersionRequired: word,
WSData: TWSA_DATA
);
2)使用socket函数得到socket句柄,m_hSocket:=Socket(AF_INET, SOCK_RAW, IPPROTO_IP); 用法如下:
INTEGER socket(af: Integer,
Struct: Integer,
protocol: Integer
);

m_hSocket:=Socket(AF_INET, SOCK_RAW, IPPROTO_IP);在程序里m_hSocket为socket句柄,AF_INET,SOCK_RAW,IPPROTO_IP均为常量。

3)定义SOCK_ADDR类型,跟据我们的网卡IP给Sock_ADDR类型附值,然后我们使用bind函数来绑定我们的网卡,Bind函数用法如下:

Type
IN_ADDR = record
S_addr : PChar;
End;

Type
TSOCK_ADDR = record
sin_family: Word;
sin_port: Word;
sin_addr : IN_ADDR
sin_zero: array[0..7] of Char;
End;

var
LocalAddr:TSOCK_ADDR;

LocalAddr.sin_family: = AF_INET;
LocalAddr.sin_port: = 0;
LocalAddr.sin_addr.S_addr: = inet_addr('192.168.1.1'); //这里你自己的网卡的IP地址,而inet_addr这个函数是winsock2的函数。

bind(m_hSocket, LocalAddr, sizeof(LocalAddr));

4)用WSAIoctl来注册WSA的输入输出组件,其用法如下:

INTEGER WSAIoctl(s:INTEGER,
dwIoControlCode : INTEGER,
lpvInBuffer :INTEGER,
cbInBuffer : INTEGER,
lpvOutBuffer : INTEGER,
cbOutBuffer: INTEGER,
lpcbBytesReturned : INTEGER,
lpOverlapped : INTEGER,
lpCompletionRoutine : INTEGER
);
5)下面做死循环,在死循环块里,来实现数据的接收。但是徇环中间要用Sleep()做延时,不然程序会出错。
6)在循环块里,用recv函数来接收数据,recv函数用法如下:
INTEGER recv (s : INTEGER,
buffer:Array[0..4095] of byte,
length : INTEGER,
flags : INTEGER,
);
7)在buffer里就是我们接收回来的数据了,如果我们想要知道数据是什么地方发来的,那么,我们要定义一定IP包结构,用CopyMemory()把IP信息从buffer里面读出来就可以了,不过读出来的是十六进制的数据需要转换一下。

看了封包捕获的全过程序,对你是不是有点起发,然而在这里要告诉大家的是封包的获得是很容易的,但是许多游戏的封包都是加密的,如果你想搞清楚所得到的是什么内容还需要自己进行封包解密。
=============================================
在本章中,我们主要来研究一下封包的制作和发送,同样,我们所采用的方法是Delphi+winsock2来制作。在以前说过在Delphi中只封装了winsock1,winsock2需要自已封装一下,我在此就不多介绍如何封装了。
下面就一步步实现我们的封包封装与发送吧:
首 先,我们应该知道,封包是分两段的,一段是IP,一段是协议(TCP,UDP,其他协议),IP就像邮政编码一样,标识着你的这个封包是从哪里到哪里,而 协议里记录着目标所要用到的包的格式及校验等,在网络游戏中的协议一般都是自已定义的,要破解网络游戏最重要的是学会破解网络游戏的协议网络游戏协议破 解,为了不影响现运行的网络游戏的安全,我在此会以UDP协议为例,介绍一下网络协议的封包与发送的全过程。
接下来,我们就可以开始看看整个封包全过程了:
1)我们要起动sock2,这时个要用到的WSAStartup函数,用法如下:
INTEGER WSAStartup(
wVersionRequired: word,
WSData: TWSA_DATA
);
在程序中wVersionRequired我们传入的值为$0002,WSData为TWSA_DATA的结构。
2)使用socket函数创建并得到socket句柄; 用法如下:
INTEGER socket(af: Integer,
Struct: Integer,
protocol: Integer
);
注意的是在我们的程序封包中饱含了IP包头,所以我们的Struct参数这里要传入的参数值为2,表示包含了包头。该函数返回值为刚刚创建的winsocket的句柄。
3)使用setsockopt函数设置sock的选项; 用法如下:
INTEGER setsockopt(s: Integer,
level: Integer,
optname: Integer,
optval: PChar,
optlen: Integer
);
网虫 (2008-10-29 15:45:59)
在S处传入的是Socket句柄,在本程序里level输入的值为0表示IP(如果是6表示TCP,17表示UDP等~),OptName里写入2,而optval的初始值填入1,optlen为optval的大小。
4)接下来我们要分几个步骤来实现构建封包:
1、把IP转换成sock地址,用inet_addr来转换。
Longint inet_addr(
cp: PChar
);
2、定义包的总大小、IP的版本信息为IP结构:
总包大小=IP头的大小+UDP头的大小+UDP消息的大小,
IP的版本,在此程序里定义为4,
3、填写IP包头的结构:
ip.ipverlen := IP的版本 shl 4;
ip.iptos := 0; // IP服务类型
ip.iptotallength := ; // 总包大小
ip.ipid := 0; // 唯一标识,一般设置为0
ip.ipoffset := 0; // 偏移字段
ip.ipttl := 128; // 超时时间
ip.ipprotocol := $11; // 定义协议
ip.ipchecksum := 0 ; // 检验总数
ip.ipsrcaddr := ; // 源地址
ip.ipdestaddr := ; // 目标地址
4、填写UDP包头的结构:
udp.srcportno := ; //源端口号
udp.dstportno := ; //目标端口号
udp.udplength := ; //UDP包的大小
udp.udpchecksum := ; //检验总数
5、把IP包头,UDP包头及消息,放入缓存。
6、定义远程信息:
remote.family := 2;
remote.port :=; //远程端口
remote.addr.addr :=; //远程地址

5)我们用SendTo发送封包,用法如下:
INTEGER sendto(s: Integer,
var Buf: Integer,
var len: Integer,
var flags: Integer,
var addrto: TSock_Addr;
tolen: Integer
);
在S处传入的是Socket句柄,Buf是刚刚建好的封包,len传入封包的总长度刚刚计算过了,flag是传入标记在这里我们设为0,addto发送到的目标地址,在这里我们就传入remote就可以了,tolen写入的是remote的大小。

6)到了最后别忘记了用CloseSocket(sh)关了socket和用WSACleanup关了winsock。

最后要说的是这种发送方式,只能发送完全被破解的网络协议,如果要在别人的程序中间发送数据就只有用APIHOOK或在winsock2做中间层了
xstarsoft 2008-11-21
  • 打赏
  • 举报
回复
帮顶一下,关注~
Game4s 2008-11-20
  • 打赏
  • 举报
回复
1,同一台机器,可以用线程注入方式,在程序A中运行你自己的THREAD;
CreateRemoteThread..
但是如何使用SOCKET呢?


2,拦截归拦截,但是要发送啊...
不光是拦截到了包修改后发送,而是要想发送的时候就发送。。。
outer2000 2008-11-20
  • 打赏
  • 举报
回复
1,同一台机器,可以用线程注入方式,在程序A中运行你自己的THREAD;
2,可以把SOCKET的DLL换成你自己的,拦截到A发的包,就可以处理了;
Bear_hx 2008-11-20
  • 打赏
  • 举报
回复
学习
Game4s 2008-11-20
  • 打赏
  • 举报
回复
更进一步说明情况:
A 是本机运行的一个程序,该程序建立了SOCKET连接。
B 是我自己写的程序,想要使用A建立的SOCKET连接来冒充A程序发送封包。
fangsp 2008-11-19
  • 打赏
  • 举报
回复
网络环境是怎么样的
是通过普通的公网
还是专网
Game4s 2008-11-19
  • 打赏
  • 举报
回复
附加:
无法修改程序A的代码...必须是程序B自己想办法。


某些网络封包截取软件就可以实现相同的功能,比如PAssistant。可以在监视现有SOCKET发送接收情况的同时使用该SOCKET发送自定义封包...

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧