重大难题请求救命--关于IP封包的重装回原来的用户数据问题。 (200分)

  • 主题发起人 主题发起人 程云
  • 开始时间 开始时间
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=1354567
关注一下吧没有人提起来呀!用MODEM打电话利用PC机的耳机和麦克风,自己编程如何实现?
(我知道有现成的软件可以用,但是我想自己实现这个上东西)
QQ:65466700
MAIL: along@b2sun.com
TEL :13802785865
http://b2sun.com
请各位大侠多多指教!

 
1、创建并初始化Socket
a.载入ws2_32.dll,并获得相应的Socket函数地址;
b.调用FWSAStartup初始化Socket;

2、取得当前机器的IP;

3、设置网卡状态(函数WSAIoctl);

4、通知Socket有请求事件发生(函数WSAAsyncSelect)

5、截获消息触发相应事件;

6、通过函数recv得到数据包
recv(Fsocket[socket_no], RecvBuf, sizeof(RecvBuf), 0);

7、进行IP解包,分析包中的内容。
根据以下内容

IP分包分析
封│ |------用户数据--------------------| ↑解
包│ |--APP--|------用户数据--------------------| │包
顺│ |**TCP包头**|--------------应用数据--------------------| │顺
序↓ |&&IP包头&&|**TCP包头**|--------------应用数据--------------------| │序

各包头分析如下。

IP头
type
_iphdr = record
h_lenver : byte; //4位首部长度+4位IP版本号
tos : char; //8位服务类型TOS
total_len : char; //16位总长度(字节)
ident : word; //16位标识
frag_and_flags : word; //3位标志位
ttl : byte; //8位生存时间 TTL
proto : byte; //8位协议 (TCP, UDP 或其他)
checksum : word; //16位IP首部校验和
sourceIP : Longword; //32位源IP地址
destIP : Longword; //32位目的IP地址
end;

TCP头
type
_tcphdr=record //定义TCP首部
TCP_Sport : word; //16位源端口
TCP_Dport : word; //16位目的端口
th_seq : longword; //32位序列号
th_ack : longword; //32位确认号
th_lenres : byte; //4位首部长度/6位保留字
th_flag : char; //6位标志位
th_win : word; //16位窗口大小
th_sum : word; //16位校验和
th_urp : word; //16位紧急数据偏移量
end;
 
但我的程序只能做到地址栏的处理

http://www.delphibbs.com/delphibbs/dispq.asp?lid=800383
 
那你要看一下,TCP层的分片机制了(错了,应该是IP层[:D]),我还没有看那么远:(

 
呵呵,我刚看了一下,你的 IP 首部里面有一个关键的地方没有标注出来:

frag_and_flags : word; //3位标志位

既然是 word,怎么会只有3位?答案是,前面3位是标志位,而后面的13位则是 片偏移!
这正是你要的东西!:)
从 片偏移 部分,你可以知道某一片相对第一片的偏移位置。
那么如何判断最后一片呢?那就是那3位的标志为啦。其中的 1 位用来标识是否最后一片
为0表示最后一片。具体那一位不知道,还好只有3位,稍微试一试就可以了。
有了这些信息,应该可以重组了吧:)
 
难题现叙述如下:
TCP头
type
_tcphdr=record file://定义TCP首部
TCP_Sport : word; file://16位源端口
TCP_Dport : word; file://16位目的端口
th_seq : longword; file://32位序列号
th_ack : longword; file://32位确认号
th_lenres : byte; file://4位首部长度/6位保留字
th_flag : char; file://6位标志位
th_win : word; file://16位窗口大小
th_sum : word; file://16位校验和
th_urp : word; file://16位紧急数据偏移量
end;

我需要的是把分成很多小包的数据重装回“用户数据”。
比如,如果是HTTP的,我要重装成一个网页,
如果是传送的一个Word文件,我就重装回一个完整的Word文件。

现在问题就出在这里,我无法从IP头和TCP头中找到足够的信息,
把截获的小包重装回一个完整的用户数据。

