前段时间研究一种加密代理软件,其中使用了多种加密算法,在和服务器协商 密钥的过程中遇到了以下的一种算法,特此发贴请教。
明文是64字节的 ,经过加密函数F1() 32轮处理,将明文散列成128字节的数据,然后调用加密函数F2 () 将上面的128字节的数据有压缩成64字节的,经过总16轮的处理后输出64字节的密文。 表达不是很清楚,直接看代码吧。随手写的代码 高手别见笑。
// 以下是将128字节聚合成64字节的处理函数代码
/*----------------------------------------------------------------------------------
0041F0BF 90 nop ; 6个参数 主要串入 表地址 和B数据
0041F0C0 8B4424 0C mov eax, [esp+C] ; 加密表地址 固定
0041F0C4 8B4C24 10 mov ecx, [esp+10] ; 20 长度
0041F0C8 83EC 14 sub esp, 14
0041F0CB 83F9 01 cmp ecx, 1
0041F0CE 53 push ebx
0041F0CF 66:8B18 mov bx, [eax] ; 取头2位数据
0041F0D2 55 push ebp
0041F0D3 56 push esi
0041F0D4 7E 0B jle short 0041F0E1
0041F0D6 66:8B40 02 mov ax, [eax+2] ; 取后头2位
0041F0DA 66:894424 10 mov [esp+10], ax
0041F0DF EB 08 jmp short 0041F0E9
0041F0E1 C74424 10 00000>mov dword ptr [esp+10], 0
0041F0E9 8B4424 28 mov eax, [esp+28] ; 21
0041F0ED 33F6 xor esi, esi
0041F0EF 33ED xor ebp, ebp
0041F0F1 2BC1 sub eax, ecx
0041F0F3 894424 1C mov [esp+1C], eax ; 保存21-20 =1
0041F0F7 0F88 82010000 js 0041F27F
0041F0FD 81E3 FFFF0000 and ebx, 0FFFF ; 头数据和 0xFFFF 取底位数据
0041F103 57 push edi
0041F104 895C24 18 mov [esp+18], ebx
0041F108 EB 06 jmp short 0041F110
0041F10A 8B5C24 18 mov ebx, [esp+18] ; 取加密表头数据
0041F10E 33F6 xor esi, esi ; 清ESI 0
0041F110 3BEE cmp ebp, esi
0041F112 75 0A jnz short 0041F11E
0041F114 8B4C24 28 mov ecx, [esp+28] ; ECX保存 散列数据地址
0041F118 897424 10 mov [esp+10], esi
0041F11C EB 14 jmp short 0041F132
0041F11E 8B4C24 28 mov ecx, [esp+28] ; 保存128位 数据表首地址
0041F122 33C0 xor eax, eax ; 晴空 EAX 0
0041F124 66:8B4469 FE mov ax, [ecx+ebp*2-2] ; 取数据表中当前值(前64位数据)
0041F129 66:897469 FE mov [ecx+ebp*2-2], si ; 清掉数据该位数据 值保存到 EAX
0041F12E 894424 10 mov [esp+10], eax ; 将该数据保存到esp+10
0041F132 8B5424 2C mov edx, [esp+2C] ; 40H 长度
0041F136 8D42 FF lea eax, [edx-1] ; 20 3F
0041F139 3BE8 cmp ebp, eax
0041F13B 74 07 je short 0041F144 ; 以下假设128字节开头数据形势xx1表示开始xx127最后一个
0041F13D 33F6 xor esi, esi ; 128字节表开始是散列最后一次的完整数据
0041F13F 66:8B7469 02 mov si, [ecx+ebp*2+2] ; 当前数据表头取xx3 xx1(散列的高位) xx2(散列的低位) xx3
0041F144 8B4424 10 mov eax, [esp+10] ; xx1保存 EAX
0041F148 3BC3 cmp eax, ebx
0041F14A 72 07 jb short 0041F153
0041F14C BF FFFF0000 mov edi, 0FFFF
0041F151 EB 56 jmp short 0041F1A9
0041F153 33D2 xor edx, edx
0041F155 66:8B1469 mov dx, [ecx+ebp*2] ; 当前计算的值xx2
0041F159 8BCA mov ecx, edx ; 当前值保存到ECX
0041F15B 33D2 xor edx, edx ; 清EDX 0
0041F15D C1E0 10 shl eax, 10 ; 将地位转换成高位
0041F160 0BC8 or ecx, eax ; 高低位合并
0041F162 8BC1 mov eax, ecx ; 结果保存到EAX
0041F164 F7F3 div ebx ; EAX / EBX 结果保存到EBX
0041F166 33D2 xor edx, edx
0041F168 8BF8 mov edi, eax
0041F16A 8BC1 mov eax, ecx
0041F16C F7F3 div ebx ; 77BF6737
0041F16E 8B4C24 14 mov ecx, [esp+14]
0041F172 81E1 FFFF0000 and ecx, 0FFFF ; 该值固定 6737
0041F178 8BC1 mov eax, ecx ; 6737
0041F17A 0FAFC7 imul eax, edi ; EAX保存 6737*上面的除商
0041F17D 8BDA mov ebx, edx ; 保存 除法的余
0041F17F C1E3 10 shl ebx, 10 ; 将余移至 高位
0041F182 03DE add ebx, esi ; 将值和表中下一位数据相加
0041F184 3BC3 cmp eax, ebx ; 数据代号 A1
0041F186 76 1D jbe short 0041F1A5
0041F188 8B5C24 18 mov ebx, [esp+18] ; 取当前加密表数据
0041F18C 4F dec edi ; 上面的商-1 = C1
0041F18D 03D3 add edx, ebx ; 将余+当前加密表数据
0041F18F 81E2 FFFF0000 and edx, 0FFFF ; 只取地位
0041F195 3BD3 cmp edx, ebx ; 到此 数据代号 B1
0041F197 72 0C jb short 0041F1A5
0041F199 C1E2 10 shl edx, 10 ; 将B1置高位 = B2
0041F19C 03D6 add edx, esi ; B2+数据表后一位的数据 =B3
0041F19E 2BC1 sub eax, ecx ; (低位)A1 - B3 保存到 EAX
0041F1A0 3BC2 cmp eax, edx
0041F1A2 76 01 jbe short 0041F1A5
0041F1A4 4F dec edi
0041F1A5 8B4C24 28 mov ecx, [esp+28] ; B数据地址
0041F1A9 8B4424 34 mov eax, [esp+34] ; 20
0041F1AD 33DB xor ebx, ebx
0041F1AF 48 dec eax
0041F1B0 85C0 test eax, eax
0041F1B2 7C 46 jl short 0041F1FA
0041F1B4 8B5424 30 mov edx, [esp+30] ; 以下比较关键
0041F1B8 8D3442 lea esi, [edx+eax*2] ; 取加密表最后数据
0041F1BB 8D1428 lea edx, [eax+ebp]
0041F1BE 40 inc eax ; eax+1 = 0x20
0041F1BF 8D1451 lea edx, [ecx+edx*2] ; 指向128字节的64字节处
0041F1C2 894424 1C mov [esp+1C], eax ; eax保存到参数总
0041F1C6 33C0 xor eax, eax ; 清一下EAX 一般此刻保存的是记数器的值
0041F1C8 66:8B06 mov ax, [esi] ; 最后开始加密表2字节 D1
0041F1CB 0FAFC7 imul eax, edi ; D1*C1 保存到EAX = D2
0041F1CE 03C3 add eax, ebx ; 上一次计算的高位数据值 有可能+1看下面的计算
0041F1D0 8BC8 mov ecx, eax ; 结果保存到 ECX
0041F1D2 C1E9 10 shr ecx, 10 ; 取高位
0041F1D5 8BD9 mov ebx, ecx ; 保存到 EBX 高位数据
0041F1D7 66:8B0A mov cx, [edx] ; A数据散列后的后64/64 根据计算的目的不同而不同
0041F1DA 66:3BC1 cmp ax, cx ; E1
0041F1DD 76 01 jbe short 0041F1E0 ; ax < cx jmp
0041F1DF 43 inc ebx ; EBX+1 下回运算时使用
0041F1E0 2BC8 sub ecx, eax ; E1 - D2 结果保存到ECX
0041F1E2 8B4424 1C mov eax, [esp+1C] ; 20--
0041F1E6 66:890A mov [edx], cx ; 取低位 写入当前数据表
0041F1E9 83EE 02 sub esi, 2 ; 加密表和数据表指向下一个处理的位置
0041F1EC 83EA 02 sub edx, 2
0041F1EF 48 dec eax ; 记数器 - 1
0041F1F0 894424 1C mov [esp+1C], eax ; esp+1c保存当前的记数器值
0041F1F4 ^ 75 D0 jnz short 0041F1C6 ; 继续处理
0041F1F6 8B4C24 28 mov ecx, [esp+28] ; B数据地址
0041F1FA 3B5C24 10 cmp ebx, [esp+10]
0041F1FE 74 49 je short 0041F249 ; 跳上去 循环
0041F200 8B5424 34 mov edx, [esp+34]
0041F204 33C0 xor eax, eax
0041F206 8D72 FF lea esi, [edx-1]
0041F209 85F6 test esi, esi
0041F20B 7C 3B jl short 0041F248
0041F20D 8B5424 30 mov edx, [esp+30]
0041F211 8D1472 lea edx, [edx+esi*2]
0041F214 03F5 add esi, ebp
0041F216 8D0C71 lea ecx, [ecx+esi*2]
0041F219 8B7424 34 mov esi, [esp+34]
0041F21D 897424 1C mov [esp+1C], esi
0041F221 33DB xor ebx, ebx
0041F223 33F6 xor esi, esi
0041F225 66:8B19 mov bx, [ecx]
0041F228 66:8B32 mov si, [edx]
0041F22B 03D8 add ebx, eax
0041F22D 83EA 02 sub edx, 2
0041F230 83E9 02 sub ecx, 2
0041F233 8D0433 lea eax, [ebx+esi]
0041F236 8B7424 1C mov esi, [esp+1C]
0041F23A 66:8941 02 mov [ecx+2], ax
0041F23E C1E8 10 shr eax, 10
0041F241 4E dec esi
0041F242 897424 1C mov [esp+1C], esi
0041F246 ^ 75 D9 jnz short 0041F221
0041F248 4F dec edi
0041F249 8B4424 38 mov eax, [esp+38]
0041F24D 85C0 test eax, eax
0041F24F 74 20 je short 0041F271
0041F251 8B4C24 2C mov ecx, [esp+2C]
0041F255 8B7424 34 mov esi, [esp+34]
0041F259 8B5C24 3C mov ebx, [esp+3C]
0041F25D 2BCD sub ecx, ebp
0041F25F 2BCE sub ecx, esi
0041F261 C1E1 04 shl ecx, 4
0041F264 03CB add ecx, ebx
0041F266 51 push ecx
0041F267 57 push edi
0041F268 50 push eax
0041F269 E8 22000000 call 0041F290
0041F26E 83C4 0C add esp, 0C
0041F271 8B4424 20 mov eax, [esp+20]
0041F275 45 inc ebp
0041F276 3BE8 cmp ebp, eax ; 32轮
0041F278 ^ 0F8E 8CFEFFFF jle 0041F10A
0041F27E 5F pop edi
0041F27F 5E pop esi
0041F280 5D pop ebp
0041F281 5B pop ebx
0041F282 83C4 14 add esp, 14
0041F285 C3 retn ;返回
----------------------------------------END---------------------------------*/
/*----------------------------------------64字节明文散列函数反汇编---------------------------------*/
/*
0041F055 8B5424 1C mov edx, [esp+1C] ; 取A数据
0041F059 03CE add ecx, esi
0041F05B 8D1472 lea edx, [edx+esi*2]
0041F05E 8D4C4B 02 lea ecx, [ebx+ecx*2+2]
0041F062 46 inc esi
0041F063 8B6C24 18 mov ebp, [esp+18]
0041F067 33DB xor ebx, ebx
0041F069 83EA 02 sub edx, 2 ; 新表数据和当前表数据值
0041F06C 83E9 02 sub ecx, 2 ; 向下2位数据
0041F06F 66:8B1C2F mov bx, [edi+ebp] ; 获取当前的表基值N
0041F073 33ED xor ebp, ebp ; 清空EBP
0041F075 66:8B6A 02 mov bp, [edx+2] ; 得到当前表的值B
0041F079 0FAFDD imul ebx, ebp ; N*B 结果保存到ebx中
0041F07C 33ED xor ebp, ebp ; 清空表EBP
0041F07E 66:8B69 02 mov bp, [ecx+2] ; 获取新数据表中的当前数据
0041F082 03E8 add ebp, eax ; 上一次进位数据加上新数据表中的当前位
0041F084 8D042B lea eax, [ebx+ebp] ; 当前乘积+edp数据
0041F087 66:8941 02 mov [ecx+2], ax ; 将底位数据写入新表当前位置
0041F08B C1E8 10 shr eax, 10 ; 取高位数据保存EAX,待下回使用
0041F08E 4E dec esi ; 记数减1
0041F091 8B5C24 20 mov ebx, [esp+20]
0041F095 8B4C24 24 mov ecx, [esp+24] ; 记数
0041F099 8B7424 10 mov esi, [esp+10]
0041F09D 66:8907 mov [edi], ax ; 将进位写入新地址
0041F0A0 49 dec ecx ; 总32回迭代记数器-1
0041F0A1 83EF 02 sub edi, 2
0041F0A4 894C24 24 mov [esp+24], ecx ; 更新单次记数器
0041F0A8 85C9 test ecx, ecx
0041F0AA ^ 7D A3 jge short 0041F04F ; 最后4字节保存完成的计算值
----------------------------------------END---------------------------------*/
#include "stdafx.h"
#include "F_G_Bt.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
#define HBYTE(buf) ( (BYTE)( (((BYTE*)(buf))[0]<<4) & 0xf0 ) )
#define LBYTE(buf) ( (BYTE)( (((BYTE*)(buf))[0]>>4) & 0x0f ) )
#define Encrypt_ALIGNMENT 8
#define ENCRYPTWORDALIGN(x) (((x)+(Encrypt_ALIGNMENT-1))&~(Encrypt_ALIGNMENT-1))
#define BUF_TO_UINT(buf) ( (UINT)( (((BYTE *)(buf))[0]<<24) | (((BYTE *)(buf))[1]<<16) | (((BYTE *)(buf))[2]<<8) | (((BYTE *)(buf))[3]) ) )
#define BUF_TO_WORD(buf) ( (WORD)( (((BYTE *)(buf))[0]<<8) | (((BYTE *)(buf))[1]) ) )
#define F_G_ERROR(x) \
AfxMessageBox(x);\
return FALSE;
char * initdata(char* szdate , int len);char * decodedata(char* szdate , int len);
char* DecodeCookie(char * data ,char*basedata, BOOL bstat);
typedef int (WINAPI * DecodePacket)(BYTE*, int , BYTE*, int, int ,int);
DecodePacket FUNDecode = NULL ;
HMODULE hModule = NULL;
DWORD dwHindex = -1;
int i = 31;
int j = 0;
int n = 0;
int k = 0;
BYTE szbuffer[0x80] = {0};
BYTE szRedultbuffer[0x80] = {0};
DWORD dwbase = 0;
BYTE szdata[64] = {0};
BYTE szbasedata[64] = {0};
//测试数据
BYTE sztmpdata[64] =
{
//以下事真实的测试明文数据
0x02 ,0x00 ,0x0D ,0x66 ,0xA9 ,0x52 ,0x0D ,0x56 ,0xB2 ,0x55 ,0xB6 ,0x91 ,0x7A ,0x45 ,0xE9 ,0xA1,
0x9A ,0xB4 ,0x8C ,0x02 ,0xA0 ,0x49 ,0x00 ,0xD8 ,0x64 ,0x35 ,0x35 ,0x39 ,0x64 ,0x61 ,0x37 ,0x63,
0x31 ,0x32 ,0x36 ,0x65 ,0x30 ,0x30 ,0x39 ,0x32 ,0x63 ,0x37 ,0x30 ,0x63 ,0x64 ,0x65 ,0x36 ,0x32,
0x65 ,0x37 ,0x33 ,0x66 ,0x64 ,0x34 ,0x39 ,0x61 ,0x33 ,0x34 ,0x61 ,0x64 ,0x64 ,0x38 ,0x32 ,0x35
};
//固定的加密表
BYTE bwdecodeTable[64] =
{
0x96 ,0xC3 ,0x37 ,0x67 ,0x2F ,0xDF ,0xA7 ,0xE7 ,0x08 ,0x00 ,0x35 ,0x9E ,0xD0 ,0xB0 ,0xF9 ,0x01 ,
0xD8 ,0x26 ,0x9D ,0x48 ,0x46 ,0x06 ,0x30 ,0x87 ,0x04 ,0x7D ,0x13 ,0xFB ,0x80 ,0x14 ,0x64 ,0x18 ,
0xEA ,0x89 ,0x49 ,0x1D ,0xDE ,0x15 ,0xCF ,0xBB ,0x8B ,0x71 ,0x5A ,0x4B ,0x88 ,0xB6 ,0xD7 ,0xE8,
0x11 ,0x81 ,0x97 ,0xD0 ,0x26 ,0x11 ,0xFC ,0x18 ,0x41 ,0x81 ,0xAF ,0x6B ,0x58 ,0x73 ,0x1B ,0xB6
};
/*==========================================================
* Function : initDecode
* Description :
* Return : int
* Comments : 初始化加密核心DLL函数
*=========================================================*/
int initDecode()
{
// 模块句柄
hModule = ::GetModuleHandle( "ww.dll");
if(hModule == NULL)
{
hModule = ::LoadLibrary("ww.dll");
}
if(hModule == NULL)
{
return -1;
}
// 获取DLL总加密函数地址
FUNDecode = (DecodePacket)::GetProcAddress(hModule, "decode");
if(FUNDecode == NULL)
return FALSE;
// Decode((BYTE*)bw128table, (BYTE*)bwdecodeTable);
// 调用函数
// int len = FUNDecode((BYTE*)bw128table, 0x40 , (BYTE*)bwdecodeTable, 0x20 , 0 , 0);
return TRUE;
}
/*
00934420 43 5D B8 24 1D 73 1F FD AD 66 82 63 3B D9 0F E3 C]?.s.?f?;?.
00934430 C5 3B 6F 4B 95 01 2D B9 EC DE 43 01 FE 90 77 52 ?oK?-轨廾.?wR
00934440 1F 20 BB 84 7A 68 26 FB 40 4A 2D 7E B1 98 0A BF . ?zh&?J-~?..
00934450 EB 76 47 E4 D8 35 C4 6A A8 EF A9 01 D6 2C 03 4E 膂G湄5年???.N
*/
/*==========================================================
* Function : _tmain
* Description :
* Return : int
* Parament : int argc
* Parament : TCHAR* argv[]
* Parament : TCHAR* envp[]
* Comments : 主函数
*=========================================================*/
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int lick = argc;
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
//以下模拟F_G6.32加密 客户端Key 的过程
BYTE bwdate64[64] = {0};
BYTE bwtable128[128] = {0};
//copy 明文数据
memcpy(bwdate64, sztmpdata, 64);
//调用聚合算法的加密库,由于比较复杂我直接用汇编写了个DLL
//加密函数地址保存在FUNDecode变量总,待下面使用
if(initDecode())
{
if(NULL != FUNDecode)
{
//总16轮迭代
for(int i = 0 ; i < 16; i++)
{
//第一层加密散列函数将明文64字节散列成128直接
char* szp = DecodeCookie((char*)bwdate64 , NULL, FALSE);
memcpy(bwtable128, szp, 128);
#ifdef _DEBUG
printf("[%d]散列\r\n" , i+1);
for(int k = 0 ; k < 128 ; k++)
{
printf("0x%02x " , bwtable128[k]);
}
printf("\r\n" );
#endif
//第二层加密聚合算法,将上面的128字节聚合成64字节
if(0x20 != FUNDecode((BYTE*)bwtable128,
0x40 , (BYTE*)bwdecodeTable, 0x20 , 0 , 0))
{ F_G_ERROR("Decode Error!!!"); }
else
{
//聚合后指向聚合数据头保存到bwdate64待下次使用
memcpy(bwdate64, bwtable128+64, 64);
#ifdef _DEBUG
printf("[%d]聚合\r\n" , i+1);
for(int k = 0 ; k < 64 ; k++)
{
printf("0x%02x " , bwdate64[k]);
}
printf("\r\n" );
#endif
}
}
#ifdef _DEBUG
printf("\r\n[END]聚合\r\n");
for(int k = 0 ; k < 64 ; k++)
{
printf("0x%02x " , bwdate64[k]);
}
#endif
//第3层加密 处理最终数据
//这里将上面16轮处理的数据和明文数据再进行一次散列
char* szp = DecodeCookie((char*)bwdate64/*16轮总结果*/ ,
(char*)sztmpdata/*明文*/,TRUE);
memcpy(bwtable128, szp, 128);
printf("\r\n[最终散列]\r\n" );
for(int k1 = 0 ; k1 < 128 ; k1++)
{
printf("0x%02x " , bwtable128[k1]);
}
//最终一次聚合
if(0x20 != FUNDecode((BYTE*)bwtable128,
0x40 , (BYTE*)bwdecodeTable, 0x20 , 0 , 0))
{ F_G_ERROR("Decode Error!!!"); }
else
{
//到这里数据加密完毕,最好将该数据颠倒一下用base64再加密一次
//放到http的cookie字段总就发送到服务器了
memcpy(bwdate64, bwtable128+64, 64);
printf("[最终结果]\r\n" );
for(int k = 0 ; k < 64 ; k++)
{
printf("0x%02x " , bwdate64[k]);
}
printf("\r\n" );
}
}
else
{F_G_ERROR("Decode Error FUNDecode == NULL!!!");}
}
else
{ F_G_ERROR("initDecode Decode Error!!!");}
}
system("pause");
return nRetCode;
}
/*
02 00 0D 66 A9 52 0D 56 B2 55 B6 91 7A 45 E9 A1
9A B4 8C 02 A0 49 00 D8 35 32 63 62 66 36 64 37
61 65 64 37 36 31 34 37 37 64 64 38 36 37 64 65
38 62 35 39 31 32 30 64 33 34 61 64 64 38 32 35
0x96 ,0xC3 ,0x37 ,0x67 ,0x2F ,0xDF ,0xA7 ,0xE7 ,0x08 ,0x00 ,0x35 ,0x9E ,0xD0 ,0xB0 ,0xF9 ,0x01 ,
0xD8 ,0x26 ,0x9D ,0x48 ,0x46 ,0x06 ,0x30 ,0x87 ,0x04 ,0x7D ,0x13 ,0xFB ,0x80 ,0x14 ,0x64 ,0x18 ,
0xEA ,0x89 ,0x49 ,0x1D ,0xDE ,0x15 ,0xCF ,0xBB ,0x8B ,0x71 ,0x5A ,0x4B ,0x88 ,0xB6 ,0xD7 ,0xE8,
0x11 ,0x81 ,0x97 ,0xD0 ,0x26 ,0x11 ,0xFC ,0x18 ,0x41 ,0x81 ,0xAF ,0x6B ,0x58 ,0x73 ,0x1B ,0xB6
*/
/*
0041F063 8B6C24 18 mov ebp, [esp+18]
0041F067 33DB xor ebx, ebx
0041F069 83EA 02 sub edx, 2
0041F06C 83E9 02 sub ecx, 2
0041F06F 66:8B1C2F mov bx, [edi+ebp]
0041F073 33ED xor ebp, ebp
0041F075 66:8B6A 02 mov bp, [edx+2] ; 取最后2字节的 WORD
0041F079 0FAFDD imul ebx, ebp
0041F07C 33ED xor ebp, ebp
0041F07E 66:8B69 02 mov bp, [ecx+2]
0041F082 03E8 add ebp, eax
0041F084 8D042B lea eax, [ebx+ebp]
0041F087 66:8941 02 mov [ecx+2], ax
0041F08B C1E8 10 shr eax, 10
0041F08E 4E dec esi
*/
/*==========================================================
* Function : DecodeCookie
* Description :
* Return : char*
* Parament : char * data
* Parament : char* basedata
* Parament : BOOL bstat
* Comments : 散列算法
*=========================================================*/
char* DecodeCookie(char * data , char* basedata , BOOL bstat)
{
__asm pushad //保存所有寄存器
j = 0; //总32轮循环记数字器
memset(szbuffer, 0 , 128); //初始化128字节的空缓冲表,用于存放下面散列的数据
memcpy(szdata , data , 64); //copy一份待散列的数据
//FALSE == 16轮迭代散列,TRUE == 整个加密过程最后一次 有点区别所以分开
if(FALSE == bstat)
{
for( j ; j < 32 ; j++)//总32轮迭代
{
i = 31;k=n=j;
n *= 2;k *= 2;
__asm
{
mov edx, offset szdata ; 取数据表
mov esi, i
lea edx, [edx+esi*2] ; 指向数据表尾
mov dwbase, edx ; 将值保存到dwbase
}
if(0 != j)
{
__asm
{
xor eax, eax ;清空EAX
mov eax, edx ;将上面的指向数据表尾的地址给EAX
sub eax, n ;指针向前移n位 注:下面的计算是从表尾开始
mov dwbase, eax ;保存到dwbase
}
//dwbase是整个散列过程总的相乘的乘数,我这里管它叫基数 代号 N
//当前表中相乘的数 代号 B
if(0 != dwHindex)
{
dwHindex = 0;
}
}
else{ dwHindex = 0; }
for( i ; i >= 0 ; i--) //子32轮迭代
{
__asm
{
mov edx, offset szdata ; 取数据表
mov esi, i ; esi保存当前的循环计数
mov ebx, offset szbuffer[0x40] ; 指向128表2段位置(64字节1段/64字节2段)
lea edx, [edx+esi*2] ; 指向数据表尾
lea ecx, [ebx+esi*2+2] ; 指向缓冲表尾
mov edi, edx ; 将数据表尾的地址保存到edi
xor ebx, ebx ; 清空EBX
sub edx, 2 ; 新表数据和当前表数据值
sub ecx, 2 ; 向下2位数据
mov edi, dwbase ; 取出本轮的基数
mov bx, [edi] ; 获取当前的表基值 N
xor ebp, ebp ; 清空EBP
mov bp, [edx+2] ; 得到当前表的值 B
imul ebx, ebp ; N*B 结果保存到ebx中
xor ebp, ebp ; 清空表EBP
xor eax , eax
mov eax, ecx
sub eax, k ; eax指向本轮数据缓冲的地址
mov ecx, eax ;
mov bp, [ecx] ; 获取新数据表中的当前数据
mov eax, dwHindex ; 上轮的高位数据保存到eax
add ebp, eax ; 上一次进位数据加上新数据表中的当前位
lea eax, [ebx+ebp] ; 当前乘积+edp数据
; EAX保存了整个计算的结果
mov [ecx], ax ; 将底位数据写入新表当前位置
mov dwHindex, eax ; dwHindex保存当前的值
}
//取高位用于下轮的计算使用
__asm push ecx
dwHindex >>= 16; //取高位,保存到dwHindex,用于下次计算
__asm pop ecx
}
__asm xor eax , eax ;子32轮循环后上面高位数据保存到当前新数据表的
__asm mov eax , dwHindex ;前2位
__asm mov [ecx-2], ax
}
__asm popad
return (char*)szbuffer; //返回散列后的数据
}
else
{
//以下处理最终散列 和上面不同的地方就是将16轮的数据不是乘自身
//而是和64字节的明文表相乘。
memcpy(szbasedata ,basedata, 64);
for( j ; j < 32 ; j++)//总32轮迭代
{
i = 31;k=n=j;
n *= 2;k *= 2;
__asm
{
mov edx, offset szdata ; 取数据表
mov esi, i
lea edx, [edx+esi*2] ; 指向数据表尾
mov dwbase, edx
}
if(0 != j)
{
__asm
{
xor eax, eax
mov eax, edx
sub eax, n
mov dwbase, eax
}
if(0 != dwHindex)
{
dwHindex = 0;
}
}
else{ dwHindex = 0; }
for( i ; i >= 0 ; i--) //子32轮迭代
{
__asm
{
mov edx, offset szdata ; 取数据表
mov esi, i
mov ebx, offset szbuffer[0x40] ; 指向128表2段位置(64字节1段/64字节2段)
lea edx, [edx+esi*2] ; 指向数据表尾
lea ecx, [ebx+esi*2+2] ; 指向缓冲表尾
mov eax, offset szbasedata
lea eax, [eax+esi*2]
mov edi, edx
xor ebx, ebx ; 清空EBX
sub edx, 2 ; 新表数据和当前表数据值
sub ecx, 2 ; 向下2位数据
mov edi, dwbase
mov bx, [edi] ; 获取当前的表基值N
xor ebp, ebp ; 清空EBP
push ecx
mov bp, [eax] ; 得到当前表的值B
imul ebx, ebp ; N*B 结果保存到ebx中
xor ebp, ebp ; 清空表EBP
pop ecx
xor eax , eax
mov eax, ecx
sub eax, k
mov ecx, eax
mov bp, [ecx] ; 获取新数据表中的当前数据
mov eax, dwHindex
add ebp, eax ; 上一次进位数据加上新数据表中的当前位
lea eax, [ebx+ebp] ; 当前乘积+edp数据
mov [ecx], ax ; 将底位数据写入新表当前位置
;shr eax, 0x10 ; 取高位数据保存EAX,待下回使用
; dec esi ; 记数减1
mov dwHindex, eax
}
//取高位用于下轮的计算使用
__asm push ecx
dwHindex >>= 16; //取高位
__asm pop ecx
}
__asm xor eax , eax
__asm mov eax , dwHindex
__asm mov [ecx-2], ax
}
__asm popad
return (char*)szbuffer;
}
return (char*)"";
}
请教:
1.有谁知道这是什么算法?
2.解密算法如何实现?
先谢谢了
[课程]Linux pwn 探索篇!