playboysen 发表于 2008-8-7 20:27:52

【七夕礼物】Power Video Converter算法分析+另类注册机

【破文标题】Power Video Converter算法分析+另类注册机
【破文作者】p layboysen
【作者主页】p layboysen2.photo.163.com
【破解工具】PEiD,OD
【破解平台】Windows XP
【软件名称】Power Video Converter
【软件大小】1.01 MB
【软件类别】国外软件/视频转换
【软件授权】共享版
【软件语言】英文
【更新时间】2008-8-7
【原版下载】http://www.apussoft.com/
【保护方式】用户名、注册码
【软件简介】Power Video Converter可以在AVi, MPEG1, MPEG2, VCD, SVCD, DVD, WMV, ASF, DAT, VOB文件格式之间进行转换,同时具有很快的转换速度和友好的使用界面。
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享:)
初学破解与编程,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------
【破解内容】
   
   大三暑期的实习,嘴里能闲出鸟来。
   趁没毕业不抓紧时间学点自己喜欢的东西,怕这后半生真像张雨生说的那样“在太阳下低头,流着汗水默默辛苦的工作”,所以啊,找资料学Delphi、找目标练习算法分析,这是近期我的第三篇算法总结了吧,也许大家不记得了,但我自己记得——每次盯着几百行汇编代码反复来看一旦没头绪连睡觉都辗转反侧的无奈和辛苦。
   没的说,就是这样,就算受了冷落,我也不会放弃自己想要的生活。加油!
   
   试运行软件发现在其左侧有“Registration”按钮,注册错误有提示,PEID查壳得知软件无壳,OD载入查找字符很轻松找到关键处,不紧不慢咱们仔细分析:00421BBA   .8B46 64       mov   eax, dword ptr                   ;假码"963852741"
