首页
社区
课程
招聘
[旧帖] [求助]这个加密函数的逆函数该怎么写? 0.00雪花
发表于: 2008-1-3 17:25 4526

[旧帖] [求助]这个加密函数的逆函数该怎么写? 0.00雪花

2008-1-3 17:25
4526
下面是一段汇编代码(我经过两天分析已经可以转换成C++了):
//初始化4个双字变量
.text:0046BE7A                 xor     eax, eax
.text:0046BE7C                 xor     ebx, ebx
.text:0046BE7E                 xor     ecx, ecx
.text:0046BE80                 xor     edx, edx

//这是低32位,一个双字
.text:0046BE82                 mov     esi, [ebp+var_8]
//这是一个32*4的表,即128个双字,32行,4列
.text:0046BE85                 lea     edi, unk_6502A8

//这是一个循环,就是按前面的双字从0到31位检测,如果是0就忽略,
//如果是1就取上表中对应该位的行处的双字与开始的4个变量进行异或操作,表中刚好是4列。
.text:0046BE8B
.text:0046BE8B loc_46BE8B:                             ; CODE XREF: sub_46BE60+3F
.text:0046BE8B                 shr     esi, 1
.text:0046BE8D                 jnb     short loc_46BE9C
.text:0046BE8D
.text:0046BE8F                 xor     eax, [edi]
.text:0046BE91                 xor     ebx, [edi+4]
.text:0046BE94                 xor     ecx, [edi+8]
.text:0046BE97                 xor     edx, [edi+0Ch]
.text:0046BE9A                 test    esi, esi
.text:0046BE9A
.text:0046BE9C
.text:0046BE9C loc_46BE9C:                             ; CODE XREF: sub_46BE60+2D
.text:0046BE9C                 lea     edi, [edi+10h]
.text:0046BE9F                 jnz     short loc_46BE8B
.text:0046BE9F

//高32位,另一个双字
.text:0046BEA1                 mov     esi, [ebp+var_4]
//又一个32*4的表
.text:0046BEA4                 lea     edi, unk_6504A8
.text:0046BEA4

//这又是一个循环,功能与上面的循环一样。
.text:0046BEAA loc_46BEAA:                             ; CODE XREF: sub_46BE60+5E
.text:0046BEAA                 shr     esi, 1
.text:0046BEAC                 jnb     short loc_46BEBB
.text:0046BEAC
.text:0046BEAE                 xor     eax, [edi]
.text:0046BEB0                 xor     ebx, [edi+4]
.text:0046BEB3                 xor     ecx, [edi+8]
.text:0046BEB6                 xor     edx, [edi+0Ch]
.text:0046BEB9                 test    esi, esi
.text:0046BEB9
.text:0046BEBB
.text:0046BEBB loc_46BEBB:                             ; CODE XREF: sub_46BE60+4Cj
.text:0046BEBB                 lea     edi, [edi+10h]
.text:0046BEBE                 jnz     short loc_46BEAA
.text:0046BEBE

////////////////////////////////////////////////////////////////
//到这里开始的4个变量eax,ebx,ecx,edx都有了新值。
////////////////////////////////////////////////////////////////

//初始化两个新变量,这个新变量计算后的值就是解出来的值。
.text:0046BEC0                 xor     esi, esi
.text:0046BEC2                 xor     edi, edi

//下面的操作,看上去就是把eax,ebx,ecx,edx不停的循环移位,其实操作和上面的两个循环实质上非常相似
//就是用ecx,edx来作为参考,就象上面的var_8和var_4。
//那么如上面的两个表在哪里呢?这个两个表不象上面是预先存储好的,而是用eax,ebx两个变量动态生成的。我会在后面标上等价于生成两个表的地方。
//通过测试ecx,edx的位值来决定是否取值与esi,edi异或。当然这里的测位顺序不象上面两个是0-31,而是用了新的顺序:
//ecx用的是从28位开始的-4模33,edx用的是从4位开始的+5模33。
//如果测试的位的值是1,这时也不能按测试位的对应行了,而只能测试的次数-1来对应表中的行了。
//当然,如果在下面操作之前把ecx,edx按上面所说的测位顺序变换一下,就可以和上面的两个循环操作一模一样了。
.text:0046BEC4 loc_46BEC4:                             ; CODE XREF: sub_46BE60+7Ej
.text:0046BEC4                                         ; sub_46BE60+8Bj
.text:0046BEC4                 bt      edx, 4
.text:0046BEC8                 rcl     ecx, 4
.text:0046BECB                 jnb     short loc_46BEED
.text:0046BECB
.text:0046BECD                 xor     esi, eax
.text:0046BECF                 xor     edi, ebx
.text:0046BECF
.text:0046BED1
.text:0046BED1 loc_46BED1:                             ; CODE XREF: sub_46BE60+8Fj
.text:0046BED1                                         ; sub_46BE60+93j
.text:0046BED1                 rcr     edx, 5

