封包加密解密-01

封包加密解密-01

网络游戏客户端与服务器之间需要数据交换处理,数据包通过TCP网络协议进行传送,这里我们称数据包为封包.

之前有教程介绍了如何使用模块中的功能进行封包拦截,修改,替换等功能.本章将完全讲解如何对封包的加密,解密技术.

为什么需要解密封包呢?除非那些封包是明文的(即没有加密处理过),否则就得解密,只有解密出来了数据,才能更清楚的了解游戏是如何交换数据处理,分析出封包数据才能够做出脱机外挂,完全脱离游戏客户端,模拟一个客户端来与游戏服务器连接,做你一切想做的事都没问题.所以封包加密解密技术是脱机外挂的第一前提条件.

即使不做脱机外挂,封包技术仍然比CALL技术更有用处.学过前章后大家应该也知道分析CALL,找CALL,调CALL都不是件容易的事.若能完全解密封包就可以减少或不需要CALL,模拟,内存操作了.

有加密就得有解密,有解密当然要有加密.这是相对立的.对封包数据进行加密与解密的函数过程,称为算法.

那封包加密解密技术容易吗?比较讽刺的就是,90%以上的网络游戏的封包都是很容易搞定了.为什么呢?如果算法复杂了的话,会多占CPU性能,而游戏服务器要处理的工作很多,不能把性能全用在加密解密上.举个简单的例子,游戏服务器若同时连接在线的玩家有十万人的话,这些玩家在聊天,打怪,走路等都会产生封包,若算法过于复杂,服务器就很难同时处理得了这么多玩家的封包,何况还得处理数据库中的数据呢.

出于服务器的性能考虑,所以若想同时能在线更多玩家,就不能进行复杂的算法来加密封包.不然就得限制减少能同时在线的玩家,不然游戏服务器会一卡一卡的,导致所有玩家都玩起来.

而还有很多的游戏在设计时,为了减少服务器的负担,不但算法简单,还放松了很多的一些数据验证处理.最终漏洞百出,以致于产生了全屏吸怪,穿墙,复制,无敌等等各种变态外挂.

基本上游戏的加密解密算法,都是采用简单的位运算.位就是比特位,简单的说,只是二进制数据运算处理罢了.所以有必要了解一些常见的位运算汇编指令.在汇编那章的指令那节,有过一些指令的介绍,这里再介绍一下几个重中之重的指令.

加减指令

加法指令 ADD (ADD Binary Numbers Instruction)

指令的格式:ADD 寄存器/内存地址, 寄存器/内存地址/立即数 
受影响的标志位:AF、CF、OF、PF、SF和ZF 
指令的功能是把源操作数的值加到目的操作数中。

加1指令 INC (Increment by 1 Instruction)

指令的格式:INC 寄存器/内存地址 
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF 
指令的功能是把操作数的值加1。

减法指令 SUB (Subtract Binary Values Instruction)

指令的格式:SUB 寄存器/内存地址, 寄存器/内存地址/立即数 
受影响的标志位:AF、CF、OF、PF、SF和ZF 
指令的功能是从目的操作数中减去源操作数。

减1指令 DEC (Decrement by 1 Instruction)

指令的格式:DEC 寄存器/内存地址 
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF 
指令的功能是把操作数的值减去1。

乘法指令

计算机的乘法指令分为无符号乘法指令和有符号乘法指令,它们的唯一区别就在于:数据的最高位是作为“数值”参与运算,还是作为“符号位”参与运算。

乘法指令的被乘数都是隐含操作数,乘数在指令中显式地写出来。 CPU 会根据乘数是8位、16位,还是32位操作数,来自动选用被乘数: AL 、 AX 或 EAX 。

指令的功能是把显式操作数和隐含操作数相乘,并把乘积存入相应的寄存器中。

无符号数乘法指令 MUL (Unsigned Multiply Instruction)

指令的格式:MUL 寄存器/内存地址 
受影响的标志位:CF和OF(AF、PF、SF和ZF无定义) 
指令的功能是把显式操作数和隐含操作数(都作为无符号数)相乘,所得的乘积按下表的对应关系存放。

下表乘法指令中乘数、被乘数和乘积的对应关系

乘数位数

隐含的被乘数

乘积的存放位置

举例

8位

AL

AX

MUL BL

16位

AX

DX-AX

MUL BX

32位

EAX

EDX-EAX

MUL ECX

