首页
社区
课程
招聘
[破解RSA512要多久]谁见过这种BT加密算法,帮忙分析分析 [完结]
发表于: 2007-2-24 10:38 15801

[破解RSA512要多久]谁见过这种BT加密算法,帮忙分析分析 [完结]

2007-2-24 10:38
15801
前段时间研究一种加密代理软件,其中使用了多种加密算法,在和服务器协商 密钥的过程中遇到了以下的一种算法,特此发贴请教。

明文是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.解密算法如何实现?

先谢谢了

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (23)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
终于忙完了过年回到了北京,一看帖子没一个回复,伤心啊
可能是我没说明白,仔细描述一下,看不懂的兄弟也帮忙顶顶吧 这算法比较有意思的,可以研究研究,或许以后你会遇到。

算法总体描述:
64字节的明文数据经过16轮的循环,经过2个函数的处理,最后输出64字节的密文数据,这2个函数,我暂时叫它们,Fun1(), Fun2()。

先说Fun()1函数

Fun()1: Fun1()将64字节的明文数据散列成128字节的数据,处理大致是这样的见下面的明文数据 .

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

以上是64字节的明文数据,Fun1()函数,经过32轮循环 从上数据表中以word形式从最后2字节开始循环的逐个相乘,如上面的数据最后2个字节是0x32,0x35,
word形式就是0x3532,第一次0x3532*0x3532=0xB0DBDC4,取输出缓冲(128字节的缓冲)的当前数据(这里就是缓冲指针指向最后2个字节的数据),加上上一次计算的高位数据,再加上0xB0DBDC4,(注:128字节的缓冲开始的时候都被初始化0,现在是第一次计算,所以没有高位数据,也就是0xB0DBDC4+0+0=0xB0DBDC4),将0xB0DBDC4高底位分开,低位0xBDC4写入新缓冲地址,高位保存,用做下会计算使用,然后字符指针-2只向前2位,就是上数据表的0x64,0x38,和上面一样,0x3532*0x3864+0(当前输出缓冲数据)+0xB0D(上一次的高位),...如此循环将数据表的数据全部处理完毕,最后输出128字节的数据.

以下是Fun1()的汇编代码
__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

先描述到这到这里有朋友见过这种算法吗,或者说说想法,小弟不胜感激.
Fun2()就是将Fun1()128字节的数据压缩成64字节的数据,由于比较长,又刚下飞机比较累,等过几天详细描述,再次谢谢了.
2007-2-25 18:23
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
Fun2() 可以看下面这段汇编代码

// 以下是将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-----------------------

首帖的代码在winxp,win2000 +VC6.0 是调试通过的,由于公司FTP关闭我家的PC没原代码,等明天去公司我会将代码发上来.可以调试的跑跑就很清楚了。

.
2007-2-25 19:13
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
上传代码,有兴趣的可以跟跟玩玩。解密算法搞定后会贴出来。
比较伤心100多人看过没一个回帖.
上传的附件:
2007-2-26 09:55
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
以上代码在 VC6.0 win2000/winxp 下调试通过,使用了比较多的内联汇编。ww.dll 是直接使用IDA dump出来的
2007-2-26 13:09
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主辛苦了,好东西.
2007-2-26 14:24
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
最初由 fivewin 发布
楼主辛苦了,好东西.


好感动,你是第一个回贴的朋友,我会记得你的,谢谢了
2007-2-26 14:41
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
8
我想回贴
但确实看不懂
2007-2-26 14:47
0
雪    币: 277
活跃值: (312)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
9
DES?不会吧
2007-2-26 17:16
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
最初由 wangshq397 发布
DES?不会吧


肯定不是拉 , 不过谢谢你参加讨论
2007-2-26 17:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我是一个很菜的菜鸟,支持下楼主 !
2007-2-26 20:53
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
最初由 懈忆梦想 发布
我是一个很菜的菜鸟,支持下楼主 !


非常感谢你的支持
2007-2-26 22:08
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很搞笑。这种算法就是RSA-512

整个过程用伪代码是这样的

明文=C 密文=M 前面提到的加密表 = N = Q*P

RSA加密 C = M^e mod N

for(int i = 0 ; i < 16 ; i++)
{
     Fun1(...); //M*M
     Fun2(...); //M*M mod N
}

Fun1(...); //上面循环16次后的最后数据*M
Fun2(...); //Fun(1)的结果 mod N

------END-------
上面Fun1() 将传进去的数据(第一次是明文数据) 进行 M*M = M^2
Fun2() 将上面计算的结果 mod N,再将mod出来的数据循环重复16次
最后调用Fun1()上面16轮计算的结果 * 明文数据M
再将结果mod N.