//////这一段就相当于生成了一个新的表,当然是2列的。
//也就是下面的这段代码循环63次再与原来的eax,ebx一起就可以组成两个32*2的表了
//如果ecx,edx也已经按测位顺序转换的话,那么这段代码安全可以写成与开始两个循环一模一样。
.text:0046BED4                 bt      ebx, 1Bh
.text:0046BED8                 rcr     eax, 4
.text:0046BEDB                 rcl     ebx, 5
.text:0046BEDE                 jnb     short loc_46BEC4
.text:0046BEDE
.text:0046BEE0                 xor     eax, 800008h
.text:0046BEE5                 xor     ebx, 80000300h

.text:0046BEEB                 jmp     short loc_46BEC4
.text:0046BEEB
.text:0046BEED ; ---------------------------------------------------------------------------
.text:0046BEED
.text:0046BEED loc_46BEED:                             ; CODE XREF: sub_46BE60+6Bj
.text:0046BEED                 test    edx, edx
.text:0046BEEF                 jnz     short loc_46BED1
.text:0046BEEF
.text:0046BEF1                 test    ecx, ecx
.text:0046BEF3                 jnz     short loc_46BED1
//最后到这里esi,edi就会新值,这个值就是解出来的值了。

现在的问题出来了,我已经知道了esi,edi(这是已经的,注册就是通过这两个数来取得注册码的),如何生成var_8,var_4(这两个数就是注册码)呢?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
是不是我给出的代码太多了没人愿意看?那我就用中文描述一下:
第1步:一个64位数分成L,R两部分,有两个32*4的双字表,先取R和第一个表,从0到31位测试位的值是否为1,如果是1则取表中与位对应的行的数来对4个(因为表中每行有4个双字)初始化为0的数进行异或。现取L和第二个表,继续上面一样的操作。这样就行到4个新的双字eax,ebx,ecx,edx。
第2步:用第1步生成的4个数中的ecx,edx做参考,用eax,ebx生成两个新的32*2的双字表,做与第1步类似的操作。与第一步不同的是ecx,edx的测位顺序不是从0到31,测位顺序和eac,ebx生成新表的方法上面说了。如果被测位为1则用测试次数-1对应的新表的行中的两个数与初始化为0的两个数做异或。最后生成新的esi,edi。

上面说的就是解密函数,它一定有一个加密函数!这个道理应该不用讲的。可是我从这个解密过程求不出加密过程。希望高和指点一下。
如果需要预存储的两个表,我也可以发上来的。
2008-1-3 18:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
自己顶一下。

