300分求oicq的资料(300分)

  • 主题发起人 主题发起人 积步
  • 开始时间 开始时间

积步

Unregistered / Unconfirmed
GUEST, unregistred user!
300分求oicq的资料:
[red]通讯协议, 文档[/red]
工具,攻击程序源码
---------------------------
少了还可以再加
 
oicq的通讯协议每个版本都会改变的,并不像MSN、ICQ那样公开的,所以就算知道,到了新版本,也可能就失效了。
 
qu wen HuaTeng Ma
 
(转载)
注意:只适合OICQ 0820版本

我们的目标是去掉广告显示,并且在广告的位置上显示目标对象的IP地址和端口号。我们应该怎么下手呢,好的,慢慢跟我来!

经过对Oicq目录结构的分析,发现目录AD和广告有关。其一是广告的英文简写就是AD,其二是其中的图片文件就是我们在广告中看到的。 试着删除该目录之后,呵呵,广告消逝了。但是下次进入Oicq之后,程序会自动新建这个目录,并且重新下载广告文件。既然程序读取不到广告文件广告就会消失,那么就人 工让它读不到咯。用Soft-ice把断点设置在CreateFileA上,这个API调用一般是用来打开一个文件或者设备的。在Sice截到断点后,查看是即将打开的那些文件,从而判断是 否是我们要修改的地方。具体修改方法详见“打开广告文件的程序段”。

广告是去掉了,但是在广告区域上点击鼠标,浏览器仍然会打开广告链接,看来我们还需要对程序作更完善的修改。好了,既然点击广告会出现 浏览器,那一定是运行了一个程序。一般打开运行浏览器程序的有两种方法,一是调用COM接口,二是调用普通的运行程序的API函数。第一种方法技术难度较高,一般程序很 少采用。所以直接用Sice把断点设置在几个和运行程序有关的API函数上,比如ShellExecuteA,WinExec等等。好了,程序在ShellExecuteA处中断,也就是只要避过这个API函 数就行咯。呵呵,顺着程序往上找合适的修改位置,会发现USER32.PtInRect函数的调用,经过分析,发现它是用作判断鼠标点击是否在特定区域内的。搞定,只要使它判断总 是在区域外,就不会执行到ShellExecuteA那儿去了。发送消息窗口和回复窗口的广告点击的程序在不同的位置,也就说在两个地方,这两个地方都要修改,原理也都是一样。 具体修改方法详见“发送消息窗口点击广告的程序段”和“回复消息窗口点击广告的程序段”。(我们为了实现在点击鼠标后出现IP地址和端口号,在发送消息窗口添加了一 个有关显示的程序入口,我将在后面讲解)。

这下广告真的是去除了,既不能看到,也不能点进去了。呵呵,开始我们的下一步目标,显示IP地址和端口号!!!

过去要想知道Oicq上朋友的IP地址只有借助民间的一些小工具程序或者采用包监听程序,后者专业要求比较高,而且辨别率低,也不方便。一些 小程序的确很管用,但是毕竟没有把这个功能直接做到Oicq程序上方便和可靠,利用Oicq内部的很多数据和结构能获得很多我们平常不容易获得的信息。但是毕竟只有二进制 汇编代码,没有源程序,程序的分析难度和工作量可想而知。经过令人难以想象多次数的死机和重起,以及极其艰辛的设置断点跟踪调试分析工作……(以下省略5201314字) ,终于粗略的获得了我们感兴趣的数据结构指针以及它相关调用的位置。这段时间是我最郁闷的时候,想起那段毫无人性的工作,就像已经过上幸福生活的老同志回忆起49年 以前悲惨生活般的胆战心惊且心有余悸……(以下省略520字)。还好我挺过来了,终于在0042513D处找到了需要的指针地址。只要利用这个指针就能获得目标对象的IP地址 以及端口号。我们需要做的就是把这些信息显示在以前的广告位置。

又是一项艰巨的任务放在我的面前,还好我有坚定的信念、丰富的临床经验以及对成功喜悦的企盼,还有对聊天MM住址的渴望,我一定会珍惜, 不能像周星星一样期望再来一次……(再次省略若干,以免挨鸡蛋)。

言归正传,既然获得了关键的数据指针,那可以说我们已经成功了90%了,接下来的就是显示出来而已。但这也需要反复的试验和修改。让我们 好好来回味一下这一过程:

首先,要实现新的功能毫无疑问需要添加代码和数据,以及执行一定的API函数,所以需要找到适当的方法添加代码到原程序之中。完美的方法就 是作一个外壳添加程序,在原程序中添加所需要的段(数据段,程序段),以及添加Import表表项,以用于新的API函数的地址定位,还要修改PE文件头中的各项相关信息,这 就是病毒的做法。这无疑非常的复杂和繁琐,有兴趣的同学可以参见我以前的文章“关于95下可执行文件的加密研究”。其实我们的要添加的程序量并不大,充其量也就零零星 星的几百个字节,而且用到的API函数也不多。所以我们采取了手动修改添加的方法,但也需要必要的条件和方法。看我以下的分析和方法:

PE可执行文件的逻辑结构是段,比如代码段“.text”、数据段“.data”、资源段“.rscs”等等。这些段大小都是按文件对齐,也就是说段大小 至少会按10h对齐,一般是1000h(4096字节),这由文件头中指定(链接的时候确定)。但是代码也好数据也好,不可能做到长度刚好是对齐的。也就是说,段的大小是大于段 中代码或数据实际大小的。他们之间的差值就是该段冗余的空间,这个空间被称为“空隙”。有一些简单的PE文件减肥软件就是使用去掉“空隙”的方法来减肥的。这个“空隙”可 以被我们用来放置代码、数据以及堆栈。我常用的分析PE文件文件头的工具软件是Borland以前在C++系列软件中带的“Tdump.exe”。让我们看看实际分析的结果:

Object table:
# Name VirtSize RVA PhysSize Phys off Flags
-- -------- -------- -------- -------- -------- --------
01 .text 000D0637 00001000 000D1000 00001000 60000020 [CER]
02 .rdata 000320E8 000D2000 00033000 000D2000 40000040 [IR]
03 .data 00039848 00105000 00012000 00105000 C0000040 [IRW]
04 .rsrc 0003E4C0 0013F000 0003F000 00117000 40000040 [IR]

以上是用Tdump看到的Oicq.exe的段信息(它的Oject就是我们所说的段)。我们肯定是首选.text段进行观察(.text是代码段,Flag为CER,意思就是包 含代码、可执行、可读的意思(Contains code, Execute,Readable))。可以看到,.text段代码实际长度D0637h,物理长度D1000h,文件偏移位置为1000h处。OK,这个段有 D1000h-D0637h=C9Ch的“空隙”。这个长度完全可以满足我们的需要了,而且代码数据堆栈都可以放在这个区域内。众所周知,要作为数据段使用,段的属性(Flags)需要可写。 好了,只需要改写“.text”的属性即可,可写属性的值是80000000h,然后加上原来的60000020h后,就是C0000020h了,也就是变成了CERW属性(具体修改方法详见“代码段段属 性修改”)。看看我们更改后的用Tdump分析的结果。