有符号数乘法指令 IMUL (Signed Integer Multiply Instruction)

指令的格式: IMUL 寄存器/内存地址 IMUL 寄存器, 立即数 IMUL 寄存器, 寄存器, 立即数 IMUL 寄存器, 寄存器/内存地址

受影响的标志位:CF和OF(AF、PF、SF和ZF无定义)

1)、指令格式1——该指令的功能是把显式操作数和隐含操作数相乘,所得的乘积按表5.2的对应关系存放。

2)、指令格式2——其寄存器必须是16位/32位通用寄存器,其计算方式为:

寄存器 ← 寄存器 × 立即数

3)、指令格式3——其寄存器只能是16位通用寄存器,其计算方式为:

寄存器 1 ← 寄存器 2 ×立即数 或 寄存器 1 ← 内存地址×立即数

4)、指令格式4——其寄存器必须是16位/32位通用寄存器,其计算方式为:

寄存器 1 ← 寄存器 1 ×寄存器 2 或 寄存器 1 ← 寄存器 1 ×内存地址

在指令格式2~4中,各操作数的位数要一致。如果乘积超过目标寄存器所能存储的范围,则系统将置溢出标志OF为1。

除法指令

除法指令的被除数是隐含操作数,除数在指令中显式地写出来。 CPU 会根据除数是8位、16位,还是32位,来自动选用被除数 AX 、 DX-AX ,还是 EDX-EAX 。

除法指令功能是用显式操作数去除隐含操作数,可得到商和余数。当除数为0,或商超出数据类型所能表示的范围时,系统会自动产生0号中断。

无符号数除法指令 DIV (Unsigned Divide Instruction)

指令的格式:DIV 寄存器/内存地址 
指令的功能是用显式操作数去除隐含操作数(都作为无符号数),所得商和余数按下表的对应关系存放。指令对标志位的影响无定义。

有符号数除法指令 IDIV (Signed Integer Divide Instruction)

指令的格式:IDIV 寄存器/内存地址 
受影响的标志位:AF、CF、OF、PF、SF和ZF

指令的功能是用显式操作数去除隐含操作数(都作为有符号数),所得商和余数的对应关系见表。?

下面表除法指令除数、被除数、商和余数的对应关系

除数位数

隐含的被除数

余数

举例

8位

AX

AL

AH

DIV BH

16位

DX-AX

AX

DX

DIV BX

32位

EDX-EAX

EAX

EDX

DIV ECX

逻辑运算指令

逻辑运算指令是另一组重要的指令,它包括:逻辑与( AND )、逻辑或( OR )、逻辑非( NOT )和异或指令( XOR ),逻辑运算指令也是经常使用的指令。

1、逻辑与操作指令AND(Logical AND Instruction)

指令的格式:AND 寄存器/内存地址, 寄存器/内存地址/立即数 
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义) 
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑“与操作”,操作结果存入目标操作数中。

例已知(BH)=67H,要求把其的第0、1和5位置为0。

解:可以构造一个立即数,其第0、1和5位的值为0,其它位的值为1,该立即数即为:0DCH或11011100B,然后用指令" AND BH, 0DCH "来实现此功能。

只有对应的1和1才等于1.其它全部为0 0和1=0 1和0=0 0和0=0

1

汇编 AND 指令等于易语言里的 位与() 和 模块里的 AND_() .

2 、逻辑或操作指令OR(Logical OR Instruction)

指令的格式:OR 寄存器/内存地址, 寄存器/内存地址/立即数 
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义) 
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑"或操作",操作结果存入目标操作数中。

例已知(BL)=46H,要求把其的第1、3、4和6位置为1。

解:构造一个立即数,使其第1、3、4和6位的值为1,其它位的值为0,该立即数即为:5AH或01011010B,然后用指令"OR BL, 5AH"来实现此功能。

只有对应的0和0才等于0.其它全部为1   0和1=1 1和0=1 1和1=1

1

汇编 OR 指令等于易语言里的 位或() 和 模块里的 OR_() .

3、逻辑非操作指令NOT(Logical NOT Instruction)

指令的格式:NOT 寄存器/内存地址 
其功能是把操作数中的每位变反,即:1←0,0←1。指令的执行不影响任何标志位。

例已知(AL)=46H,执行指令“NOT AL”后,AL的值是什么?

解:执行该指令后,(AL)=0B9H。该指令只是把二进制位反过来而已

1

