首页
社区
课程
招聘
[求助]一个算法只有8行汇编代码的CM,前辈们来指点一下。
发表于: 2015-12-15 03:37 14516

[求助]一个算法只有8行汇编代码的CM,前辈们来指点一下。

2015-12-15 03:37
14516
使用OllyDbg从零开始Crack 第22章-反调试之UnhandledExceptionFilter,ZwQueryInformationProcess
http://bbs.pediy.com/showthread.php?t=189193
首先感谢安大无私的翻译精神,才让我能看到这么好的教程。
在学习过程中,遇到问题,希望前辈们指点一下。
目标CM:sphynx.7z

00401121     33C9         XOR     ECX,ECX
00401123     33D2         XOR     EDX,EDX
00401125     33FF         XOR     EDI,EDI
00401127     0FBEB9 54304>MOVSX   EDI,BYTE PTR DS:[ECX+0x403054] ;保存序列号
0040112E     81C2 7856341>ADD     EDX,0x12345678
00401134     D1D2         RCL     EDX,1
00401136     13D7         ADC     EDX,EDI
00401138     81C2 2143658>ADD     EDX,0x87654321
0040113E     41           INC     ECX
0040113F     3BC8         CMP     ECX,EAX
00401141   ^ 75 E4        JNZ     SHORT 00401127
00401143     81FA 382AB4C>CMP     EDX,0xC3B42A38 ;结果为C3B42A38时正确.
00401149     75 32        JNZ     SHORT 0040117D

序列号计算方法大概如下:
        char *pszSerial = "123123";
        char aChar;
        unsigned long long res = 0;
        while (aChar = *pszSerial++)
        {
                res += 0x12345678;
                char cf = (char)(res >> 31);
                res = (unsigned)res << 1 | (unsigned)(res >> 32);
                res += aChar + cf;
                res = res + 0x87654321 & 0xffffffff;
        }
        printf("%08X\n", (unsigned)res);

可是想了两天了,也不知道如何推导出正确序列号,希望大家前来指点一二。

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

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 1121
活跃值: (722)
能力值: ( LV5,RANK:66 )
在线值:
发帖
回帖
粉丝
2
想了两天还没想出来?你可以转行了。把算法倒着来,加的地方换成减,序列号从后往前循环,左右移不变。
2015-12-15 10:24
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我本来就不是计算机行业的啊,难道要我转计算机行业?
请问你倒出序列号了吗?请发出来让我让我试验一下,试验过后说不定我能想明白了。
2015-12-15 16:15
0
雪    币: 204
活跃值: (911)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
4
22222210102
2015-12-15 19:31
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
12345678910
楼主序列号计算函数好像有点问题。

        char *pszSerial = "str";
        char aChar;
        int res = 0;
        int cf = 0;

        while (aChar = *pszSerial++){
                cf = (res & 0xFFFFFFFF)  > 0x7FFFFFFF;
                res += 0x12345678;
                res <<= 1;
                res += aChar;
                res += cf;
                res += 0x87654321;
        }
        printf("0x%X\n", res);
2015-12-15 19:48
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢提醒,确实有问题,改了一下。
        char *pszSerial = "12345678910";
        char aChar;
        unsigned long long res = 0;
        while (aChar = *pszSerial++)
        {
                res += 0x12345678;
                res = res << 1 | res >> 32;
                res += aChar + (res >> 32 & 1);
                res = res + 0x87654321 & 0xffffffff;
        }
        printf("%08X\n", (unsigned)res);

不过,兄弟你还没告诉我怎样算出来的序列号呢.
2015-12-15 21:54
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我是渣渣 试的 序列号是11位 然后输入数字字母都是相近的..
2015-12-16 09:30
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
嗯,你是渣渣,渣渣把序列号算出来了,那我就是连渣渣也不如了,借你家墙给我撞几下
二楼的方法,管用吗?还是误导人的?
我尝试过先减去0X87654321,然后减去一个ASCII码值,可是并不知道是否产生进位,前面的RCL也是根据EDX + 0X12345678,产生的进位来移位的,这里就又难住了,无法再住后继续了
2015-12-16 16:01
0
雪    币: 204
活跃值: (911)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
9
0x12345678和0x87654321和注册码对最后结果的影响是线性的。
当注册码为空是,算出一个结果,再用0XC3B42A3B减去这个结果得到的值就是正确的验证码产生的值。
说起来好绕,不过你应该能懂了吧。
2015-12-16 17:23
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
大侠,请收下我的膝盖。
等有时间,我按您的思路去试验一下,我按2楼的思路倒过来试验过了,结果走不通。
2015-12-16 20:06
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
这个算法是不可逆的,除了穷举,别无他法。
2015-12-17 10:00
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习一下我等小菜望而却步啊
2015-12-17 13:37
0
游客
登录 | 注册 方可回帖
返回
//