lknight 发表于 2013-3-23 15:25

新手破解epubtopdf--算法跟踪

本帖最后由 lknight 于 2013-3-23 15:28 编辑

【软件名称】: epubtopdf v2.0.4
【软件大小】: 4.79m
【下载地址】: http://www.epub-to-pdf.com/?soft
【加壳方式】: 无壳
【保护方式】: 序列号
【编写语言】: Microsoft Visual C++ 6.0
【使用工具】: PEiD,ollydbg
【操作平台】: win8

【详细过程】
      这个软件是本身没啥太大用处,只是为了提高技术找的练习软件,是比较简单的那种,适合新手。废话不多说,下面开始正题了。
      
      这个软件也可以直接用Universal Extractor解包,作为绿色软件使用的,这个软件给用户15次的试用次数,过了15次就变成下图的启动窗口
      
      下面是破解完成后的破解效果图
      
   下面我们就开始了,软件装好后,直接把15次试用全部试用玩,我们运行软件,随便输入用户名和注册码点击注册,会看到下面图中所示内容,再点击确定程序就推出了
   
    上面图片中的expired就是关键的内容,我们OD载入程序搜索字符串,如下图
   
   双击上图的字符串位置,来到下图的位置
   
   在上图位置可以往上找可以跳过这一提示的跳转,发现上面有这样的跳转,那么我们就拉倒段首下F2断点,F9运行程序,程序断下来了,下图
   
      我们一路F8看程序有什么变化,知道走到下图的call位置,程序状态变为run了,下图
   
   我们在程序中随意输入的用户名和注册码,点击注册按钮,程序暂停了,下图
   
   我们继续往下走F8,看看程序在下面的call中都做了什么,走到下面两个临近的一样的调用call我们看到他们是把用户名和注册码压栈了,下图
   
   用户名和注册码入栈就说明这些信息可能要进行检测了,后面的call我们全都进去看看,进第一个call,下图
   
      上图中我们看到,有两个CALL 0048285A,再次将用户名和注册码入栈了,那么,我们就直接看之后的那个call干了什么吧,跟进CALL 0040EAD0,下图
   
   上图中,我们还是F8一步一步分析,CALL 0040ED30什么都没做,我就不截图了,接着的那个call,CALL 0047C6E8,是检测输入的注册码中是否有链接符“-”的,我们可以跟进看一下
      
   上图中的CALL 0047C6F6,跟进
   
   上图中的CALL 0042CB56,跟进
   
   上图中对连接符的检测分析完了之后的代码没有什么重要的,我们一直返回到CALL 0047C6E8下一行,继续分析,不重要的call我就不跟进了
   
   我这里只分析了跳转实现后的内容,长度不等于16的情况我就不分析了,有兴趣的朋友自己分析吧,下图,是跳转实现后的位置
   
   上面这段代码就是把输入的注册码分成8组,每组两个字符,并计算每组字符在“N3NANBN4NCNDNHNJNKNMP3PAPBP4PCPDPHPJPKPMA3ANABA4ACADAHAJAKAMH3HAHBH4HCHDHNHJHKHMJ3JAJBJ4JCJDJHJNJKJMK3KAKBK4KCKDKHKJKNKMB3BABNB4”
      这个表中的位置,然后把每组字符的位置数值右移1位,存放在0018A06C地址,程序运行到上图中最后一行0040EBBF位置是,我们可以在命令框中输入db 0018A06C看到下图中读取输入字符在上表中的位置
      
       输入的注册码中的所有字符位置都得到后,程序就到了下面的位置,就是最终检验注册码是否正确的位置
      
       上图中的CALL 0040ED70,里面计算过程不复杂,我就不详细说了,其实,可以在程序执行到0040EBFE的位置的时候修改0018A06C出保存的1-4组字符(也就是前八个)位置,让位置的数值等于
   上面两个call算出来的数值,然后运行就可以了,当然你也可以修改后面的跳转,当然这是爆破,下面我详细说下这个软件的注册机制,并给出c语言编写的注册机。

   上面的分析基本分析完了,下面我总结一下这个软件的注册机制:
   首先,由上面的分析可以知道,注册码的内容必须有“N3NANBN4NCNDNHNJNKNMP3PAPBP4PCPDPHPJPKPMA3ANABA4ACADAHAJAKAMH3HAHBH4HCHDHNHJHKHMJ3JAJBJ4JCJDJHJNJKJMK3KAKBK4KCKDKHKJKNKMB3BABNB4”中的内容组成, 当然了,这是注册码长度为16的情况(长度不为16的情况各位看官自己玩玩吧),从分析中我们也可以看出,用户名没有参与注册码运算,同样连接符“-”也是可有可无的,同样,连接符“-”的位置也是可以随意调整的, 最终计算过程没有用到连接符。
      下面就是算法的具体过程了,首先我们假设输入的注册码是:N3NANBN4-NCNDNHNJ(连接符随意加的方便看,不加也行),这样我们会在内存0018A06C的位置看到这样的16进制数据0001020304050607(注意这是07是高位), 接着把5、6组字符的位置信息取出,组成一个16位的数据及0x0504,这个数据为输入调用CALL 0040ED70(本人水平有限,这个函数只能用汇编了,用c没有搞定。。。汗一个。。。),计算得到一个16位数据,假设这个数据为 0xXXYY,那么XX就对应于01,YY就对应于00,如果都像等的话,就说明这部分注册码是正确的;同样取出7、8组字符位置数值组成16位数据0x0706,这个数据为输入,调用CALL 0040ED70,同样得到一个16位数据结果,假设这个 结果是0xZZWW,那么,ZZ对应于07,WW对应于06,如果都像等的话就说明这部分注册码是正确的。这个软件的注册码计算过程就是这样,但是需要注意的是,输入的注册码中有可能某一组字符可能在表中出现了两次,那么就得 注意了,这样可能造成计算得到的位置和读取的位置错位的现象,我的做法是只用没有重复的字符串。。。

      注册机源码(VC 6.0编译通过)keygen.cpp:
      #include "windows.h"