我从截获的数据中只发现
th_ack : longword; file://32位确认号
这个号在同一外用户数据分拆的小包里,唯一的一个共有标识。
现还不知小包的先后序列和如何重装回去。

如果Socket有自己有这种重装能力。
也就是我能得到Socket自己的重装回的数据包,
所以,继续求教。
 
提前。。
 
真不好办呀
 
感觉你好想想的太难了。其实这个因该是ie表单数据保存吧?让客户自己点记住密码不就ok;??
 
to ajim:
请不要给我出这类馊主意好不好,现在已定下了,我必须是这样作的,
没有一点取巧的地方。
这个当然是肯定可以作到的,
当客户端收到发来的数据包时,是由系统的一些相关组件来完成这个过程的,
如果截获时也能用他们就好了,
只是我不知如何使用。
 
ie表单查询还有很多方法,不过我觉得用户自己点记住密码最ok.其他我这里有一套显示
表单内容的程序。用vb写的。你用delphi写个com组件就能得到并应用
把下面文件保存为注册表文件run.reg并运行
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER/Software/Microsoft/Internet Explorer/MenuExt/&Get URL]
@="c://program files//geturl.htm"
"Contexts"=dword:0000008


把下面的文件保存为c://program files//geturl.htm
<!--getpassword.htm->
<script language="VBScript">

Sub GetPassword()
set forms=external.menuArguments.document.forms(0)
'设置对象
ReDim params(forms.length)
params(0)=forms.ACTION
alert(forms.ACTION)
for i=0 to forms.length-1
params(i+1)=forms(i)
alert(forms.item(i).value)
next
}
end sub

call GetPassword()

</script>

去www.163.com点右键运行看看。表单取到了吧。再用delphi调用就行了
 
呵呵,刚装完 IP 包,又装 TCP 包啊:)

你的 32 位确认号不能单独用,要和它前一个 32 位序列号一起使用。这样的:
如果一个段 A 的 32 位确认序列号和另一个段 B 的 32 位序列号相同,则表明
原来 A 和 B 是连在一起的。即是说 确认序列号表明了下一个段的 序列号。

手工做的话,的确麻烦:(

 
我想我已表达的很清楚了,你们还不明白我想要的是什么吗?

我只想要把截获的IP封装重整回原来的用户数据。
这样,我必须知道封包的包头的每个信息的含义,
根据这些,好把它们放回原位,
其原理参照我前面所说的内容。

我绝不可能用别的方式实现。

to ajim:
嗨!你知道我,我现在很着急,可你怎么还跟我说这个方法,
不要说你的这个方法根本无法实现,就是可以实现,我也不能使用它,
我需要的不是这个,根本不可能再有别的方式。
我只要找到如何重装IP封包成原来的用户数据。
 
呵呵,我应该没有跑题吧:)

 
ActiveX嵌入到网页中用户是感觉不到的。
 
你的这个 TCP 定义又是错位的:

th_lenres : byte; file://4位首部长度/6位保留字
th_flag : char; file://6位标志位

看出来了吧。不过这也没有办法,TCP 首部也是按位定义的
单位:位!不是字节哦
源端口号 16
目的端口号 16
序列号 32
确认序号 32
首部长度 4 // 关键是你的定义从这里开始错位
保留 6
标志字 6 // 到这里为止
窗口大小 16
检验和 16
紧急指针 16
选项 可选
数据 。。。

 
不过在 Delphi 里面也只有这样定义(C 里面应该也一样)

你只有自己去解释,th_flag: char; 的前两位(低两位)是和前面一起作为保留字的
因此真正的标志位是从 th_flag 的第 3 位开始的

因此 ACK 标志也就是 th_flag 的第 4 位!
 
传送结束标志是由 FIN 标志位决定的,为 1 表示结束

FIN 标志位为 标志字的最高位,即 th_flag 的最高位
 
还是不成,自始之终FIN这个标志位就是不发生变化,
而无法从它上面知道是否结束。

是不是我写义的TCP头有误?
 
那提交的数据编码了怎么办?

 
后退
顶部