Object table:
# Name VirtSize RVA PhysSize Phys off Flags
-- -------- -------- -------- -------- -------- --------
01 .text 000D0637 00001000 000D1000 00001000 C0000020 [CRW]
02 .rdata 000320E8 000D2000 00033000 000D2000 40000040 [IR]
03 .data 00039848 00105000 00012000 00105000 C0000040 [IRW]
04 .rsrc 0003E4C0 0013F000 0003F000 00117000 40000040 [IR]

好了,找到了放置代码数据和堆栈的地方,也就是其实偏移1000h+D0637h 的地方。为了对齐边界,我们采用D1640h这个值(文件偏移)。用Tdump 查看代码段基址(Code Base)和PE文件映象基址(Image Base),分别是1000h和400000h,可以算出我们的程序在装入后的实际地址,400000h+1000h+D0640h=4D1640h。也就是 说我们的代码在被系统装入后在内存4D1640h处,这在以后程序跳转处用到。

添加代码的工作已经做好,现在关键的问题就是编制具体的代码,以用于IP地址和端口号的保存和显示。

首先是对对象数据中IP地址和端口信息的保存,我们在获得该数据指针后(程序00425157处),更改程序使程序直接跳转到我们的保存程序中 (4D1640h)。该数据的指针首址放在EAX,由于该段程序有些寄存器的值都有用,堆栈也不能乱压。所以我们首先修改了栈指针,使所有的堆栈活动都在我们的“空隙”中进行 (堆栈顶端4D1900h)。然后保存几个寄存器的值(压栈)。IP地址和端口号分别在该数据结构+214h和+218h的地方(也就是EAX+214h和EAX+218h)。IP地址是一个字符串指针 ,端口是个32位整数。我们要做的就是把他们都转换成字符串,保存在自己的地盘中。我们巧妙的用了一个wsprintfA函数把字符串和端口号输出到一个地址上(随便在我们的 “空隙”中找个空闲的地址,我用的是4D1700h,4D1720h中放的是格式化字符串“%s:%d”)。实际这段程序翻译成C语言就是printf(“%s:%d”,char *ip,int port),这样 我们就把字符串形式的数据保存在了数据区里。值得注意的是,由于我们修改了原程序中的有用的代码用于跳转程序,所以在我们的程序中就需要加上(cmp dword ptr [eax+000001DC], ecx)这句代码,退出我们的程序之前恢复栈指针和各寄存器,用一条无条件跳转指令转回到原程序继续执行。

细心的同学可能注意到我们没有显式的调用wsprintfA函数,但是我们实际上是调用了。在显示IP的那段附加程序中调用SetWindowTextA的调用也 是这样。这是怎么回事呢?我们知道所有API函数的调用前都需要重定位,这个过程发生在系统装入这个PE程序的时候。系统按照PE文件中Import表的内容对API函数在程序中的 地址进行填写。我们没有修改Import表,所以,如果直接写上汇编代码,系统是不会为它定位的。由于Import表比较复杂,更改它是个非常繁琐的事情。所以我们采用变通的方 法,既然系统为用到的API函数地址都作了重定位,所以API函数的地址信息也就存在了。

具体的做法如下:
找到原程序中有调用wsprintfA的地方:
:0049CE30 FF1560274D00 Call USER32.wsprintfA
:0049CE36 83C410 add esp, 00000010
:0049CE39 EB1A jmp 0049CE55

实际的汇编代码应该是Call dword ptr [004D2760],我们就知道了wsprintfA的地址是放在004D2760中。所以,我们只要间接的获得这个调用的地址 ,这个地址就是指向wsprintfA实际地址的二重指针。这样我们就可以直接Call这个地址了。在“显示IP地址和串口的附加程序”中所用到的SetWindowTextA也是用这种方法调用的 。(具体修改方法详见“弹出发送消息窗口之前的对象数据调用的程序段”和“保存IP地址和端口的附加程序”)

在把IP地址和端口保存为了字符串形式在4D1700h之后,今后只需要在需要的时候显示出来就行了。

前面我们提到了需要在点击广告后显示IP地址。所以,我们在点击广告的程序段中间添加了跳转到我们显示程序的入口(4D1680h)。显示程序的原 理很简单,使用SetWindowTextA函数把保存在4D1700h的字符串显示在以前广告的窗口中。在显示之前,判断一下如果没有IP地址的情况,如果是只有一个冒号,说明没有IP地址, 就简单的写上一个“0”。调用SetWindowTextA函数的方法在前面已经提到。需要注意还有两个重要的问题:

我们从什么地方获得SetWindowTextA函数需要的一个参数――广告窗口句柄呢?我特意在“发送消息窗口点击广告的程序段”中写出了在点击广告 时有一个Call USER32.GetWindowRect调用的代码,这个函数同样需要窗口句柄。[ESI+160h]就是USER32.GetWindowRect需要的广告窗口句柄,我们就可以利用这个句柄调用 SetWindowTextA,使字符串显示在广告窗口上。

还有就是由于原来的广告窗口是用于图片的显示,所以不能用来显示字符。它的窗口样式中有个SS_ETCHEDFRAME的值。我们需要去掉它并加上用 于垂直居中和水平居中的两个样式SS_CENTER和SS_CENTERIMAGE。一般静态对话框中的窗口元素(控件)都是静态的保存在资源段中,而不是程序动态生成的。所以我们不需要 改程序,只需要改掉资源段中的值就可以了。具体改法详见“消息发送对话框中广告窗口样式的更改”。

程序基本上改完了,终于可以享受我们辛苦改动的结果了,不料Oicq 820版有检查文件是否被修改过这一手。同样,阻止我们通向成功道路上的任 何障碍只能无情的被我们消灭,这个提示文件已被修改的对话框也只能被我们搞调。幸好搞它非常的简单,把断点设置在MessageBoxA上,等蹦出断点后,查找前面的代码,找到 判断是否弹出对话框的代码并且无情的干掉,详见“弹出文件修改警告框的程序段”。

大功告成!学到不少东西吧!这么多代码自己慢慢用UltraEdit查找修改吧,知道敲错一个的后果吗?呵呵,不是死机就是重起。考虑到一些初级 DIY用户的需求,我把修改好的EXE文件用专业的Patch软件“CodeFusion”作成了一个18K的Patch执行文件。需要的朋友额可以到我主页上去下载。

