菜鸟中的菜鸟 发表于 2016-6-26 21:24

某Crackme算法分析的问题

本帖最后由 菜鸟中的菜鸟 于 2016-6-26 21:34 编辑

004010D0|.B9 08000000   mov ecx,0x8
004010D5|.BE 44304000   mov esi,Pusillus.00403044
004010DA|>8036 32       /xor byte ptr ds:,0x32
004010DD|.46            |inc esi                                           ;Pusillus.00403044
004010DE|.^ E2 FA         \loopd short Pusillus.004010DA
把每个字符与0x32进行异或,循环次数为8

004010EA|> /8A06          /mov al,byte ptr ds:
004010EC|. |8A5E 01       |mov bl,byte ptr ds:
004010EF|. |32C3          |xor al,bl
004010F1|. |8887 4C304000 |mov byte ptr ds:,al
004010F7|. |83C6 02       |add esi,0x2
004010FA|. |47            |inc edi
004010FB|.^\E2 ED         \loopd short Pusillus.004010EA
取出相邻的两个字符进行异或,保存异或结果到0x40304C,循环次数为4

00401102|.8A06          mov al,byte ptr ds:
00401104|.8A5E 01       mov bl,byte ptr ds:
00401107|.32C3          xor al,bl
00401109|.8A5E 02       mov bl,byte ptr ds:
0040110C|.8A4E 03       mov cl,byte ptr ds:
0040110F|.32D9          xor bl,cl
00401111|.32C3          xor al,bl
把上一步计算出的四个字节进行异或,得到一个字节

00401113|.B9 08000000   mov ecx,0x8
00401118|.BE 44304000   mov esi,Pusillus.00403044
0040111D|>3006          /xor byte ptr ds:,al
0040111F|.46            |inc esi                                           ;Pusillus.00403044
00401120|.^ E2 FB         \loopd short Pusillus.0040111D
把code的每个字符与上一步计算出一个字节进行异或


00401122|.B9 08000000   mov ecx,0x8
00401127|.BE 44304000   mov esi,Pusillus.00403044
0040112C|.BF 08304000   mov edi,Pusillus.00403008
00401131|>8A06          /mov al,byte ptr ds:
00401133|.3A07          |cmp al,byte ptr ds:
00401135|.75 1D         |jnz short Pusillus.00401154
00401137|.46            |inc esi                                           ;Pusillus.00403044
00401138|.47            |inc edi                                           ;Pusillus.00403008
00401139|.^ E2 F6         \loopd short Pusillus.00401131
把处理后的code的每个字节与00403008起始的每个字节进行比较,全部相等则通过校验
00403008起始的每个字节内容如下:
004030081B591871qY
0040300C4C454279yBEL

整个校验过程非常清楚,但是要从00403008起始的8个字节算出正确的注册码却要花一番心思。
作者在这里巧妙的利用大量的异或运算,异或运算最重要的就是交换律和结合律,以及a^a=0,a^0=a这四个性质

下面是keygen代码:
int main(int argc, char* argv[])
{
      unsigned int i;
      char szName = { 0x71, 0x18, 0x59, 0x1B, 0x79, 0x42, 0x45, 0x4C,0x00 };//对应从00403008起始的8个字节
      char szSerial = { 0 };
      unsigned char byResult=0;
      
      for (i = 0; i < 8; i++)
      {
                byResult ^= szName;
      }
      
      for (i = 0; i < 8; i++)
      {
                szSerial = szName ^ byResult;
      }
      
      for (i = 0; i < 8; i++)
      {
                szSerial = szSerial ^ 0x32;
      }
      
      printf("Serial:%s\r\n", szSerial);


      return 0;
}正确的注册码是:Z3r0Ring

---------------------------------------------------------------------------------------------------

这是以上有别人分析出来的,在没看别人分析的文章前,也把算法分析了一下,也明白是怎么一回事,但是就感觉不太可能存在这样的注册码,
之后看了别人的分析,和别人的分析过程是一样的,就是不知道如何写注册机,这里说的不会写注册机,不是说,不会用C语言来
写,而是说,怎么写这个注册机,思路是什么,是思路的问题,而不是某种语言的语法实现,是感觉逻辑上行不通,不会存在这样的注册码能满足注册成功。

当输入一个序列号时,每个字符都^0x32后,再^这个序列号内部某种运算后的一个值,结果等于
char szName = { 0x71, 0x18, 0x59, 0x1B, 0x79, 0x42, 0x45, 0x4C,0x00 }; 可能存在这种正确的序列号吗?
当在什么情况下,才会出现这种情况,,,想不明白。作者给出了a^a=0,a^0=a,这种解决方法,但是就是想不通,。。。。

所以想请高手给指点,卡在这里就是想不明白了。。上传下这个crackme.

梦游枪手 发表于 2016-6-26 21:24

本帖最后由 梦游枪手 于 2016-6-27 00:13 编辑

这个CM思路很绕,不理解很正常,因为这篇文章讲的不够详细。看下分析:
CM先把长度为8的code和0x32逐字节进行异或,然后运算一个字节p,我们先来分析一下算出p的过程。
p=[(1xor2)xor (3xor4)]xor [(5xor6)xor (7xor8)]
1=code xor 32h,2=code xor 32h,其他同理。
根据异或的结合律和交换律,可以看出来,这个字节其实就是1xor2xor3xor4xor...
然后就是x xor p的部分了,我把存放00403008的字节集记为s,以1为例子:
s=1 xor p
那现在要怎么得到code呢?
我们先整理下得到code的思路:
我们从上面可以得到
s=1 xor p
s=2 xor p
...
s=x xor p
根据异或运算的可逆性,x=s xor p
code=x xor 32
那p又要怎么得到?
从前面可以知道,p是code所有字节异或后的结果。
而s=x xor p
举两个例子
s=1 xor p
s=2 xor p 根据a xor a=0,我们可以得到
s xor s=1 xor 2而1 xor 2=(code xor 32h) xor (code xor 32h)
=(code xor code) xor (32h xor 32h)
=code xor code
以此类推,可以得出p是s所有字节异或后的结果。
而s是存放00403008的字节集,也就是已知了。
所以得到code的算法就是:
p=s xor s xor...
t=s xor p
code=t xor 32h
也就是文章中注册机的代码。最后一句是为了让字节处于字符串代码值的区间,也是CM作者设计好了的。
口误多,请见谅。
最后膜拜下写出这个CM的人{:6_197:}




退隐猫九_ 发表于 2016-6-26 21:36

{:5_188:}解密专家都求助了   小白就看着

菜鸟中的菜鸟 发表于 2016-6-26 21:44

退隐猫九_ 发表于 2016-6-26 21:36
解密专家都求助了   小白就看着

专家?我只是打酱油的菜鸟而已。

_BaZzi 发表于 2016-6-26 22:56

异或是可逆的
A^B=C -> A^C=B B^C=A
页: [1]
查看完整版本: 某Crackme算法分析的问题