汇编 NOT 指令等于易语言里的 位取反() 和 模块里的 NOT_() .

4、逻辑异或操作指令XOR(Exclusive OR Instruction)

指令的格式:XOR 寄存器/内存地址, 寄存器/内存地址/立即数 
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义) 
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑"异或操作",操作结果存入目标操作数中。

例已知(AH)=46H,要求把其的第0、2、5和7位的二进制值变反。

解:构造一个立即数,使其第0、2、5和7位的值为1,其它位的值为0,该立即数即为:0A5H或10100101B,然后再用指令"XOR AH, 0A5H"来实现此功能。

使用XOR运行后,只要对应的位相同时为0 0和0=0 1和1=0 对应两位不同时为1 0和1=1 1和0=1

1

汇编 XOR 指令等于易语言里的 位异或() 和 模块里的 XOR_() .


移位操作指令

移位操作指令是一组经常使用的指令,它包括 算术移位 、 逻辑移位 、 双精度移位 、 循环移位 和 带进位的循环移位 等五大类。

移位指令都有指定移动二进制位数的操作数,该操作数可以是立即数或CL的值。在8086中,该立即数只能为 1 ,但在其后的 CPU 中,该立即数可以是 1··31 之内的数。

、算术移位指令

算术移位指令有:算术左移 SAL (Shift Algebraic Left)和算术右移 SAR (Shift Algebraic Right)。它们的指令格式如下:

SAL/SAR 寄存器/内存地址, CL/立即数

受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。

算术移位指令的功能描述如下,具体功能下图(a)、(b)所示。

1算术左移 SAL 把目的操作数的低位向高位移,空出的低位补0; 
1算术右移 SAR 把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。

1

1

(a)、SAL (b)、SAR

例已知(AH)=12H,(BL)=0A9H,试给出分别用算术左移和右移指令移动1位后,寄存器AH和BL的内容。

解:用算术左移和右移指令移动1位后,寄存器AH和BL的结果如下表所示。

操作数的初值

执行的指令

执行后操作数的内容

(AH)=12H=10010B

SAL AH, 1

(AH)=24H=100100B

(BL)=0A9H=10101001B

SAL BL, 1

(BL)=52H=1010010B

(AH)=12H=10010B

SAR AH, 1

(AH)=09H=1001B

(BL)=0A9H=10101001B

SAR BL, 1

(BL)=0D4H=11010100B

汇编指令 SAL 指令等于易语言里的 左移() 和 模块里的 SAL_() SHL_().

汇编指令 SAR 指令在易语言里无对应函数 等于模块里的 SAR_() 函数.

但要注意模块里的 SAR_() 是以32位整数型来运算的,只等于汇编里的 SAR eax,1 这类的32位寄存器的运行结果.

若想以16位或8位来运算,需要先把符号位扩展到32位后再处理.

逻辑移位指令

此组指令有:逻辑左移 SHL (Shift Logical Left)和逻辑右移 SHR (Shift Logical Right)。它们的指令格式如下:

SHL/SHR 寄存器/内存地址, CL/立即数

受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。

逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补 。它们的具体功能下图(a)、(b)所示。

1

1

(a)、SHL (b)、SHR

例已知(AH)=12H,(BL)=0A9H,试给出分别用逻辑左移和右移指令移动1位后,寄存器AH和BL的内容。

解:用算术左移和右移指令移动1位后,寄存器AH和BL的结果如下表所示。

操作数的初值

执行的指令

执行后操作数的内容

(AH)=12H=10010B

SHL AH, 1

(AH)=24H=100100B

(BL)=0A9H=10101001B

SHL BL, 1

(BL)=52H=1010010B

(AH)=12H=10010B

SHR AH, 1

(AH)=09H=1001B

(BL)=0A9H=10101001B

SHR BL, 1

(BL)=54H=1010100B

汇编 SHL 指令等于易语言里的 左移() 和模块里的 SHL_() SAL_().

汇编 SHR 指令等于易语言里的 右移() 和模块里的 SHR_().

双精度移位指令

此组指令有:双精度左移SHLD(Shift Left Double)和双精度右移SHRD(Shift Right Double)。它们都是具有三个操作数的指令,其指令的格式如下:

SHLD/SHRD 寄存器/内存地址, 寄存器, CL/立即数    ;80386+

其中:第一操作数是一个16位/32位的寄存器或存储单元;第二操作数(与前者具有相同位数)一定是寄存器;第三操作数是移动的位数,它可由CL或一个立即数来确定。