好了,课程结束。如果有时间的话,还可以对Oicq作很多的改造。但无疑这个任务是非常艰巨而复杂的,但是只要你有必胜的信心以及充沛的精力 ,并且敢于接受这种毫无人性任务的挑战,还有视一切PPMM为粪土的高尚眼光和能忍受对自己无情虐待的勇气,你会成功的!(¥……#%%……※#!¥#%啊啊啊啊~~~ ~~~~呃~~,被前排学生暴扁)。

~~~~下课咯~~~~

打开广告文件的程序段 更改以前:
:0042AF5B FF152C244D00
:0042AF61 8BF8
:0042AF63 83FFFF
:0042AF66 897D08
:0042AF69 0F84EB000000
:0042AF6F 8D45F4
:0042AF72 50
:0042AF73 57

Call KERNEL32.CreateFileA
mov edi, eax
cmp edi, FFFFFFFF
mov dword ptr [ebp+08], edi
je 0042B05A
lea eax, dword ptr [ebp-0C]
push eax
push edi


;打开广告文件
;返回文件句柄
;判断是不是无效句柄(打开失败)
;保存
;无效就转




更改以后:
:0042AF5B FF152C244D00
:0042AF61 8BF8
:0042AF63 83FFFF
:0042AF66 897D08
:0042AF69 E9CE000000

Call KERNEL32.CreateFileA
mov edi, eax
cmp edi, FFFFFFFF
mov dword ptr [ebp+08], edi
jmp 0042B03C

;打开广告文件
;返回文件句柄
;判断是不是无效句柄(打开失败)
;保存
;不管打开成功与否都转

手工更改方法:
文件偏移: 2AF69h
查找16进制代码: 89 7D 08 0F 84 EB 00 00 00
更改为: E9 EC 01

弹出文件修改警告框的程序段

更改以前:
:00443B56 33FF
:00443B58 397DDC
:00443B5B 755C

xor edi, edi
cmp dword ptr [ebp-24], edi
jne 00443BB9


;是否修改过原文件,是就弹出警告对话控
;不是转

更改以后:
:00443B56 33FF
:00443B58 397DDC
:00443B5B EB5C

xor edi, edi
cmp dword ptr [ebp-24], edi
jmp 00443BB9


;不管是不是都转
手工更改方法:
文件偏移: 43B5Bh
查找16进制代码: 39 7D DC 75 5C
更改为: EB
 
发送消息窗口点击广告的程序段

更改以前:
:00432B4E 50
:00432B4F FFB660010000
:00432B55 FF1578274D00
:00432B5B 8D45DC
:00432B5E 8BCE
:00432B60 50
:00432B61 E8A6110700
:00432B66 FF7510
:00432B69 8D45DC
:00432B6C FF750C
:00432B6F 50
:00432B70 FF15B8274D00
:00432B76 85C0
:00432B78 0F84FF000000
:00432B7E 6A10
:00432B80 FF157C274D00
:00432B86 33DB
:00432B88 663BC3
:00432B8B 7D0F
:00432B8D C705D874510001000000
:00432B97 E9E8000000

push eax
push dword ptr [esi+00000160]
Call USER32.GetWindowRect
lea eax, dword ptr [ebp-24]
mov ecx, esi
push eax
call 004A3D0C
push [ebp+10]
lea eax, dword ptr [ebp-24]
push [ebp+0C]
push eax
Call USER32.PtInRect
test eax, eax
je 00432C7D
push 00000010
Call USER32.GetKeyState
xor ebx, ebx
cmp ax, bx
jge 00432B9C
mov dword ptr [005174D8], 00000001
jmp 00432C84



;esi+160是窗口句柄










;判断是否在广告区域内点击

;是








更改以后:
:00432B70 FF15B8274D00
:00432B76 85C0
:00432B78 0F84FF000000
:00432B7E 6A10
:00432B80 FF157C274D00
:00432B86 E9F5EA0900
:00432B8B 7D0F
:00432B8D C705D874510001000000
:00432B97 E9E8000000

Call USER32.PtInRect
test eax, eax
je 00432C7D
push 00000010
Call USER32.GetKeyState
jmp 004D1680
jge 00432B9C
mov dword ptr [005174D8], 00000001
jmp 00432C84

;判断是否在广告区域内点击


;是就跳到我们的显示程序当中


手工更改方法:
文件偏移: 32B86h
查找16进制代码: 33 DB 66 3B C3 7D 0F C7
更改为: E9 F5 EA 09 00


回复消息窗口点击广告的程序段

更改以前:
:0046221C FF15B8274D00
:00462222 85C0
:00462224 0F84D8000000 Call USER32.PtInRect
test eax, eax
je 00462302 ;判断是否在广告区域内点击

;不是就转
 
更改以后:

:0046221C FF15B8274D00
:00462222 85C0
:00462224 E9D9000000
Call USER32.PtInRect
test eax, eax
jmp 00462302
;判断是否在广告区域内点击

;不管是不是都转

手工更改方法:
文件偏移: 62224h
查找16进制代码: 0F 84 D8 00 00 00 8B 46 56
更改为: E9 D9 00 00 00 90

弹出发送消息窗口之前的对象数据调用的程序段

更改以前:
:0042513D 56
:0042513E 8BF1
:00425140 FFB6F4000000
:00425146 FFB6B0000000
:0042514C E879810300
:00425151 33C9
:00425153 3BC1
:00425155 7431
:00425157 3988DC010000
:0042515D 7508
:0042515F 8988E8010000
:00425165 EB0A push esi
mov esi, ecx
push dword ptr [esi+000000F4]
push dword ptr [esi+000000B0]
call 0045D2CA
xor ecx, ecx
cmp eax, ecx
je 00425188
cmp dword ptr [eax+000001DC], ecx
jne 00425167
mov dword ptr [eax+000001E8], ecx
jmp 00425171



;获得对象的数据结构首址

;是否成功,非零就成功
;失败转





 
更改以后:

:0042513D 56
:0042513E 8BF1
:00425140 FFB6F4000000
:00425146 FFB6B0000000
:0042514C E879810300
:00425151 33C9
:00425153 3BC1
:00425155 7431
:00425157 E9E4C40A00
:0042515C 90
push esi
mov esi, ecx
push dword ptr [esi+000000F4]
push dword ptr [esi+000000B0]
call 0045D2CA
xor ecx, ecx
cmp eax, ecx
je 00425188
jmp 004D1640
nop




;获得对象的数据结构首址

;是否成功,非零就成功
;失败转
;跳到我们的保存IP地址和端口的程序中
;加一个空操作对齐

手工更改方法:
文件偏移: 25157h
查找16进制代码: 39 88 DC 01 00 00 75 08
更改为: E9 E4 C4 0A 00 90

保存IP地址和端口的附加程序

添加代码:
:004D1640 8BDC
:004D1642 BC00194D00
:004D1647 50
:004D1648 51
:004D1649 52
:004D164A 56
:004D164B FFB018020000
:004D1651 FFB014020000
:004D1657 6820174D00
:004D165C 6800174D00
:004D1661 8B3532CE4900
:004D1667 FF16
:004D1669 83C410
:004D166C 5E
:004D166D 5A
:004D166E 59
:004D166F 58
:004D1670 3988DC010000
:004D1676 8BE3
:004D1678 E9E03AF5FF
:004D167D 90
:004D167E 90
:004D167F 90 mov ebx, esp
mov esp, 004D1900
push eax
push ecx
push edx
push esi
push dword ptr [eax+00000218]
push dword ptr [eax+00000214]
push 004D1720
push 004D1700
mov esi, dword ptr [0049CE32]
call dword ptr [esi]
add esp, 00000010
pop esi
pop edx
pop ecx
pop eax
cmp dword ptr [eax+000001DC], ecx
mov esp, ebx
jmp 0042515D
nop
nop
nop ;保存原程序的栈指针
;设置新的栈指针到无用的内存区域
;保存原程序几个有用寄存器



;对象端口的地址
;IP地址的字符串指针
;指向“%s:%d”,这是printf的模式字符
;输出到的地方
;其他地方调用wsprintfA的地址
;esi为已经重定位好了的wsprintfA的地址
;恢复栈指针
;恢复有用的寄存器值



;原程序00425157处被改掉的有用代码
;恢复为以前的栈指针
;跳转到原程序




手工更改方法:
文件偏移: D1640h
添加16进制代码: 8B DC BC 00 19 4D 00 50 51 52 56 FF B0 18 02 00
00 FF B0 14 02 00 00 68
00 8B 35 32 CE 49 00 FF
39 88 DC 01 00 00 8B E3 20 17 4D 00 68 00 17 4D
16 83 C4 10 5E 5A 59 58
E9 E0 3A F5 FF 90 90 90

显示IP地址和端口的附加程序

添加代码:



:004D1680 803D00174D003A
:004D1687 7509
:004D1689 66C70500174D003000
:004D1692 6800174D00
:004D1697 FFB660010000
:004D169D A1E8714A00
:004D16A2 FF10
:004D16A4 E9D415F6FF
:004D16A9 90
:004D16AA 90
:004D16AB 90
:004D16AC 90
:004D16AD 90
:004D16AE 90
:004D16AF 90


cmp byte ptr [004D1700], 3A
jne 004D1692
mov word ptr [004D1700], 0030
push 004D1700
push dword ptr [esi+00000160]
mov eax, dword ptr [004A71E8]
call dword ptr [eax]
jmp 00432C7D
nop
nop
nop
nop
nop
nop
nop ;判断字符内存区第一个字符是不是冒号,是就说明没有IP地址
;不是转到显示程序
;在字符内存区写上一个“0”
;字符内存区首址
;广告窗口的窗口句柄
;其他地方调用SetWindowTextA的地址
;eax为已经重定位好了的SetWindowTextA的地址
;跳到广告点击程序之后
;无用的空操作,只是为了对齐好看




wsprintf所用到的模式字符串:
:004D1720 25733A2564 "%s:%d"
手工更改方法:
文件偏移: D1680h
添加16进制代码: 80 3D 00 17 4D 00 3A 75 09 66 C7 05 00 17 4D 00
30 00 68 00 17 4D 00 FF
4A 00 FF 10 E9 D4 15 F6 B6 60 01 00 00 A1 E8 71
FF 90 90 90 90 90 90 90
文件偏移为: D1720h
添加16进制代码 25 73 3A 25 64

消息发送对话框中广告窗口样式的更改

更改样式字:
更改以前的窗口样式(style)是50000012h WS_CHILDWINDOW|WS_VISIBLE|SS_LEFT|SS_ETCHEDFRAME
更改以后的窗口样式(style)是50000201h WS_CHILDWINDOW|WS_VISIBLE|SS_LEFT|SS_CENTER|SS_CENTERIMAGE
手工更改方法:
文件偏移: 141EFCh
查找16进制代码: 12 00 00 50
02 01 00 50

代码段段属性修改

更改属性字:
更改以前的代码段属性为60000020h CER(包含代码,可执行,可读)
更改以后的代码段属性为C0000020h CRW(包含代码,可执行,可读写)
手工更改方法:
文件偏移: 21Ch
查找16进制代码: 20 00 00 60
20 00 00 C0
 
Thank !
More..
 
这也是我想要的
 
话题473316的标题是: 关于OICQ (0分)
分类:Internet/TCPIP UFO is me (2002-04-30 10:23:00)

我们的主机是通过代理服务器上网的,而网管关闭了服务器的某些功能,
使我们不能用OICQ,但我想能不能写一个程序 A,发布到自己在某个网站上的网页中,作为
一个中转,自己的主机上则放一个客户程序 B。
自己的OICQ发的消息首先是通过 B 转化成HTTP格式的消息传到 A, 然后由 A 再把接受到
的消息,转化成OICQ格式的消息,传给目的人。
接受时也一样。A 先接受到消息,再传给 B, B再传给OICQ
注:s2h 作不到这个功能。(我用s2h 也没有用)
我觉得,我们首先要知道OICQ 的 传输协议。


Chenlili (2001-03-19 11:47:00)
OICQ 的传输协议能有几个人知道?

sportsman (2001-03-19 12:11:00)
不可能(可能性很小)

悲酥清风 (2001-03-19 13:32:00)
不是有那种把sock等协议转成http协议的软件的吗?
可惜记不清是在电脑报上还是计算机文章上看到的。

教父 (2001-03-19 13:38:00)
如果可以的话,OICQ早就被别人黑了。

eprog (2001-03-20 23:25:00)
搞清楚QQ的协议基本上不可能,你的意思其实就是架一个代理服务器,但是要求也太高了,
要求只能在网页上实现。ASP除非ASP服务器上有ACTIVEX控件可以使ASP使用SOCKET,JAVA
APPLET的SOCKET一般则只能连回到原来的服务器,PHP的也有类似问题。如果以上关键的
问题解决了则我想完全可以实现架设一个网页上的代理服务器。不过话说回来,这个东西
耗的资源也太不合算了,除了自己偷偷用之外,大规模用不如找一个真正的代理服务器。

Kaven (2001-03-20 23:57:00)
它走的是udp.

honghs (2001-03-22 14:45:00)
这个是把socks请求转成http请求,如果你那边连http都不开的话,建议公司换你做网管算了
Socks2HTTP 查看版本及下载 >>
一个代理服务器协议转换软件,它能将基于 Socks 协议的请求转换为HTTP协议的请求,并通过你指定的 HTTP代理服务器处理这些请求。此软件配合 SocksCap32,能使只提供 HTTP 代理服务的局域网或是 169 用户使用非HTTP协议的软件,如 FTP 客户端软件,E-Mail 客户端软件,Telnet 客户端软件,以及聊天软件等等!
http://202.101.237.103/f/jwjjt/soft4/setups2h07.zip
http://202.101.237.103/f/jwjjt/patch10/s2h07-ro.zip

djdsz (2001-03-22 15:07:00)
这软件似乎very slow,我用过,只能发一条信息就不行了。结果我还是用代理。

你可以试试61.144.238.145作服务器地址,端口号8000

UFO is me (2001-04-11 1:10:00)
有谁能告诉我,oicq接受消息的端口号是多少?

socks2http 我这根本用不了,一连接就报错。
用djdsz的服务器地址也没有用。

redsky.l (2001-04-11 2:50:00)
呵呵,只要一锁8000的端口,OICQ服务端口, 你会飞天也收不到OICQ信息,
OICQ服务器传不进来!
解决方法:1、和网管搞好关系;
2、争取自己做网管,最好是老总:)
3、跳槽。