00421BBD   .8B4E 60       mov   ecx, dword ptr                   ;用户名"senhuan"
00421BC0   .8D5E 64       lea   ebx, dword ptr
00421BC3   .8D7E 60       lea   edi, dword ptr
00421BC6   .50            push    eax
00421BC7   .51            push    ecx
00421BC8   .E8 73FEFFFF   call    00421A40                                 ;用户名和假码同时入栈,关键call
00421BCD   .83C4 08       add   esp, 8
00421BD0   .85C0          test    eax, eax
00421BD2   .75 15         jnz   short 00421BE9
00421BD4   .6A 40         push    40
00421BD6   .68 14894300   push    00438914                                 ;sorry
00421BDB   .68 E8884300   push    004388E8                                 ;invalid username or registration code
00421BE0   .8BCE          mov   ecx, esi
00421BE2   .E8 5F5C0000   call    <jmp.&MFC42.#4224_CWnd::MessageBoxA>跟进00421BC8处的call:00421A40/$8B5424 04   mov   edx, dword ptr                    ;用户名“senhuan”
00421A44|.56            push    esi
00421A45|.57            push    edi
00421A46|.BF F08B4300   mov   edi, 00438BF0
00421A4B|.8BF2          mov   esi, edx
00421A4D|.B9 01000000   mov   ecx, 1
00421A52|.33C0          xor   eax, eax
00421A54|.F3:A6         repe    cmps byte ptr es:, byte ptr    ;比较用户名是不是输入
00421A56|.74 2B         je      short 00421A83
00421A58|.8B4424 10   mov   eax, dword ptr                   ;假码“963852741”
00421A5C|.53            push    ebx
00421A5D|.BF F08B4300   mov   edi, 00438BF0
00421A62|.8BF0          mov   esi, eax
00421A64|.B9 01000000   mov   ecx, 1
00421A69|.33DB          xor   ebx, ebx
00421A6B|.F3:A6         repe    cmps byte ptr es:, byte ptr    ;比较假码是否输入
00421A6D|.5B            pop   ebx
00421A6E|.74 13         je      short 00421A83
00421A70|.50            push    eax
00421A71|.52            push    edx
00421A72|.E8 99FDFFFF   call    00421810                                 ;用户名和假码同时入栈,又是关键call,跟进
00421A77|.83C4 08       add   esp, 8
00421A7A|.F7D8          neg   eax
00421A7C|.1BC0          sbb   eax, eax
00421A7E|.5F            pop   edi
00421A7F|.F7D8          neg   eax
00421A81|.5E            pop   esi
00421A82|.C3            retn
00421A83|>5F            pop   edi
00421A84|.33C0          xor   eax, eax
00421A86|.5E            pop   esi
00421A87\.C3            retn跟进00421A72的call(省略部分代码):……
0042185F|.8B4C24 38   mov   ecx, dword ptr                   ;假码放入ECX
00421863|.8BD8          mov   ebx, eax                                 ;用户名放入EBX,下面关键处会用到
00421865|.51            push    ecx
00421866|.8D4C24 14   lea   ecx, dword ptr
0042186A|.E8 FD5D0000   call    <jmp.&MFC42.#537_CString::CString>
0042186F|.8D4C24 10   lea   ecx, dword ptr
00421873|.C64424 2C 01mov   byte ptr , 1
00421878|.E8 DF610000   call    <jmp.&MFC42.#6282_CString::TrimLeft>
0042187D|.8D4C24 10   lea   ecx, dword ptr
00421881|.E8 D0610000   call    <jmp.&MFC42.#6283_CString::TrimRight>
00421886|.6A 20         push    20
00421888|.8D4C24 14   lea   ecx, dword ptr
0042188C|.E8 9F600000   call    <jmp.&MFC42.#2915_CString::GetBuffer>
00421891|.8BD0          mov   edx, eax                                 ;假码放入EDX
00421893|.83CE FF       or      esi, FFFFFFFF
00421896|.8BFA          mov   edi, edx
00421898|.8BCE          mov   ecx, esi
0042189A|.33C0          xor   eax, eax
0042189C|.895424 20   mov   dword ptr , edx                  ;放假码是用来求其长度
004218A0|.F2:AE         repne   scas byte ptr es:         
004218A2|.F7D1          not   ecx                                    ;这三句是用来求字符串长度的另一种方法
004218A4|.49            dec   ecx                                 
004218A5|.8BFB          mov   edi, ebx
004218A7|.8BE9          mov   ebp, ecx
004218A9|.8BCE          mov   ecx, esi
004218AB|.F2:AE         repne   scas byte ptr es:
004218AD|.F7D1          not   ecx                                    ;求用户名长度
004218AF|.49            dec   ecx
004218B0|.3BCD          cmp   ecx, ebp
004218B2|.0F87 54010000 ja      00421A0C                                 ;此处得知用户名长度必须小于注册码
004218B8|.8BFB          mov   edi, ebx
004218BA|.8BCE          mov   ecx, esi
004218BC|.F2:AE         repne   scas byte ptr es:
004218BE|.F7D1          not   ecx
004218C0|.49            dec   ecx
004218C1|.0F84 45010000 je      00421A0C                                 ;检测用户名和注册码是不是为空
004218C7|.8BFA          mov   edi, edx
004218C9|.8BCE          mov   ecx, esi
004218CB|.F2:AE         repne   scas byte ptr es:
004218CD|.F7D1          not   ecx
004218CF|.49            dec   ecx
004218D0|.0F84 36010000 je      00421A0C
004218D6|.894424 38   mov   dword ptr , eax
004218DA|>8B5424 38   /mov   edx, dword ptr
004218DE|.8D4C24 34   |lea   ecx, dword ptr
004218E2|.8A82 A8884300 |mov   al, byte ptr
004218E8|.884424 18   |mov   byte ptr , al
004218EC|.E8 BD5A0000   |call    <jmp.&MFC42.#540_CString::CString>
004218F1|.8BFB          |mov   edi, ebx
004218F3|.83C9 FF       |or      ecx, FFFFFFFF
004218F6|.33C0          |xor   eax, eax
004218F8|.33ED          |xor   ebp, ebp
004218FA|.F2:AE         |repne   scas byte ptr es:
004218FC|.F7D1          |not   ecx
004218FE|.49            |dec   ecx                                     ;此时ECX中是用户名长度
004218FF|.C64424 2C 02|mov   byte ptr , 2
00421904|.74 4B         |je      short 00421951
00421906|>8A042B      |/mov   al, byte ptr                ;EBX中放的是用户名,用户名每个字母依次放入al中
00421909|.33F6          ||xor   esi, esi
0042190B|>3A0475 408843>||/cmp   al, byte ptr          ;在00438840处有一个密码表,是计算注册码的关键
00421912|.74 08         |||je      short 0042191C
00421914|.46            |||inc   esi
00421915|.83FE 34       |||cmp   esi, 34
00421918|.^ 7C F1         ||\jl      short 0042190B
0042191A|.EB 11         ||jmp   short 0042192D
0042191C|>8A0C75 418843>||mov   cl, byte ptr             ;这里的字符串是用户名所对应的密码表转换后的值
00421923|.51            ||push    ecx
00421924|.8D4C24 38   ||lea   ecx, dword ptr
00421928|.E8 1B5D0000   ||call    <jmp.&MFC42.#940_CString::operator+=>
0042192D|>83FE 34       ||cmp   esi, 34
00421930|.75 0E         ||jnz   short 00421940
00421932|.8B5424 18   ||mov   edx, dword ptr
00421936|.8D4C24 34   ||lea   ecx, dword ptr
0042193A|.52            ||push    edx
0042193B|.E8 085D0000   ||call    <jmp.&MFC42.#940_CString::operator+=>
00421940|>8BFB          ||mov   edi, ebx
00421942|.83C9 FF       ||or      ecx, FFFFFFFF
00421945|.33C0          ||xor   eax, eax
00421947|.45            ||inc   ebp
00421948|.F2:AE         ||repne   scas byte ptr es:
0042194A|.F7D1          ||not   ecx
0042194C|.49            ||dec   ecx
0042194D|.3BE9          ||cmp   ebp, ecx                               ;EBP是循环的次数,ECX是用户名位数
0042194F|.^ 72 B5         |\jb      short 00421906
00421951|>8B4424 34   |mov   eax, dword ptr                ;用户名和密码表对应换算成的一串字符(注册码一部分)设为R1
00421955|.8B48 F8       |mov   ecx, dword ptr                   ;用户名长度放入ECX
00421958|.83F9 10       |cmp   ecx, 10                                 ;比较用户名是不是大于16位
0042195B|.7D 3A         |jge   short 00421997
0042195D|.8BC1          |mov   eax, ecx
0042195F|.B9 10000000   |mov   ecx, 10
00421964|.2BC8          |sub   ecx, eax                              ;如果用户名长度(设为len)小于16位,算出(16-len)
00421966|.8D5424 1C   |lea   edx, dword ptr
0042196A|.51            |push    ecx
0042196B|.52            |push    edx
0042196C|.B9 C48E4300   |mov   ecx, 00438EC4                        
00421971|.E8 D45A0000   |call    <jmp.&MFC42.#4129_CString::Left>      ;可疑之处,等会跟进看看
00421976|.50            |push    eax
00421977|.8D4C24 38   |lea   ecx, dword ptr
0042197B|.C64424 30 03|mov   byte ptr , 3
00421980|.E8 BD5C0000   |call    <jmp.&MFC42.#939_CString::operator+=>
00421985|.8D4C24 1C   |lea   ecx, dword ptr
00421989|.C64424 2C 02|mov   byte ptr , 2
0042198E|.E8 0F5A0000   |call    <jmp.&MFC42.#800_CString::~CString>
00421993|.8B4424 34   |mov   eax, dword ptr                ;两部分注册码连接,即R1+R2(出现了明码)
00421997|>8B4C24 20   |mov   ecx, dword ptr
0042199B|.51            |push    ecx                                     ; /s2
0042199C|.50            |push    eax                                     ; |s1
0042199D|.FF15 B4D64200 |call    dword ptr [<&MSVCRT._mbscmp>]         ; \_mbscmp 比较真假码
004219A3|.83C4 08       |add   esp, 8
004219A6|.8D4C24 34   |lea   ecx, dword ptr
004219AA|.85C0          |test    eax, eax
004219AC|.C64424 2C 01|mov   byte ptr , 1
004219B1|.74 1B         |je      short 004219CE                        ;真正的关键跳
004219B3|.33F6          |xor   esi, esi
004219B5|.E8 E8590000   |call    <jmp.&MFC42.#800_CString::~CString>
004219BA|.8B4424 38   |mov   eax, dword ptr
004219BE|.40            |inc   eax
004219BF|.83F8 03       |cmp   eax, 3
004219C2|.894424 38   |mov   dword ptr , eax
004219C6|.^ 0F8C 0EFFFFFF \jl      004218DA
004219CC|.EB 0A         jmp   short 004219D8
004219CE|>BE 01000000   mov   esi, 1跟进00421971的call:……
73D86480    33FF            xor   edi, edi
73D86482    8B01            mov   eax, dword ptr                      ; 另外一截密码表"ESqNCdaYoDciekuS"
73D86484    3B78 F8         cmp   edi, dword ptr
73D86487    7C 0B         jl      short 73D86494
73D86489    51            push    ecx
73D8648A    8B4D 08         mov   ecx, dword ptr
73D8648D    E8 FFDEFAFF   call    #535_CString::CString
73D86492    EB 3C         jmp   short 73D864D0
73D86494    56            push    esi
73D86495    8D4D 0C         lea   ecx, dword ptr
73D86498    E8 BFC1FAFF   call    #540_CString::CString
73D8649D    8B4D F0         mov   ecx, dword ptr
73D864A0    6A 00         push    0
73D864A2    6A 00         push    0
73D864A4    33F6            xor   esi, esi
73D864A6    57            push    edi
73D864A7    8D45 0C         lea   eax, dword ptr
73D864AA    46            inc   esi
73D864AB    50            push    eax
73D864AC    8975 FC         mov   dword ptr , esi
73D864AF    E8 27710000   call    #1589_CString::AllocCopy
73D864B4    8B4D 08         mov   ecx, dword ptr                    ; 加入刚刚算出的(16-len)为9,则从第一位开始截取第二组密码表"ESqNCdaYoDciekuS"9位并取出(注册码第二部分)设为R2
73D864B7    8D45 0C         lea   eax, dword ptr
73D864BA    50            push    eax
73D864BB    E8 D1DEFAFF   call    #535_CString::CString至此,算法过程逐渐明朗:
1、软件事先定义两组密码表如下:
   单步走到0042190B处,查看数据窗口可知第一处密码表:aGbmcldSemfkgEhcixjsktlYmbnkoDptqarfswtlujvDwIxPyZzXAPBoCKDgEyFmGtHaIrJqKNLQMUNuOGPJQLRnSbTCUFVHWoXwYEZpvMw
   在73D86482会出现第二处密码表:ESqNCdaYoDciekuS