如果老大认为这个问题应该我自己解决就直接告诉一下,我就不再顶了。
2008-1-4 11:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这个算法很难吗?
kanxue老大指点一下。
2008-1-7 17:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
自己顶一下。
这个算法是公开的算法吗?如果是我就自己找。只是我知道的公开算法中没有这样转换的。
2008-1-8 13:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
DWORD Dwordtab1[128] =
{
0xCDC97540, 0x390BEA52, 0x7720D3C4, 0x9E062EF3,
0xEE815284, 0x2535867D, 0x2FFEBD26, 0x068A5BC0,
0xFC08709A, 0xD29F366F, 0xDF6003A3, 0xF8428566,
0x3E192D17, 0x9A011983, 0x253C5E97, 0xE63BA569,
0x350C5E49, 0xC47AF442, 0x19FF279E, 0xBE9ACBA1,
0xE11354A3, 0xFEA5A342, 0xC6FCE0A4, 0xCC0D8739,
0x6CB5CBE5, 0x81FC90DA, 0x32E070BF, 0x96984172,
0xCBA0D80B, 0x49DE00A8, 0xE15382A5, 0x3E873ED7,
0xA3FE70CA, 0x319B754C, 0xCF48527D, 0xDF2E853A,
0xF63E7EBE, 0xC59C9208, 0x7CD79BEC, 0x49D758FA,
0xC094B280, 0x73C0D885, 0xE5CD46FE, 0x98E199BC,
0x0A8B528F, 0x92B4B6B7, 0xD78312F0, 0x55F9094C,
0xBF74ED2E, 0x37CC1CAC, 0x7A8271FD, 0x4A6B9E5A,
0xBB57C3BB, 0x2A4CC1EB, 0x03EF7DA4, 0x7B4048F5,
0x7DB8E91D, 0x70EC9EA0, 0x853B9B31, 0x4827E53D,
0x5C3B5BB9, 0x2DAAFC1E, 0x68FF1845, 0x4FF2DD09,
0x726F0DE1, 0xB60F66B3, 0x11CF06F4, 0xA2D42196,
0xCB6B1D43, 0xA22EEF16, 0x14727664, 0x4B48A8AB,
0x04A211BA, 0x1CB696EC, 0x1991695F, 0x40A75F5D,
0xAE138531, 0x4C110763, 0x54814774, 0x37972974,
0x8FC0C509, 0x3EAB1593, 0xBB39368C, 0xBF660AF5,
0xC27C21FA, 0xED17B209, 0xC3AFDB0F, 0xA747C846,
0x583C6A9B, 0x705E00DD, 0x8E8059C7, 0x71F900C1,
0x98C248AC, 0xA47665A6, 0xD6E55CD1, 0xB4B48158,
0xA87F0E89, 0xB08FA6AD, 0x0655F14F, 0x7100FBB7,
0xEB66E0C6, 0xEFCAE1B1, 0xBAF0D3C0, 0xC89A04E0,
0xFBA83AC7, 0x4B759382, 0x845C1139, 0xDFC52687,
0x3E011A5C, 0xE8D7A0A4, 0xB6BDFD72, 0x58EC0C27,
0x499E8925, 0x7FC0EA92, 0x72CBAB16, 0xEB8DE581,
0x34E14C97, 0x6B0AA4B0, 0xBF333FF4, 0xD88B9473,
0x9142C73E, 0xB706DBEA, 0x8E4E8C54, 0xD8AE7AE5,
0xE8318F5A, 0xF3037B2A, 0x38DB42E4, 0x1594D124,
};