sluger (2001-04-11 19:44:00)
最新版本的qq2000支持http代理了

gzlad (2001-04-11 20:07:00)
用djdsz的服务器地址有用. 我就是用那个的。

UFO is me (2001-05-11 2:34:00)
还是不行呐!太惨了。icq 都可以,oicq 却不行。

jingtao (2001-05-11 16:03:00)
OICQ 的传输协议:
协议是UDP的,但问题是在于它的信息加密格式不知道.
如果QQ接收到信息后发现加密不对就不显示出来(不弹出窗口)

finalwish (2001-05-15 11:20:00)
我在WWW.CSDN.com上看到一张帖子讲的是OICQ的协议,我还未研究完,现帖上一起研究。

发信人: flyingblue (好想睡觉!), 信区: Encrypt
标 题: Re: 请教OICQ的加密原理
发信站: 武汉白云黄鹤站 (Wed May 31 13:52:22 2000), 站内信件

c前言:
Oicq 作为Inet实时通讯应该是一个不错的选择,
众多的用户群也证明了这点。(按照腾讯主页(www.tencent.com)
上的说话,截至目前,Oicq 用户已经突破 450 万,而且以每天30000的速度增加)
在安全问题日益突出的今天,一个如此*广泛使用*的产品不去考虑
安全方面的问题,显然是不明智的。而且这个考虑应该是在产品
规划阶段就提上日程的。Oicq 显然没有把安全放在第一位,几个月
前,安安(watchsea@sina.com)就已经指出了 Oicq 存放在本地的用户
口令仅仅使用了微弱的加密手段。 ( build:220 中,Oicq
声称已经将其修正)
经过我们的分析测试,更加严重的问题还在后面。在发现了这些问题后,
我们马上通知了腾讯公司,腾讯的反应很快,一夜间,Oicq 的版本就从
220 升级到了 410 . 在其 whatnew 中,声称解决了这些问题。
我们立即对其进行了测试。应该看到,在 Oicq build 410 中,腾讯使用
了某种加密协议,从而解决了明文传输的问题。应该说是一个很大的进步。
因此本文分为两章,第一章针对 Oicq Build 220 及其以下版本。
第二章针对 Oicq Build 410 (截至目前最新版本)
应该看到,本文不带有任何地感情色彩,我们也是使用 Oicq 进行日常的
联络的.希望腾讯公司能尽快的解决这些问题。
- I -
-
测试报告:
除开安全问题,Oicq 应该是一个很好的选择,其功能实用,不花哨。
但作为一个放在互连网上的产品,必须还要考虑到安全性。
Oicq 采用的是 server-client 模型,使用的是 UDP 协议。和 TCP 相比,
UDP 本身就是不可靠的,可被轻易的伪造。使用 UDP 协议的软件必须自身在
两端进行可靠性检测。但和 TCP 相比,UDP 在资源占用上显然要
小许多,这也是 Icq,Oicq 选择 UDP 的一个主要原因。
经过分析,Oicq 在所有的传输过程中,任何数据都使用了明文发送,也就是
说,一个窃听者能直接的偷听到经过其的所有 OICQ 信息。这是一个不大不小
的问题,象往常一样,你有两个选择,更低的资源占用率和更高的安全性。很难作出
决定在二者之间。显然, Oicq 选择了前者。
在Oicq中最常用的消息传送时,Oicq 采用了如下策略: 当二者能直接(点到点)
通讯时,消息就直接的发送到对方,否则重试 N 次后通过Oicq 服务器转发。接受方
在收到消息后返回一个回应信息,发送方就是通过这个信息来确认消息是否已经收到。
消息的结构是:
(注意:本文中所有的 Oicq 协议结构是通过分析得来,不能保证其正确性)
struct TOicqPtoP
{
char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag3; // 0x07
char Tag4; // 0x00
char Tag5; // 0x78
char Tag6; // 这两个字节相当于 unix 上的进程 ID,
char Tag7; // 随便赋值就可。
char cOicqNub[]; // 发送方的Oicq 号码。 exp:123456
char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f
char cR; // '0' 固定
char cFF; //
char cE[]; // "75" ,这一位相对固定,可能是操作方式。
char cFF;
char cDateTime[]; // exp: "2000-4-10",0x1f,"12:00:12",0x1f
char OutMsg[]; // 发送的消息内容。
char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。
};
当接受方收到以上格式的 Udp Packet,就会显示有信息收到,完全没有其他的验证过程。
也就是说,如果我从 linux 上发了个符合上述格式的 Udp packet,在 cOicqNub 处可填
写任意的oicq 号码,也就是可以伪造了任何的 oicq 号码。(你看到Oicq 上显示号码
为 1 的用户向你发信,不要吃惊。)
例如:有 A, B ,C 三用户,Oicq 分别是:
A: 10000
B: 20000
C: 30000
已知 B 和 C 是好友,则 A 可以发送一个带有 B 号码的Udppacket 给 C, 在
C 处看来,完全就像是 B 亲自发给他的一样,但此时如果 C 点回复的话,
信息会回到 B 的地址(IP)上。A 不能收到。也就是说 A 只能冒充B 发消息。
如果此时 A 不停地发,就形成了 Oicq Flood,注意的是,此时Tag6,Tag7 两处要不停地
变化,Oicq 对两个完全一样的信息只显示一次。
严重的是,虽然Oicq 本身对发送的消息的长度做了限制,但这种限制是在发送方进行的,
一旦发送的长度超过 2000 or >2000 个字节,接受方的 Oicq 就会发生缓冲区溢出,
相当严重的远程溢出。
接下来就是谈谈怎样让 C 回复伪造消息时直接返回到 A 处。
运行 Oicq 时,过程如下:
start oicq.exe-> 上线 -> oicq 把口令发给 oicq server -> oicq server 返回
其好友名单以及其对应的 IP (Oicq 把他存到本地内存中的一张表中)
当 Oicq 给相应的好友号码发送消息时,依据的地址就是这个 IP.
即首先与该 IP 联系,反复多次没有回音就通过服务器转发。
下面是 Oicq server 通知Oicq 好友上线和下线的消息结构:
struct TOicqUp
{
char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag3; // 0x00
char Tag4; // 0x00
char Tag5; // 0x81
char Tag6; // 这两个字节相当于 unix 上的进程 ID,
char Tag7; // 随便赋值就可。
char cOicqNub[]; // 通知上线的Oicq 号码。 exp:123456
char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f
char cIP; // 该号码所在的 IP 地址
char cFF; //
char cE[]; // "8685" ,这一位相对固定,随便添一个四位数字
char cFF;
char cDD[]; // exp: "10",0x1f,"107" 基本固定
char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。
};
//--------------------------------------------------------
struct TOicqDown
{
char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag3; // 0x00
char Tag4; // 0x00
char Tag5; // 0x81
char Tag6; // 这两个字节相当于 unix 上的进程 ID,
char Tag7; // 随便赋值就可。
char cOicqNub[]; // 通知上线的Oicq 号码。 exp:123456
char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f
char cIP; // 该号码所在的 IP 地址 // 随便填
char cFF; //
char cE[]; // "8685" ,这一位相对固定,随便添一个四位数字
char cFF;
char cDD[]; // exp: "20",0x1f,"107" 基本固定
char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。
};
向目标发送一个上述的UDp packet ,可让任意的在其列表上的好友上线或下线。
在上线时,IP 可填任意的你所希望的。然后Oicq 就会更据该 IP 来发送消息。
这样,上面的例子就改为:
首先, A 发送一个带有 B 上线信号的消息给 C, 但其 IP 添写 A 自己的IP,
不管此时 B 在线上没有, C 的 oicq 中就会显示 B 正在线上,此时 C 给 B 发消息,
更据的地址(IP) 就是 A 的地址,其所有的消息都会发往 A 处。
但此时有个问题:
如果 C 反复发送多次都没有收到来自 ‘B' 的回复时,就会通过Oicq 服务器转发。
这样 真正的 B 也会收到。解决方案是 C 在收到消息的同时也给 A 发送一个
回复。结构是:
struct TOicqReply
{
char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag3; // 0x07
char Tag4; // 0x00
char Tag5; // 0x79
char Tag6; // 值得注意的是,此时Tag6,Tag7 不能随便了,应该添写发过来的消息中的
char Tag7; // Tag6,Tag7.
char cOicqNub[]; // Oicq 号码。 exp:123456
char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。
};
//--------------------------------------------------------
值得注意的是,如果此时 A 所指定 C 回复的 IP 处正好有一个 Oicq ,
C 发给 B 的信息就会直接显示在其上面,不用伪造回复包。
至此,完整的一次Oicq 欺骗就完成了。
再来一次:
A 发送一个带有 B 上线信号的消息给 C, 但其 IP 添写 A 自己的IP(或所希望的),
这样 C 的 oicq 中就显示了 B 正在线上,当 C 给 B 发消息时,更据的地址
却是 A 的地址,其所有的消息都会发往 A 处。A 及时的返回一个表示已收到的消息
给 C ,C 处不会感到任何地异常,就仿佛是在和真正的 B 通讯一样,
如果当 A 发送消息时 B 已经在 C 的 Oicq 线上,此时 C 的 IP 表中关于 B 的ip
是其真实的 地址,此时我们有两种方法:
1. 向 c 发送一个 B 已下线的信号,让真正的 B 下线,然后再发送一个假的上线信号
2. 直接发送一个假的 B 上线信号,同样的, C 的IP 表中关于 B 的地址也会更新。
在 Oicq 的所有消息传送过程中,除了上线和下线时向oicq server 效对了口令之外,
其余的所有过程中,都没有进行任何的口令效验. 显然这是腾讯公司程序员的疏忽。
-
- II -
-
在我们告知腾讯公司关于 Oicq 的问题之后,腾讯很快的就推出了一个新版。
以修正其安全问题。在此之前,我就得知,Oicq 最近会有大的改动,可能是我们的
原因,迫使得他们提前将不成熟版推出。在新版中, 腾讯使用了某种新的算法将所有
的明文进行加密。算法的强度我们不得而知。但应该会在很大的程度上增强其安全性。
如果其早一周公布,这篇文章也就不会公布了。
在新版中,以前能随意使用户上下线的方法不行了,但其他的问题依然存在。
首先是缓冲区溢出,问题依然,任何熟悉安全的人士都知道这是个严重问题,
远不止当掉 Oicq 那么简单。希望腾讯能马上解决。
其次是类似于 build: 220 中那种假冒任意用户的 bug 依然如故。方法一样。
这也是个严重的问题,我们应该相信谁?
最后是象 Build 220 中那种完全欺骗 C 的技巧依然存在,即可以在某些情况下
截获任何人的对话,然后冒充之。
这个问题严重吗?赫赫
老话,希望腾讯马上修正。
-

