pcqq协议 0836中有一个official算法,貌似和稳定性有关,汇编代码为 mov eax, [ebp+0Ch] mov eax, [eax] add eax, 08h push eax mov edx, [ebp+08h] mov edx, [edx] add edx, 08h mov ecx, [ebp+10h] mov ecx, [ecx] add ecx, 08h call 00000024Ch
mov esp, ebp pop ebp retn 000Ch
sub esp, 14h mov eax, [edx] push ebx mov [esp+14h], ecx mov ebx, 00000010h mov ecx, [esp+1Ch] push ebp push esi mov esi, [edx+04h] mov edx, [ecx+04h] mov [esp+0Ch], edx mov edx, [ecx] mov ebp, [esp+0Ch] mov [esp+10h], edx mov edx, [ecx+0Ch] mov ecx, [ecx+08h] push edi bswap esi bswap eax mov edi, 9E3779B9h mov [esp+1Ch], edx mov [esp+18h], ecx mov edx, esi mov ecx, esi shr edx, 05h shl ecx, 04h add edx, ebp add ecx, [esp+14h] xor edx, ecx lea ecx, [esi+edi] xor edx, ecx add eax, edx mov edx, eax mov ecx, eax shl edx, 04h add edx, [esp+18h] shr ecx, 05h add ecx, [esp+1Ch] xor edx, ecx lea ecx, [eax+edi] xor edx, ecx lea edi, [edi-61C88647h] add esi, edx dec ebx jne 00000041h mov ebp, [esp+20h] bswap esi pop edi bswap eax mov [ebp+04h], esi mov [ebp+00h], eax mov eax, ebp pop esi pop ebp pop ebx add esp, 14h retn 0004h
翻译成c++: #include "stdafx.h"
typedef unsigned char BYTE;
BYTE* Long2Bytes(unsigned long n); unsigned long Bytes2Long(BYTE *bytes); BYTE* ReverseBytes(BYTE* data, int size); void Official(BYTE *data, BYTE *key, BYTE *result); BYTE* SubBytes(BYTE *bytes, int start, int count); void PrintBytes(BYTE *bytes, int size);
int _tmain(int argc, _TCHAR* argv[]) { BYTE *data = new BYTE[8]{1, 2, 3, 4, 5, 6, 7, 8};//要加密的数据 BYTE *key = new BYTE[16]{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};//加密key BYTE *result = new BYTE[8]{0};//加密结果 Official(data, key, result); PrintBytes(result,8); delete[] data; delete[] key; delete[] result; getchar(); return 0; } void PrintBytes(BYTE *bytes, int size){ for (int i = 0; i < size; i++){ printf("%d ",bytes); } } void Official(BYTE *data, BYTE *key, BYTE *result){ unsigned long eax = Bytes2Long(SubBytes(data,0,4)); unsigned long esi = Bytes2Long(SubBytes(data, 4, 4)); unsigned long var4 = Bytes2Long(ReverseBytes(SubBytes(key, 0, 4), 4)); unsigned long ebp = Bytes2Long(ReverseBytes(SubBytes(key, 4, 4), 4)); unsigned long var3 = Bytes2Long(ReverseBytes(SubBytes(key, 8, 4), 4)); unsigned long var2 = Bytes2Long(ReverseBytes(SubBytes(key, 12, 4), 4)); //printf("%lu %lu %lu %lu %lu %lu\n", eax,esi,var4, ebp, var3, var2);
unsigned long edi = 0x9E3779B9; unsigned long edx = 0; unsigned long ecx = 0; for (int i = 0; i < 16; i++){ edx = esi; ecx = esi; edx = edx >> 5; ecx = ecx << 4; edx += ebp; ecx += var4; edx = edx ^ ecx; ecx = esi + edi; edx = edx ^ ecx; eax += edx; edx = eax; ecx = eax; edx = edx << 4; edx = edx + var3; ecx = ecx >> 5; ecx += var2; edx = edx ^ ecx; ecx = eax + edi; edx = edx ^ ecx; edi -= 0x61C88647; esi += edx; } memcpy(result,Long2Bytes(eax), 4); memcpy(result+4, Long2Bytes(esi), 4); } BYTE* Long2Bytes(unsigned long n){ BYTE *temp = new BYTE[4]; temp[0] = n / 16777216; temp[1] = (n - temp[0] * 16777216)/65536; temp[2] = (n - temp[0] * 16777216 - temp[1] * 65536) / 256; temp[3] = (n - temp[0] * 16777216 - temp[1] * 65536-temp[2]*256); return temp; } unsigned long Bytes2Long(BYTE *bytes){ unsigned long a =bytes[0] * 16777216; unsigned long b = bytes[1] * 65536; unsigned long c = bytes[2] * 256; unsigned long d = bytes[3]; unsigned long n = a + b + c + d; return n; } //因为数据在内存中是从低到高存放的,所以要反取字节 BYTE* ReverseBytes(BYTE* bytes, int size){ BYTE *temp = new BYTE[size]; for (int i = 0; i < size; i++){ temp = bytes[size - i - 1]; } return temp; } BYTE* SubBytes(BYTE* bytes, int start, int count){ BYTE *temp = new BYTE[count]; for (int i = 0; i < count; i++){ temp = bytes[start + i]; } return temp; }
|