#include "stdio.h"
#include "wchar.h"
#include <time.h>

int GenResult(int input);

int main()
{
      WCHAR table[] = L"N3NANBN4NCNDNHNJNKNMP3PAPBP4PCPDPHPJPKPMA3ANABA4ACADAHAJAKAMH3HAHBH4HCHDHNHJHKHMJ3JAJBJ4JCJDJHJNJKJM";
      int result_tmp = 1,tmp1,tmp2;
      int pos={0};
      int tablelen = wcslen(table);
      WCHAR wstr1=L"";
      WCHAR wstr2=L"";
      WCHAR wstr3=L"";
      WCHAR wstr4=L"";
      WCHAR wstr5=L"";
      WCHAR wstr6=L"";
      WCHAR wstr7=L"";
      WCHAR wstr8=L"";
      srand((unsigned)time(NULL));
      for(int i=4; i<8; i+=2)
      {
                for(;;)
                {
                        pos = rand()%(tablelen-1);
                        pos = rand()%(tablelen-1);
                        tmp1 = pos>>1;
                        tmp2 = pos>>1;
                        result_tmp = GenResult(tmp1 | (tmp2<<8));
                        if(i==4)
                        {
                              if (tmp1>0x31 || tmp2>0x31)
                              {
                                        continue;
                              }
                              else
                              {
                                        pos = (result_tmp & 0x0FF)<<1;
                                        pos = ((result_tmp>>8) & 0x0FF)<<1;
                                        wstr1=table];
                                        wstr1=table+1];
                                        wstr2=table];
                                        wstr2=table+1];
                                        wstr5=table];
                                        wstr5=table+1];
                                        wstr6=table];
                                        wstr6=table+1];
                                        if ((wcsstr(table,wstr1)-&table] <0)|| (wcsstr(table,wstr2) - &table]<0) ||
                                                (wcsstr(table,wstr5)-&table] <0)|| (wcsstr(table,wstr6) - &table]<0))
                                        {
                                                continue;
                                        }
                                        else
                                        {
                                                break;
                                        }
                              }
                        }
                        else
                        {
                              if (tmp1>0x31 || tmp2>0x31)
                              {
                                        continue;
                              }
                              else
                              {
                                        pos = (result_tmp & 0x0FF)<<1;
                                        pos = ((result_tmp>>8) & 0x0FF)<<1;
                                        wstr3=table];
                                        wstr3=table+1];
                                        wstr4=table];
                                        wstr4=table+1];
                                        wstr7=table];
                                        wstr7=table+1];
                                        wstr8=table];
                                        wstr8=table+1];
                                        if ((wcsstr(table,wstr3)-&table] <0)|| (wcsstr(table,wstr4) - &table]<0) ||
                                                (wcsstr(table,wstr7)-&table] <0)|| (wcsstr(table,wstr8) - &table]<0))
                                        {
                                                continue;
                                        }
                                        else
                                        {
                                                break;
                                        }
                              }
                        }
                }
      }

      wprintf(L"%s%s%s%s%s%s%s%s\n",wstr1,wstr2,wstr3,wstr4,wstr5,wstr6,wstr7,wstr8);

      return 0;
}

int GenResult(int input)
{
      int re;
      _asm
      {
                pushad
                mov ecx,input
                mov ebx,0x351D
                mov esi,0x5A39
                mov edi,0x1
label1: test bl,0x1
                jnz label3
label2:      mov eax,ecx
                xor edx,edx
                imul eax,ecx
                div esi
                shr ebx,1
                test bl,0x1
                mov ecx,edx
                je label2
label3: mov eax,edi
                xor edx,edx
                imul eax,ecx
                div esi
                dec ebx
                mov edi,edx
                jnz label1
                mov eax,edi
                mov re,eax
                popad
      }
      return re;
}
            第一次写算法跟踪,写的比较乱,高手勿笑。。。
                                                                                 by lknight
--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!

                                                       2013年03月23日 14:55:23

Chief 发表于 2013-3-23 16:05

写的不错,希望继续发布好破文,
吾爱破解论坛有你更精彩。

taotao 发表于 2013-3-23 16:08

不错,支持下

Victory.ms 发表于 2013-3-23 16:09

挖槽,那个算法。。无语了

chenlinhui 发表于 2013-3-23 16:37

看看   学习一下

zhangbaida 发表于 2013-3-23 17:13

高手,学习一下哈

kantal 发表于 2013-3-23 18:07

不错 很详细值得学习一下~~谢谢分享~

RedAngel丶 发表于 2013-3-23 19:40

膜拜,学习下

音美乐纯 发表于 2013-3-23 20:03

看不懂啊,不会编程

silent_grief 发表于 2013-3-23 22:09

顶下帖子了。新手来照着一部一部的做,会得到 成就感的。
页: [1] 2 3
查看完整版本: 新手破解epubtopdf--算法跟踪