在上一篇的跟踪中,调试后发现二次加密的密匙其实就是一个常量008B480C,分析一下整个二次加密的过程,以下代码均在VC6.0中运行通过,加密后数据与客户端实际发送数据一致。
函数1 - _declspec(naked) void _stdcall getEncryptMsg(long *nIdentity, char * dest)
nIdentity - 008B480C
dest - 二次加密明文
该函数负责生成二次加密后的明文,代码如下
注意:第13行是原来的代码,14行是自己加的,原因如下
在实际的客户端中,mov al, byte ptr [eax] 取的是地址为008B480C的低8位,调试的时候该值为0,有可能二次解密后的解密掩码会存放在这里,目前还未可知;而在该代码中008B480C的地址是不可读的,因此这里需要将AL置0
static long nIdentity = 0x008B480C;
1
_declspec(naked) void _stdcall getEncryptMsg(long *nIdentity, char * dest)
{
2
_asm
{
3
sub esp, 8
4
push ebx
5
push ebp
6
push esi
7
push edi
8
mov edi, dword ptr [esp+0x20]
9
inc edi
10
mov dword ptr [esp+0x14], 4
11
L008:
12
mov eax, dword ptr [esp+0x1C]
13
;mov al, byte ptr [eax]
14
xor al, al
15
xor al, 0x87
16
push 0x31
17
push 0
18
mov byte ptr [esp+0x1B], al
19
call ll401A60
20
add al, 0x0A
21
push 0x13
22
push 0
23
mov byte ptr [esp+0x30], al
24
call ll401A60
25
26
mov cl, byte ptr [esp+0x30]
27
28
mov ebx, eax
29
add bl, 0x0A
30
movzx eax, bl
31
add esp, 0x10
32
mov byte ptr [edi-1], cl
33
mov byte ptr [edi+8], bl
34
xor esi, esi
35
lea ebp, dword ptr [eax-1]
36
L029:
37
movzx eax, byte ptr [esp+0x13]
38
mov edx, 0x80
39
mov ecx, esi
40
sar edx, cl
41
push ebp
42
push 0
43
test eax, edx
44
jnz L039
45
call ll401A60
46
jmp L041
47
L039:
48
call ll401A60
49
add al, bl
50
L041:
51
add al, byte ptr [esp+0x28]
52
add esp, 8
53
mov byte ptr [edi+esi], al
54
inc esi
55
cmp esi, 8
56
jl L029
57
mov edx, dword ptr [esp+0x1C]
58
mov eax, dword ptr [esp+0x14]
59
inc edx
60
add edi, 0x0A
61
dec eax
62
mov dword ptr [esp+0x1C], edx
63
mov dword ptr [esp+0x14], eax
64
jnz L008
65
pop edi
66
pop esi
67
pop ebp
68
pop ebx
69
add esp, 8
70
retn 8
71
72
}
73
}
---------------------------------------------------------------------------------------------------------
函数2 - _declspec(naked) int _cdecl _ll401A60(int a1, int a2)
该函数负责生成一个伪随机数
_declspec(naked) int _cdecl _ll401A60(int a1, int a2)


{


_asm
{
push esi
push edi
call ll4bb903
mov esi, eax
call ll4bb903
sub esi, eax
jns L008
neg esi
L008:
mov ecx, dword ptr [esp+0xC]
mov edi, dword ptr [esp+0x10]
mov eax, esi
sub edi, ecx
cdq
inc edi
idiv edi
pop edi
pop esi
mov eax, edx
add eax, ecx
retn
}
}
---------------------------------------------------------------------------------------------------------
函数3 - _declspec(naked) int _cdecl ll4bb903()
该函数根据客户端启动时生成的当前时间来进行随机数生成(这个步骤调试2个小时才出来)
long int_4D4F78 = 0x484953AE; //客户端启动时的当前时间

_declspec(naked) int _cdecl ll4bb903()


{

_asm
{
mov eax, dword ptr [int_4D4F78]
imul eax, eax, 0x343FD
add eax, 0x269EC3
mov dword ptr [int_4D4F78], eax
xor eax, eax
mov ax, word ptr [int_4D4F78+2]
and eax, 0x7FFF
retn
}
}
运行的Main函数如下,客户端在启动时执行了5次ll4bb903,因此这里也执行5次,不过服务器端也不可能知道客户端到底什么时候启动的,所以未必一定要执行5次,这点还没试

void encodeTest()
{

//执行5次ll4bb903()
ll4bb903();
ll4bb903();
ll4bb903();
ll4bb903();
ll4bb903();

long * ll = (long*)0x008b480c;
ll = 0;

char dest[40];
getEncryptMsg(&nIdentity, dest);
printf("%s\n", dest);

char idest[54];
fnEncode6BitBuf(dest, idest, 40, 54);
printf("%s\n", idest);
}
以上代码转成JAVA代码如下:

public class DecodeMask
{

private static int int_4D4F78 = 0x484953AE; // 系统当前时间,不包含毫秒
private static long nIdentity = 0x008B480C; // 常量


private static int ll4bb903()
{
int_4D4F78 = int_4D4F78 * 0x343FD + 0x269EC3;
int r = (int_4D4F78 >> 16) & 0x7FFF; //这里取高16位
return r;
}


private static int ll401A60(int nFrom, int nTo)
{
int nRandNum = 0;
int nRand = (ll4bb903() - ll4bb903());
if (nRand < 0)
nRand = -nRand;
nRandNum = nRand % (nTo - nFrom + 1) + nFrom;
return nRandNum;
}


private static byte[] getEncryptMsg()
{
byte[] dest = new byte[40];
int pos = 1;

for (int i = 0; i < 4; i++)
{

byte bMax = (byte) (ll401A60(0, 0x31) + 0x0A);
byte bMin = (byte) (ll401A60(0, 0x13) + 0x0A);

dest[pos - 1] = bMax;
dest[pos + 8] = bMin;


for (int j = 0; j < 8; j++)
{
int bT = 0x80 >> j;
byte _b = (byte) ll401A60(0, bMin - 1);

if ((bT & 0x87) != 0)
{
_b += bMin;
}
dest[pos + j] = (byte) (_b + bMax);
}
nIdentity++;
pos += 0x0a;
}

return dest;
}


/** *//**
* 调试: 客户端启动时的当前时间为 0x484953AE
* 选择角色进入游戏时,客户端向服务器端实际发送数据为
* #3<<<<<Jx?<<<<<<<<E`\cFo<mO@Q?A=ToC]\YE_DnGMDfQ_Q@IPIOMqLW?oPS?mD_E>dtAL!
* 该方法运行后的正确输出应为:
* E`\cFo<mO@Q?A=ToC]\YE_DnGMDfQ_Q@IPIOMqLW?oPS?mD_E>dtAL
*/

public static void doTest()
{
// 执行5次ll4bb903()
ll4bb903();
ll4bb903();
ll4bb903();
ll4bb903();
ll4bb903();
byte[] b = getEncryptMsg();
System.out.println("二次加密明文 - [" + new String(b) + "]");
String s = PacketEncode.fnEncode6BitBuf(b);
System.out.println("二次加密密文 - [" + s + "]");
}


/** *//**
* @param args
*/

public static void main(String[] args)
{
doTest();
}

}
posted on 2008-06-07 10:20
Phrancol Yang 阅读(701)
评论(3) 编辑 收藏 所属分类:
反汇编