总结:
有 ICQ 的前车之鉴, Oicq 本应做得更好。作为一个传递着纵多用户隐私的重要
通讯工具,Oicq 应该说在安全方面做得很糟。发展到现在,为了保持向下兼容,Oicq 也
很难立即作出大的改动。希望腾讯公司能尽可能修复这些问题,保护好广大用户的利益。
zer9 (zer9@21cn.com)
2000-4-12 15:47 于 I S B A S E 网络安全实验室
-
附录 & FAQ:
001.exe 和 002.exe 只是作为测试使用,请不要使用在违背国家法律的地带。
001.exe 和 002.exe *只能* 使用在 Microsoft Windows2000 平台上,测试是在
Windows2000 Server & Windows2000 Adv Server 上进行的。
001.exe 的作用是向目标发送完全匿名的消息,以及测试 Oicq 的远程溢出。
同时,对于 Build: 410 的 Oicq ,你向目标发送的匿名消息,目标回复时,消息
会回到指定地点。(UPD 源地址) 如果你正好在 该地址上装有 Oicq, 就会直接显示。
exp: 已知 A: Oicq: 10000 IP: 10.0.0.1
B: Oicq: 20000 IP: 10.0.0.2
C: Oicq: 30000 IP: 10.0.0.3
A 希望冒充 B 给 C 发送消息,同时希望接受到 C 给 B 的回复。
则在 UPD 源地址中添 A 自己的 IP,目标地址添 C 的 IP,目标号码添 B 的号码,
端口不变。就可以了。
002.exe 则只能用在 Build: 220 一下版本中,主要是使对方上下线。
最后,如果测试的任何一方处于网管或 Firewall 后,都可能不会成功。