DWORD Dwordtab2[128] =
{
0x56C2B1C6, 0x30A21DA1, 0x6CA371E4, 0x39F53A26,
0x44C945D8, 0xEC7C1F94, 0x1852911D, 0x7D5CD13D,
0xAD880DBD, 0x4473F541, 0xCA527FA2, 0x0CA60A29,
0xF8A6B2C5, 0xD912E585, 0xE019103A, 0xEDB71F13,
0xEAE668DE, 0xF906C589, 0x0AAC587F, 0x33F7A295,
0x30CD6152, 0xA7EF7013, 0xD68FDF13, 0xE8DB74B6,
0xD8CC6379, 0x534A1AA7, 0xE32E93A6, 0xA198DCFE,
0x861EBA19, 0xB8F07F02, 0x70DBC376, 0x09A3EBA6,
0x6B289B44, 0x7E994F22, 0xD9D2C9B2, 0xF5DDAD63,
0x96C947F7, 0x83A6E093, 0x9957A97E, 0x0CE1DEB9,
0x14594DB5, 0x8B8FD448, 0x03584249, 0x60F6467C,
0xC388F72F, 0x4FAEE84E, 0x3EF17F90, 0x72D924C4,
0x43D2AB1D, 0x22023F29, 0xF7F712D1, 0xDBCE4138,
0x0F61754F, 0xBBAF6A5E, 0x1200FD58, 0xAD15B1BC,
0xD1282833, 0x122A0FA6, 0xF398916F, 0xB4D8C74E,
0x521F4214, 0xB4B69FE3, 0xDC6C6A6C, 0x7975B089,
0xB9A3A5B4, 0xD4423501, 0x96C401BC, 0xE8E22BB7,
0xD5C6C264, 0x259EE4E0, 0xA137CD7F, 0x88CC5348,
0xDEA55210, 0xCAF19396, 0x9A383787, 0x006CDCCF,
0x31999793, 0x1876889F, 0x2E9A10AF, 0xE7598501,
0xDF0498D5, 0xF2B6F045, 0x81EAED9E, 0x02AA7F76,
0xC170C838, 0x940A7816, 0x80D79386, 0x8FFA731B,
0x6D0B3658, 0x72F4F86E, 0x3CFDF67E, 0xE03A1D5C,
0xA113EA63, 0xF5FB71E7, 0x02951367, 0x81FCDE6D,
0x82FC1F1B, 0x331CC39B, 0x527E38DB, 0xDC690C3A,
0xE1B8E432, 0x91DFA1B0, 0x29607F86, 0xB03AAF1D,
0xDC46707F, 0xBB594A1B, 0x7841082A, 0x90E093D0,
0xE6E00041, 0x7105C73D, 0x8CDF6AC3, 0xB09CC838,
0x88350103, 0x6B594111, 0xFCA6C0C4, 0xBBBA7CE5,
0x11318D47, 0x55DED3DF, 0xA6A64F64, 0x9E215AD7,
0xA1E2F463, 0x7E21544C, 0x57D67A6F, 0x3EAA1AF8,
0xB841428D, 0xE3F9F18A, 0xE6145444, 0x37F36777,
};

        DWORD tmp = var4;
        DWORD* pdw = Dwordtab1;
        DWORD eax = 0;
        DWORD ebx = 0;
        DWORD ecx = 0;
        DWORD edx = 0;
        DWORD testecx, testedx, testebx, testeax;
        DWORD esi=0, edi=0;

        while( tmp != 0)
        {
                if( (tmp&1) == 1)
                {
                        eax = eax ^ *pdw;
                        ebx = ebx ^ *(pdw+1);
                        ecx = ecx ^ *(pdw+2);
                        edx = edx ^ *(pdw+3);
                }
                pdw+=4;
                tmp = tmp>>1;
        }
        tmp = var8;
        pdw = Dwordtab2;
        while( tmp != 0)
        {
                if( (tmp&1) == 1)
                {
                        eax = eax ^ *pdw;
                        ebx = ebx ^ *(pdw+1);
                        ecx = ecx ^ *(pdw+2);
                        edx = edx ^ *(pdw+3);
                }
                pdw+=4;
                tmp = tmp>>1;
        }

        while(1)
        {
                testedx = edx & 0x10;
                testecx = ecx & 0x10000000;
                ecx = (ecx<<4) | (ecx>>(32-3));
                if( testedx != 0 )
                {
                        ecx |= 8;
                }
                if( testecx == 0 )
                {
                        if( (edx == 0) && (ecx == 0) )
                        {
                                break;
                        }
                }
                else
                {
                        esi = esi ^ eax;
                        edi = edi ^ ebx;
                }
                edx = (edx >> 5) | (edx<<(32-4) );
                testebx = ebx & 0x08000000;
                testeax = eax & 8;
                eax = (eax>>4) | (eax<<(32-3));
                ebx = (ebx<<5) | (ebx>>(32-4));
                if(testeax != 0)
                {
                        ebx |= 0x10;
                }
                if(testebx != 0)
                {
                        eax |= 0x10000000;
                        eax = eax ^ 0x00800008;
                        ebx = ebx ^ 0x80000300;
                }
        }

上面就是用C++实现的。
老大指点一下就可以,给点思路,不用直接写出逆函数来。我现在关键是根本无从下手,感觉就象没有逆函数一样。说一下要用到什么知识点也可,我可以自己去补。
2008-1-8 15:14
0
游客
登录 | 注册 方可回帖
返回