2、软件依次取出用户名每一位根据第一处密码表换算成密码表中的字符,从而生成一个和用户自己输入的用户名相同的字符串
3、然后判断用户名是不是大于16位,若小于则算出(16-len),然后从第二处密码表开头依次取出(16-len)位,并且与第2步的字串连接作为注册码;若不小于16位,则直接把根据第一处密码表换算生成的字串作为注册码

根据研究发现要把这段汇编“翻译”成高级语言还真不太容易,灵机一动想到一个另类的方法,呵呵:
OD载入,用户名我们输入“abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”,注册码随便,然后单步到004218B2时不要让跳转实现(会跳向错误),当单步到00421951时,出现一个字符串“GmlSmkEcxstYbkDtafwljDIPZXPoKgymtarqNQUuGJLnbCFHowEp”,呵呵,这就是大小写52个字母分别对应的注册码值,用这个字符串来选个注册码看看

用户名:p layboysen(因为我们论坛有文字自动过滤,所以我在p的后面故意加了一个空格,试验的时候请自行去除)
对应
注册码:tYGZmDZwmk

因为我们的用户名只有10位,那么16-10=6,从第二个密码表中取出前6位“ESqNCd”
最终注册码为: tYGZmDZwmkESqNCd

今天七夕,天比较晚了,还要赶着回去给GF打电话去呢,注册机就先不写了,有时间再补上,同时也祝愿大家有情人终成眷属,七夕快乐!/:013