声明:我们对该程序不提供技术支持,也不提供任何的保证)



Jamw (2001-09-21 11:36:00)
OICQ用户到OICQ服务器的通讯协议 引导符 (0x81+0x0A+0x01)
报文类型 报文内容 报文说明
0x01 昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T)新用户注册,身份验证用于当有人要将他加入好友时询问是否允许
0x02 服务号(L)+密码(S)+注册方式(T)老用户注册,方式分为0正常,1隐身
0x03 服务号(L)+对方服务号(L)+内容(S) 发送信息到某人
0x04 服务号(L)+组号(L)+内容(S) 广播信息,组号=0为全体
0x05 服务号(L)+朋友服务号(L) 查看朋友资料
0x06 服务号(L)+组名称(S) 增加组
0x07 服务号(L)+组编号(T)+组名称(S) 修改组名称
0x08 服务号(L)+组编号(T) 删除组
0x09 服务号(L)+移动人数(T)+{朋友服务号(L)+目的组号(T)} 移动组成员
0x0a 服务号(L)+起始编号(L)+回传个数(T)+查找标志(T) 看谁在线上
查找标志 1=向小找 2=向大找
0x0b 服务号(L)+SQL语句(S) 自定义查找
0x0c 服务号(L)+朋友服务号(L) 增加好友
0x0d 服务号(L)+朋友服务号(L)+加入原因(S) 请求加入好友
0x0e 服务号(L)+朋友服务号(L) 删除好友
0x10 服务号(L)+显示模式(T) 更改显示方式 1上线2隐藏3免打扰4离线
0x11 服务号(L)+监视服务号(L) 监视某人谈话
0x12 服务号(L)+昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T)更改用户基本信息
0x13 服务号(L)+朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件
0x14 服务号(L)+朋友服务号(L)+允许/拒绝 是否允许发送文件
0x15 服务号(L)+朋友服务号(L)+文件内容(B) 发送文件
0x16 服务号(L) 连接测试报文
0x17 服务号(L)+朋友服务号(L)+同意标志(T) 应答对方请求加入好友
0=拒绝
1=同意

