原帖地址:http://bbs.pediy.com/showthread.php?t=37109
VC源码Part1
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
extern unsigned int Key4;
extern unsigned int Key3;
extern unsigned int Key2;
extern unsigned int Key1;
extern void Decrypt(unsigned int *ebx, unsigned int *edi);
/* input: 8 bytes long */
int blowfish_decrypt(char *pIn, char *key, char *pOut)
{
unsigned int ebx, edi;
Key4 = *(int *)key;
Key3 = *(int *)(key+4);
Key2 = *(int *)(key+8);
Key1 = *(int *)(key+12);
Key1 = ntohl(Key1);
Key2 = ntohl(Key2);
Key3 = ntohl(Key3);
Key4 = ntohl(Key4);
ebx = *(unsigned int *)(pIn+0);
edi = *(unsigned int *)(pIn+4);
ebx = ntohl(ebx);
edi = ntohl(edi);
Decrypt(&ebx, &edi);
ebx = ntohl(ebx);
edi = ntohl(edi);
memcpy(pOut, &ebx, 4);
memcpy(pOut+4, &edi, 4);
//MsgEx_DumpHex(pOut, 8);
return 0;
}
/* total_len: len of pOut, should be given at calling */
int QQMSG_decode(char *pIn, int len, char *key, char *pOut, int *total_len)
{
int n;
char *pEdi; //原始指针,指向前8个字节
char *pLocal; //前驱指针,指向后8个字节
int BLOCK_LEN=8;
int count=0;
int offset = 0;
char *pbuffer;
char buffer[8];
char ebx_edi[8];
char cl=0;
int i=0;
int retLen;
if((len % 8) != 0)
return -1;
if(len < 0x10)
return -1;
n = len;
pLocal = pIn;
blowfish_decrypt(pIn, key, ebx_edi);
cl = *ebx_edi;
cl &= 0x7;
n -= cl;
n -= 0xa;
if(*total_len < n)
return -1;
if(n == 0)
return -1;
*total_len = n;
retLen = n;
n=0;
offset = BLOCK_LEN;
memset(buffer, 0, 8);
pEdi = pIn;
pLocal += BLOCK_LEN;
pbuffer = buffer;
n = cl+1;
count = 1;
while(count <= 2)
{
if(n < BLOCK_LEN)
{
n++;
count++;
continue;
}
if(n != BLOCK_LEN)
continue;
pbuffer = pEdi; //pIn
pIn = pLocal;
/* xor ebx_edi with bytes afterward */
for(i=0; i < BLOCK_LEN; i++)
{
char *p;
if((offset+i) >= len)
return -1;
p = pLocal+i;
cl = *p;
p = ebx_edi+i;
(*p) ^= cl;
}
/* compute new ebx_edi */
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset += BLOCK_LEN;
pEdi = pLocal;
pLocal += BLOCK_LEN;
n = 0;
};
//end of while
if(*total_len == 0)
goto final_process;
while(*total_len != 0)
{
char *p;
if(n < BLOCK_LEN){
p = pOut;
cl = *(char*)(pbuffer+n);
cl ^= *(char*)(ebx_edi+n);
pOut++;
n++;
(*total_len)--;
*p = cl;
continue;
}
if(n != BLOCK_LEN)
continue;
pbuffer = pEdi;
pIn = pLocal;
i = 0;
/* xor ebx_edi with bytes afterward */
do{
if((offset+i) >= len)
return -1;
cl = *(pLocal+i);
*(ebx_edi+i) ^= cl;
i++;
}while(i<BLOCK_LEN);
/* compute new ebx_edi */
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset += BLOCK_LEN;
pEdi = pLocal;
pLocal += BLOCK_LEN;
n = 0;
}//end of while
final_process:
count = 1;
do{
if(n < BLOCK_LEN){
char *p;
p = pOut;
cl = *(char*)(pbuffer+n);
cl ^= *(char*)(ebx_edi+n);
if(cl != 0)
return -1;
n++;
count++;
continue;
}
if(n != BLOCK_LEN)
continue;
pbuffer = pEdi;
pIn = pLocal;
i = 0;
do{
if((offset+i) >= len)
return -1;
cl = *(pLocal+i);
*(ebx_edi+i) ^= cl;
i++;
}while(i<BLOCK_LEN);
/* compute new ebx_edi */
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset += BLOCK_LEN;
pEdi = pLocal;
pLocal += BLOCK_LEN;
n = 0;
}while(count < 7);
*total_len = retLen;
return 0;
}
Part2
#define F_FUNCTION(x, k1, k2, c) ((((x) >> 5) + (k1)) ^ (((x) << 4) + (k2)) ^ ((c) +(x)))
#define C_BLOWFISH 16
unsigned int Key4 = 0;
unsigned int Key3 = 0;
unsigned int Key2 = 0;
unsigned int Key1 = 0;
//软件里面的解密运算过程
//注意:编译器会将有符号数的右移翻译成SAR指令,而我们需要的是SHR指令,所以必须定义成无符号数
void Decrypt(unsigned int *ebx, unsigned int *edi)
{
int C1 = 0xE3779B90;
int k = 0;
for(k = 0 ; k < C_BLOWFISH; k++)
{
*edi -= F_FUNCTION((*ebx), Key1, Key2, C1);
*ebx -= F_FUNCTION((*edi), Key3, Key4, C1);
C1 += 0x61C88647;
}
}
//上面的函数的逆
void Encrypt(unsigned int *edx, unsigned int *ebx)
{
int C1 = 0x00000000;
int k=0;
for(k = 0 ; k < C_BLOWFISH; k++)
{
C1 -= 0x61C88647;
(*edx) += F_FUNCTION((*ebx), Key3, Key4, C1);
*ebx += F_FUNCTION((*edx), Key1, Key2, C1);
}
}
我转的Delphi代码:unit QQmsg_Decode;
interface
uses
winsock,windows;
function blowfish_decrypt(pIn:pChar; key:pChar;pOut:pChar):integer;
function QQMSGdecode(pIn:pchar;len:integer;key:pchar; pOut:pchar;total_len:pInteger):integer;
procedure Decrypt(ebx,edi:pCardinal);
procedure Encrypt(edx,ebx:pCardinal);
implementation
var
Key1,Key2,Key3,Key4:Cardinal;
const
C_BLOWFISH=16;
function F_FUNCTION(x, k1, k2, c:Cardinal):Cardinal;
begin
result:=((((x) shr 5) + (k1)) xor (((x) shl 4) + (k2)) xor ((c) +(x)))
end;
function blowfish_decrypt(pIn:pChar; key:pChar;pOut:pChar):integer;
var
ebx:Cardinal;
edi:Cardinal;
temp_p:pChar;
begin
Key4 := pinteger(key)^;
temp_p:=key+4;
Key3 := pinteger(temp_p)^;
temp_p:=key+8;
Key2 := pinteger(temp_p)^;
temp_p:=key+12;
Key1 := pinteger(temp_p)^;
Key1 := ntohl(Key1);
Key2 := ntohl(Key2);
Key3 := ntohl(Key3);
Key4 := ntohl(Key4);
ebx := PCardinal(pIn)^;
temp_p:=pIn+4;
edi := pCardinal(temp_p)^;
ebx := ntohl(ebx);
edi := ntohl(edi);
Decrypt(@ebx, @edi);
ebx := ntohl(ebx);
edi := ntohl(edi);
CopyMemory(pOut, @ebx, 4);
temp_p:= pOut+4;
CopyMemory(temp_p, @edi, 4);
result:= 0;
end;
function QQMSGdecode(pIn:pchar;len:integer;key:pchar; pOut:pchar;total_len:pInteger):integer;
var
n,BLOCK_LEN,i,retLen,offset,count:integer;
pEdi,pLocal,pbuffer,p,temp_p:pChar;
buffer,ebx_edi:array[0..7] of char;
cl:char;
begin
BLOCK_LEN:=8;
i:=0;
offset:=0;
count:=0;
cl:=chr(0);
if((len mod 8) <> 0) then
begin
result:= -1;
exit;
end;
if(len < $10) then
begin
result:= -1;
exit;
end;
n := len;
pLocal := pIn;
blowfish_decrypt(pIn, key, @ebx_edi);
cl := ebx_edi[0];
cl :=Chr(ord(cl) and $7);
n :=n - ord(cl);
n :=n - $a;
if(total_len^ < n)then
begin
result:= -1;
exit;
end;
if(n = 0)then
begin
result:= -1;
exit;
end;
total_len^ := n;
retLen := n;
n:=0;
offset := BLOCK_LEN;
zeromemory(@buffer,8);
pEdi := pIn;
pLocal :=pLocal+ BLOCK_LEN;
pbuffer := buffer;
n := ord(cl)+1;
count := 1;
while(count <= 2) do
begin
if(n < BLOCK_LEN) then
begin
inc(n);
inc(count);
continue;
end;
if(n <> BLOCK_LEN) then
continue;
pbuffer := pEdi; //pIn
pIn := pLocal;
for i:=0 to BLOCK_LEN -1 do
begin
if((offset+i) >= len)then
begin
result:= -1;
exit;
end;
p := pLocal+i;
cl := p^;
p := ebx_edi+i;
p^ :=Chr(ord(p^) xor ord(cl));
end;
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset :=offset+ BLOCK_LEN;
pEdi := pLocal;
pLocal :=pLocal+ BLOCK_LEN;
n := 0;
end;
//end of while
if(total_len^ <> 0) then
while(total_len^ <> 0)do
begin
if(n < BLOCK_LEN)then
begin
p := pOut;
temp_p:=pbuffer+n;
cl := pchar(temp_p)^;
temp_p:=pbuffer+n;
cl :=chr(ord(cl) xor ord(pchar(temp_p)^));
inc(pOut);
inc(n);
dec(total_len^);
p^ := cl;
continue;
end;
if(n <> BLOCK_LEN) then
continue;
pbuffer := pEdi;
pIn := pLocal;
i := 0;
repeat
if((offset+i) >= len)then
begin
result:= -1;
exit;
end;
p := pLocal+i;
cl := p^;
p := ebx_edi+i;
p^ :=Chr(ord(p^) xor ord(cl));
inc(i);
until (i>=BLOCK_LEN);
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset :=offset+ BLOCK_LEN;
pEdi := pLocal;
pLocal :=pLocal+ BLOCK_LEN;
n := 0;
end;//end of while
count := 1;
repeat
if(n < BLOCK_LEN)then
begin
p := pOut;
temp_p:=pbuffer+n;
cl := pchar(temp_p)^;
temp_p:=pbuffer+n;
cl :=chr(ord(cl) xor ord(pchar(temp_p)^));
if(ord(cl) <> 0)then
begin
result:= -1;
exit;
end;
inc(n);
inc(count);
continue;
end;
if(n <> BLOCK_LEN) then
continue;
pbuffer := pEdi;
pIn := pLocal;
i := 0;
repeat
if((offset+i) >= len) then
begin
result:= -1;
exit;
end;
p := pLocal+i;
cl := p^;
p := ebx_edi+i;
p^ :=Chr(ord(p^) xor ord(cl));
inc(i);
until(i>=BLOCK_LEN);
blowfish_decrypt(ebx_edi, key, ebx_edi);
offset := offset+BLOCK_LEN;
pEdi := pLocal;
pLocal :=pLocal+ BLOCK_LEN;
n := 0;
until(count >= 7);
total_len^ := retLen;
result:= 0;
end;
procedure Decrypt(ebx,edi:pCardinal);
var
C1: Cardinal;
k :integer;
begin
C1 := $E3779B90;
for k:= 0 to C_BLOWFISH -1 do
begin
edi^ := edi^ - F_FUNCTION((ebx^), Key1, Key2, C1);
ebx^ := ebx^ - F_FUNCTION((edi^), Key3, Key4, C1);
C1 := C1 + $61C88647;
end;
end;
//上面的函数的逆
procedure Encrypt(edx,ebx:pCardinal);
var
C1: integer;
k :integer;
begin
C1 := $0;
for k:= 0 to C_BLOWFISH -1 do
begin
C1 := C1 - $61C88647;
edx^ := edx^ + F_FUNCTION((ebx^), Key3, Key4, C1);
ebx^ := ebx^ + F_FUNCTION((edx^), Key1, Key2, C1);
end;
end;
end.
问题如下:转了编译后delphi程序可正常执行,但是调用QQMSGdecode返回的结果不对!是不是哪里错了,哪位大侠帮小弟看看呵..
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课