[ 本帖最后由 playboysen 于 2008-8-8 08:12 编辑 ]

foxjinlin 发表于 2008-8-7 21:41:34

强烈支持

十分强大

xiakexing 发表于 2008-8-7 21:44:27

学习一下,先谢谢楼主了

hggg 发表于 2008-8-7 22:06:09

写得真详细,楼主辛苦了。

116690450 发表于 2008-8-8 02:03:12

哎,我这水平能达到这样就好了!

playboysen 发表于 2008-8-8 08:07:39

版主是不是把论坛的文字过滤系统给改一下啊,连我的名字“p layboysen”都给我过滤了的,呜呜

Nisy 发表于 2008-8-8 08:57:29

原帖由 **sen 于 2008-8-8 08:07 发表 https://www.chinapyg.com/images/common/back.gif
版主是不是把论坛的文字过滤系统给改一下啊,连我的名字“p layboysen”都给我过滤了的,呜呜

坚持过奥运感谢兄弟分享 ~

retext123 发表于 2008-8-8 18:43:05

不错!学习了!感谢楼主分享:victory:

playboysen 发表于 2008-8-9 10:33:43

呵呵,补充注意事项:
1、软件会把任何单个中文字符用密码表换算成“vv”,即如果用户名是“飘云阁”,则在00421951设断会发现R1为“vvvvvv”(6位),然后再用16-6=10,从第二处密码表“ESqNCdaYoDciekuS”取出十位并连接,即为注册码(用户名:飘云阁 注册码:vvvvvvESqNCdaYoD)
2、注册成功后要重启软件才能在About中看到效果
3、注册码保存在软件根目录videoconvert.ini文件中

Enjoy~~

dnuu47803877 发表于 2008-8-9 11:55:58

不错,不错

支持支持
:loveliness: :loveliness: :loveliness:
页: [1] 2
查看完整版本: 【七夕礼物】Power Video Converter算法分析+另类注册机