OICQ服务器到OICQ的通讯协议
报文类型 报文内容 报文说明
0x01 成功/失败(T)+服务号(L) 新用户注册结果返回
0x02 成功/失败(T)+组个数(T)+{组名称(S)+组编号(T)+朋友个数(T)+{朋友服务号(L)+肖像编号(T)+朋友状态(T)+朋友昵称(S)] 老用户注册结果返回
朋友状态
1=上线=2隐藏=3免打扰4离线
0x03 标志(T) + 朋友服务号(L)+信息(S)+信息类型(T) 标志 1=系统 2=用户
发送消息,服务号=0是系统消息
1=用户某某已经把你加为好友
2=用户某某请求你通过身份验证
3=用户某某同意了你的验证要求
4=用户某某拒绝了你的验证请求
0x04 成功/失败(T)+朋友服务号(L)+昵称(S)+肖像(M)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)朋友信息回送
0x05 成功/失败(T)+组编号(T)+组名称(S) 增加组结果回送 1/0
0x06 成功/失败(T)+组编号(T)+组名称(S)修改组名称结果回送1/0
0x07 成功/失败(T)+组编号(T) 删除组结果回送1/0
0x08 成功/失败(T) 移动组成员结果回送1/0
0x09 成功/失败(T)+在线个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)} 查找在线人员结果回送
0x0a 成功/失败(T)+找到个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)} 自定义查找结果回送(最多50)
0x0b 标志(T)+朋友服务号(L) 增加好友结果回送标志
0=数据库失败
=1成功
=2需要身份验证
=3对方不允许加入
=4需要身份验证且不在线
0x0c 朋友服务号(L)+昵称(S)+肖像号(M)+朋友状态(T) 给在线用户增加好友
0x0e 成功/失败(T)+朋友服务号(L) 删除好友结果回送
0x10 服务号(L)+显示模式(T) 显示模式回送 =1上线=2隐藏=3免打扰4离线
0x11 成功/失败 更改用户基本信息结果回送
0x12 朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件
0x13 朋友服务号(L)+允许/拒绝 是否允许发送文件 1允许 0拒绝
0x14 朋友服务号(L)+文件内容(B) 发送文件
0x15 朋友服务号(L)+当前状态(T)朋友状态回送(系统发送)=1上线=2隐藏=3免打扰4离线
0x16 服务号(L) 连接测试

小人物 (2001-09-24 10:26:00)
高人啊,。。。

smilboy (2001-09-24 18:36:00)
udp如何发送Record类型的数据?

Type apple=Record
color:=Color;
name:string;
end;

..................


UFO is me (2001-10-18 19:11:00)
我爱高手!
TmpStr:=char($81)+char($0A)+char($01)+char($02)+'10000'+'(L)'
+'123123'+'(S)'+'1'+'(T)';
MyStream := TMemoryStream.Create;
try
MyStream.Write(TmpStr[1], Length(tmpStr));
UDP.SendStream(MyStream);
finally
MyStream.Free;
end;
我这样写为什么没反应?

LiDS (2001-11-12 16:29:00)
to "UFO is me"
MyStream.Write((@TmpStr[1])^, Length(tmpStr));
or
MyStream.Write((@TmpStr)^, Length(tmpStr));

OK?

OopsWare (2001-11-12 16:47:00)
OICQ 不只使用 TCP/IP 的 TCP8000端口, 还有UDP4000 4001 .....
还是想法子得到网关的口令吧!

delta2 (2002-02-08 3:29:00)

GZ


whsuperboy (2002-02-25 15:21:00)

有现成的工具。
使用socksonline。国产免费软件,通过HTTP实现本机SOCKS代理。支持tcp和udp协议。
能用QQ,FTP,MUD,IRC...
http://www.waysonline.com


smallbs (2002-04-29 12:29:00)

socksonline是免费下载的,但在使用时要想得到正常的效果还是要注册交费的


justcool (2002-04-29 15:31:00)

不知对于在一局域网内通过网关IP登陆的QQ是如何通过网关收到另一通讯QQ发给它的数据包
的呢,就是说数据包到了网关,如何转发到局域网内的目标IP?


OopsWare (2002-04-29 16:25:00)

这个问题还没结束?!
finalwish 和 Jamw 在发贴子的时候鰧讯就已经停止了对上述协议的服务。
并在IP包中加入了利用 QQ 号加密产生的通讯验证数据。
Linux下的FOicq开放了其加密部分的源码(NASM汇编),我还在尝试将他在Delphi下编译,见:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=944640


xdf_hubei (2002-04-29 16:38:00)

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1041729
前段时间我刚奉老总之命封杀公司QQ,你不会是我们公司的吧~!?[8D][8D]
我也不想这样啊,我通过网关封杀,直接丢弃来自腾讯主机IP的数据


coolbaby (2002-04-29 18:51:00)

我知道你的意思是只开80端口,如何上qq
主要是做一个socks代理服务器
不过这个socks代理服务器还需要一个中转服务器支持
这个中转服务器监听80端口
因为最终socks代理服务器的数据还是要通过80端口发出的
相当与用两个socks代理服务器
socksonline和socks2http的原理就是这样的
本来想写一个这样的软件的,因为sockesonline用的人多,太慢了
现在看来是没时间了


justcool (2002-04-29 19:30:00)

不知对于在一局域网内通过网关IP登陆的QQ是如何通过网关收到另一通讯QQ发给它的数据包
的呢,就是说数据包到了网关,如何转发到局域网内的目标IP?

and id:
1404862
365804
849267
others you can search DELPHIBBS(20030331).chm
 
oicq与UDP协议

--------------------------------------------------------------------------------

TCP/IP协议是整个互联网上数据传输的核心,OICQ也是基于TCP/IP协议的UDP协议来实现的。下面来看看 OICQ是怎么样工作的呢?下面我将通过捕捉OICQ2000数据包来进行分析OICQ2000的工作原理:(在WIN2000的安装包里有一个网络监视器,可以用来监视网络上的各个数据包。)
打开WIN2000的网络监视器,然后开始监视网络数据包,然后打开OICQ,登陆后停止捕获数据包。然后就可以进行分析了。下面这个数据包就是利用网络监视器捕捉到的我的OICQ登陆的发送时的第一个数据包:
00000000 00 80 C8 EB 06 3B 00 80 C8 EB 25 18 08 00 45 00 .....;....%...E.
00000010 00 78 48 8A 00 00 80 11 BC 3A C0 A8 00 02 CA 60 .xH......:.....`
00000020 AA A5 0F A0 1F 40 00 64 AA 4E 02 04 05 00 15 F7 .....@.d.N......
00000030 2F 00 BD 77 9D F3 BE 2E 18 9A 86 DA 47 B4 83 41 /..w........G..A
00000040 3A A1 A5 60 89 AD 78 61 D7 EE 6A ED 5C 05 25 EA :..`..xa..j./.%.
00000050 17 95 B0 5C 3B 69 F1 1C 0F 5D C1 4C 91 FD C3 A8 .../;i...].L....
00000060 1D 33 9C 86 2A 0F 12 11 EA A8 29 E4 AC 64 D4 D6 .3..*.....)..d..
00000070 A4 96 4D 86 AD C2 19 F1 ED E9 FB 7B 74 99 B7 7A ..M........{t..z
00000080 C3 FB C2 B5 7D 03 ....}.