我们看公式 RSA加密 C = M^e mod N
e的取值 对RSA计算速度影响很大,最常见的0x10001 = 63357D = 2^16+1

上面循环16次,然后M^2 ,实际就是2^16
最后一次将上面16轮的数据 * M 实际上就是+1,也就是2^16+1 = e
晕死,很有意思吧,前面我发了加密过程的代码,如果朋友想看看计算机是如何进行512位的大数乘法和取模计算,可以跟一下程序。

最后想请教一下 对于RSA-512 有谁用RSATOOlS 或其他因式分解的软件 算过Q,P. 如果使用P4-3.0的CPU 2GB内存 要想解密出强度512位的RSA 需要算多久。

我查了一下网上说RSA-600以下的已经被破解,消息是出自RSA官方网站的,有谁知道具体是怎么破解的吗?
2007-3-7 00:41
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
RSA-256的我爱机使用ppsiqs跑半个小时就出来了,用RSA TOOLS2需要近2个小时。 我真的很想知道 RSA-512 要跑多久才能出来
我自己算了一下 好象P4-3.0的机器大概要5-6个月??? 迷惑中..
2007-3-7 00:52
0
雪    币: 259
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
PPSIQS Ver 1.1 by S.Tomabechi 2001
C77=5808691759331683824566659742093088649450706739973255070785815794156267928004
9
#FactorBase 10976 max FactorBase 248839
max LargePrime 17912010 Upper Bound 8139484397182
SieveWidth 20480 SieveUnit 20480 CutOff 84 multiplier 1 ncomb 10
To stop sieving, press Ctrl + Pause

3807(11008)/11008
search cycles
1781 duplicated data merged in Large Prime
74 duplicated data merged e.
(f)  type 3807 total 11362
(p)  type 50952( p_p 4305, p_p_pp 1394, p_p_p_p_pp_pp 216)
(pp) type 31294( pp_pp 715, pp_pp_pp 430, others 224)

block Lanczos method
#singleton 305 : zero-weight columns 78
10593*10703 matrix 28.8255 entries / row
nonzero entry 305349 memory 1193K
#iteration 340 gained 31 solutions  0:00:06:62
failed  gcd 1
found  factor 299073611622137685654157528640601939371
cputime 0:19:19:06
t et 1260 22706372342004951600
Jacobi Sum Test ( APR-CL )
for P=2 Q=3 5 7 13 11 31 61 19 37 181 29 43
for P=3 Q=7 13 31 61 19 37 181 43
for P=5 Q=11 31 61 181
for P=7 Q=29 43
final test
t et 1260 22706372342004951600
Jacobi Sum Test ( APR-CL )
for P=2 Q=3 5 7 13 11 31 61 19 37 181 29 43
for P=3 Q=7 13 31 61 19 37 181 43
for P=5 Q=11 31 61 181
for P=7 Q=29 43
final test

在我的机器上跑的256的RSA
2007-3-7 11:15
0
雪    币: 217
活跃值: (15)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
  
帮着顶一下
半夜了还在玩,好辛苦啊
2007-3-7 16:38
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
2007-3-8 08:58
0
雪    币: 538
活跃值: (460)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
18
还是不大明白RSA!
2007-3-8 09:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
支持!!!!!!!!!
2007-3-8 17:43
0
雪    币: 234
活跃值: (61)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
楼主这么辛苦,虽然水平还没达到看懂的程度,不过还是要顶的。
2007-3-8 17:59
0
雪    币: 277
活跃值: (312)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
21
rsa好像是分解 N 吧
2007-3-8 19:37
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
最初由 wangshq397 发布
rsa好像是分解 N 吧


是的,因为N是两个质数(也叫素数)的乘积,质数的特性就是只能被自己和1整除的数,但是这个N如果很大的化因式分解就非常困难,比如 RSA-512实际上是64个字节的16进制转换 64*8 = 512位 大概就是154数字长10进制的数,要分解它非常困难地 1994年美国人用了1600台PC 协同跑了 8个月的时间解出了128数字长(10进制)的大数。

    如果对此方面感兴趣的朋友可以去看看 <<现代应用密码学>> 11章x小节(忘了^_^) 因子分解 相关的信息
2007-3-8 20:10
0
雪    币: 277
活跃值: (312)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
23
好像可以替换成自己的 N ,然后 XX 吧。
2007-3-9 13:12
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
最初由 wangshq397 发布
好像可以替换成自己的 N ,然后 XX 吧。


是的,这种方法只能在软件破解使用,说白了就是在本地化的应用软件使用,对于C/S模式通讯的没什么用,因为你换了N服务器解不出来了
2007-3-9 21:03
0
游客
登录 | 注册 方可回帖
返回
//