在执行SHLD指令时,第一操作数向左移n位,其“空出”的低位由第二操作数的高n位来填补,但第二操作数自己不移动、不改变。

在执行SHRD指令时,第一操作数向右移n位,其“空出”的高位由第二操作数的低n位来填补,但第二操作数自己也不移动、不改变。

SHLD和SHRD指令的移位功能示意图如下图所示。

受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)

1

1

(a)、SHLD (b)、SHRD

双精度移位指令操作示意图

下面是几个双精度移位的例子及其执行结果。

双精度移位指令

指令操作数的初值

指令执行后的结果

SHLD AX, BX, 1

(AX)=1234H,(BX)=8765H

(AX)=2469H

SHLD AX, BX, 3

(AX)=1234H,(BX)=8765H

(AX)=91A4H

SHRD AX, BX, 2

(AX)=1234H,(BX)=8765H

(AX)=448DH

SHRD AX, BX, 4

(AX)=1234H,(BX)=8765H

(AX)=5123H

汇编 SHLD 与 SHRD 在易语言里暂无对应的函数,2.5模块里也没加上这两个函数.

循环移位指令

循环移位指令有:循环左移 ROL (Rotate Left)和循环右移 ROR (Rotate Right)。

指令的格式:ROL/ROR 寄存器/内存地址, CL/立即数

受影响的标志位:CF和OF

循环左移/右移指令只是移位方向不同,它们移出的位不仅要进入CF,而且还要填补空出的位。具体功能如下图(a)、(b)所示。

1 1

(a)、ROL

(b)、ROR

下面是几个循环移位的例子及其执行结果。

循环移位指令

指令操作数的初值

指令执行后的结果

ROL AX, 1

(AX)=6789H=110011110001001B

(AX)=0CF12H=1100111100010010B

ROL AX, 3

(AX)=6789H=110011110001001B

(AX)=3C4BH=11110001001011B

ROR AX, 2

(AX)=6789H=110011110001001B

(AX)=59E2H=101100111100010B

ROR AX, 4

(AX)=6789H=110011110001001B

(AX)=9678H=1001011001111000B

汇编 ROL 在易语言里无对应函数,模块里提供了 ROL_().

汇编 ROR 在易语言里无对应函数,模块里提供了 ROR_().

带进位的循环移位指令

带进位的循环移位指令有:带进位的循环左移 RCL (Rotate Left Through Carry)和带进位的循环右移 RCR (Rotate Right)。

指令的格式:RCL/RCR 寄存器/内存地址, CL/立即数

受影响的标志位:CF和OF

带进位的循环左移/右移指令只有移位的方向不同,它们都用原CF的值填补空出的位,移出的位再进入CF。具体功能如下图(a)、(b)所示。

1 1 (a)、RCL (b)、RCR

下面是几个带进位循环移位的例子及其执行结果。

双精度移动指令

指令操作数的初值

指令执行后的结果

RCL AX, 1

CF=0,(AX)=0ABCDH=1010101111001101B

(AX)=579AH=101011110011010B

RCL AX, 1

CF=1,(AX)=0ABCDH=1010101111001101B

(AX)=579BH=101011110011011B

RCR AX, 2

CF=0,(AX)=0ABCDH=1010101111001101B

(AX)=AAF3H=1010101011110011B

RCR AX, 2

CF=1,(AX)=0ABCDH=1010101111001101B

(AX)=EAF3H=1110101011110011B

汇编 RCL 在易语言里无对应函数,模块里提供了 RCL_().

汇编 RCR 在易语言里无对应函数,模块里提供了 RCR_().

本文重新介绍了这些将在封包算法里将常用到的汇编指令..大家要尽量记住这些指令的运算方式.

最多被用到的指令主要有 XOR-位异或 ,ROL-左循环移位 ,ROR-右循环移位 ,AND-位与 ,OR-位或 ,SHL-左移 ,SHR-右移 ,NOT-位取反.其它加减乘除,算术移位等用到的机率很少..

有些算法指令在易语言里也有对应的函数,或者模块里也有提供了这些功能,不过需要注意的是目前2.5模块里提供的这几个功能是按32位运算的.大家在使用时要注意.有关相应的8位与16位运算的函数下版时会增加上去.

原文地址:https://www.cnblogs.com/chenjian/p/3543588.html