下面我将解析这个数据包。此个数据包可以分三段来解析:网卡地址段,IP协议段和UDP协议段。

1、网卡地址段
00000000 00 80 C8 EB 06 3B 00 80 C8 EB 25 18 08 00
如上可所视00 80 到第一行的确良08 00为网卡地址段。开始的六个字节00 80 C8 EB 06 3B为对方服务器网 络适配器在内存中的地址,00 80 C8 EB 25 18 ,这六个节嘛就代表我这台机子上的调解在内存中的地址。然后的08表示该数据传输协议将用TCP/IP协议传输。00表示下面将用TCP/IP协议中的IP协议传输。

2、IP协议段
00000000 45 00 .....;....%...E.
00000010 00 78 48 8A 00 00 80 11 BC 3A C0 A8 00 02 CA 60 .xH......:.....`
00000020 AA A5
如上所示45 00 到AA A5之前的代码都代表了IP段的内容。45代表此IP协议版本是4.0版本,IP关长度是20字节。即从45到AA A5的20个字节。00 是代表IP包的优先级。这里是平常的没有设等级。00 78转换成十进制是120。(倒过来算,0078=120(十进制))表示此数据包的所有数据有120个字节。48 8A 代表IP协议的身份验证, 00 00是IP协议的摘要,80传表IP数据包的生存时间。11这里很重要,表示此IP数据段完成以后将由UPD协议来 代替,由此我们可以得知OICQ消息传播是通过UDP协议来实现的。BC 3A是用来校检数据包的正确性的。C0 A8 00 02代表我的IP地址。用计算器可以转化成192.168.0.2。CA 60 AA A5代有目的IP,即202.96.170.165。此IP 数据段就完成了。余下的就是UDP数据段了。

3、UDP数据段
00000020 0F A0 1F 40 00 64 AA 4E 02 04 05 00 15 F7 .....@.d.N......
00000030 2F 00 BD 77 9D F3 BE 2E 18 9A 86 DA 47 B4 83 41 /..w........G..A
00000040 3A A1 A5 60 89 AD 78 61 D7 EE 6A ED 5C 05 25 EA :..`..xa..j./.%.
00000050 17 95 B0 5C 3B 69 F1 1C 0F 5D C1 4C 91 FD C3 A8 .../;i...].L....
00000060 1D 33 9C 86 2A 0F 12 11 EA A8 29 E4 AC 64 D4 D6 .3..*.....)..d..
00000070 A4 96 4D 86 AD C2 19 F1 ED E9 FB 7B 74 99 B7 7A ..M........{t..z
00000080 C3 FB C2 B5 7D 03
如上可看到此段即为激动人心的UDP数据段了。我们开始分析。0F A0代表我是通过哪个端口进行发送消息的 ,这里可以换算成4000,即我用4000的端口进行消息发送。1F 40代表腾讯的OICQ主机是通过哪个端口接收消息 ,这里可以换算成十进制的8000。即腾讯的OICQ服务器是通过8000端口接收消息的。00 64代表此UDP数据段的 总的字节是100。AA 4E是拿来校检UDP数据段的数据的。余下的数据就是此UDP数据包传送的数据。而前面都是 一些控制协议。下面我们将解析这些数据。02 04 05 00似乎是一些和版本有关的数。相同版本的数据相同的。 15代表登录服务器,F7 2F 00可能是和一些顺序号有关。接下来的三个字节是从高到低放着你的OICQ号。后面的16位字节是随机产生的16个字节的密钥,64字节口令加密内容。 最后03表示UDP数据结束。一般是固定的值。
当OICQ的服务器收到此登录数据包以后通过验证,服务器将反馈给你一个数据包,这里你的OICQ就上线了。
OICQ上线以后,每隔一段时间服务器向你发送一个数据包,上面有你好友的IP和号码,用此来表示你好友在线的情。你同时也反回一个数据包给服务器。里面当然也包括你的IP了。表示你在线。如果你没有反回一个数据包给服务器,那么就表示你不在线了,这时你在你的朋友的OICQ上就不在线了。

OICQ消息传递原理
00000000 00 80 C8 EB 06 3B 00 80 C8 EB 25 18 08 00 45 00 .....;....%...E.
00000010 00 60 1A D9 00 00 80 11 E6 54 C0 A8 00 02 3D A6 .`.......T....=.
00000020 3B 0F 0F A0 0F A0 00 4C 3D 31 00 04 05 9D 62 DF ;......L=1....b.
00000030 15 FF 62 37 81 9B 0B 1E 83 8F F7 DE 1A 67 E6 2B ..b7.........g.+
00000040 35 28 E1 A9 ED B4 01 7C 92 B5 E4 2D E5 69 70 C5 5(.....|...-.ip.
00000050 2E E1 22 FC AF 1C 25 4D E9 7C E8 BA FD F0 8B 87 .."...%M.|......
00000060 17 95 08 88 95 DD A4 1B 8D DC 36 85 0C 8E ..........6...
如上所示,也是基于上面的UDP协议。所不同的只是UDP传输的数据不同。根据服务器发送来的给来的数据包知道你好友在线的IP,然后当你向好友传送消息的时候,就是根据好友的IP通过UDP协议向对方发送数据包,对方机子上的OICQ收到的你的数据包的时候就反馈一个数据包给你表示已经收到你的消息,否则的话就一直发送。 等到对方反馈数据包为止。当到一定时候对方一直没有反馈数据包给你的时候,就通过服务中转。中转的原理是这样的,将数据包给腾讯的服务器上,由服务器又将数据包发到对方的机子上,这就是通过服务器中转的工作的原理。

00000020 00 04 05 9D 62 DF ;......L=1....b.
00000030 15 FF 62 37 81 9B 0B 1E 83 8F F7 DE 1A 67 E6 2B ..b7.........g.+
00000040 35 28 E1 A9 ED B4 01 7C 92 B5 E4 2D E5 69 70 C5 5(.....|...-.ip.
00000050 2E E1 22 FC AF 1C 25 4D E9 7C E8 BA FD F0 8B 87 .."...%M.|......
00000060 17 95 08 88 95 DD A4 1B 8D DC 36 85 0C 8E ..........6...
(聊天的时间和内容从数据包的偏移地址2B处开始)

好友间消息传送原理基于UDP协议,和登录的数据包一样。只不过所传输的UDP数据为你和好友聊天的记录。如上面的数据段即为即为谈话时间,内容。这些数据都通过加密的形式在网络中转输。

 
多人接受答案了。
 
后退
顶部