首页
社区
课程
招聘
[原创]一个字节搞定12Ghost版NotePad
发表于: 2009-4-26 22:23 4901

[原创]一个字节搞定12Ghost版NotePad

2009-4-26 22:23
4901
【文章标题】: 一个字节搞定12Ghost版NotePad
【文章作者】: jackozoo
【作者邮箱】: [email]jackozoo@163.com[/email]
【软件名称】: 12Ghost Notepad
【下载地址】: 自己搜索下载
【保护方式】: NAG加序列号
【编写语言】: C++/ VS2005
【使用工具】: OD
【软件介绍】: 一款看起来很清爽的增强版记事本,生成rtf文档。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  没什么技术含量,希望对菜鸟朋友能有一些帮助,因此截了不少图。
  
  安装好软件后, 到目录中看看, 里面有很多文件, 打开运行看看, 结果提示如下的窗口。

   
  我们点击输入注册码看看, 随便输入一个,提示出错。如图:

  

  我们现在想,从哪里下手了? 先不慌。 看看启动代码。
  
  004141B7 >  E8 25630000     call    12notepa.0041A4E1   //ep
  004141BC  ^ E9 16FEFFFF     jmp     12notepa.00413FD7
  004141C1    55              push    ebp
  004141C2    8BEC            mov     ebp, esp
  004141C4    81EC 28030000   sub     esp, 328
  // 。。。
  
  //。。。
  00414140    51              push    ecx
  00414141    50              push    eax
  00414142    6A 00           push    0
  00414144    68 00004000     push    12notepa.00400000
  00414149    E8 325BFFFF     call    12notepa.00409C80
  //好的, 这里就是WinMain了。 (怎么确定?GetCommandLine之后,再加至少3个push压参就到了(Win)Main了)
  
  
  // ...
  看看这里WinMain进去的东西:
  00409CDD    56              push    esi
  00409CDE    68 FC2B4200     push    12notepa.00422BFC           ; ASCII "unused"
  00409CE3    68 D42B4200     push    12notepa.00422BD4           ; ASCII "http://12Ghosts.com/ghosts/notepad.htm"
  00409CE8    6A 47           push    47
  00409CEA    6A 4E           push    4E
  00409CEC    56              push    esi
  00409CED    56              push    esi
  00409CEE    56              push    esi
  00409CEF    56              push    esi
  00409CF0    68 C42B4200     push    12notepa.00422BC4           ; ASCII "12notepad.exe"
  00409CF5    68 B82B4200     push    12notepa.00422BB8           ; ASCII "notepad.htm"
  00409CFA    68 A82B4200     push    12notepa.00422BA8           ; ASCII "12Ghosts.hlp"
  00409CFF    68 F8244200     push    12notepa.004224F8           ; ASCII "Software\12Ghosts\NotePad"
  00409D04    68 A02B4200     push    12notepa.00422BA0           ; ASCII "NotePad"
  00409D09    68 A02B4200     push    12notepa.00422BA0           ; ASCII "NotePad"
  00409D0E    68 942B4200     push    12notepa.00422B94           ; ASCII "PactNotepad"
  00409D13    68 A02B4200     push    12notepa.00422BA0           ; ASCII "NotePad"
  00409D18    68 B0254200     push    12notepa.004225B0           ; ASCII "12Ghosts NotePad"
  00409D1D    50              push    eax
  00409D1E    E8 C78D0000     call    <jmp.&12Ghosts.#312>        ; 写入数据到dll变量中。
  00409D23    6A 32           push    32
  00409D25    6A 06           push    6
  00409D27    E8 B88D0000     call    <jmp.&12Ghosts.#11>
  00409D2C    83C4 54         add     esp, 54
  调用的是dll中以序号导出的函数, 其中第一个函数有19个参数, 真是第一次见到这么奇怪的函数。
  
  看看这个巨型函数中的一部分代码:
  
  // ... ...
  // 巨大一堆strcpy、、、
  // ... ...
  10002961   .  50            push    eax                         ; /String2
  10002962   .  68 10F70210   push    12Ghosts.1002F710           ; |String1 = 12Ghosts.1002F710
  10002967   .  880D 08F70210 mov     [1002F708], cl              ; |  
  1000296D   .  8815 09F70210 mov     [1002F709], dl              ; |
  10002973   .  FFD6          call    esi                         ; \lstrcpyA
  
  注意这一句: mov     [1002F708], cl 。这一句的cl是参数4的末字节的值。先在这打住。
  
  
  从下至上的思路:
  
  我们按OK的时候程序要读取Edit控件的文本,那就下相关API试试,bp GetWindowTextW ,
  bp GetDlgItemTextW(某菜鸟问:为什么后面都是W了? 因为如果软件在编码时定义了UNICODE,就会直接执行以W结尾的函数,
  而不会去执行以A结尾的外壳函数)。 OK, 对SetWindowTextW下好断,再按OK。 滴-- 还是弹窗了。看来没断下。 原因太多。
  
  那我们换种思路,用IsDialogMessageW条件加代码断点大法来确定OK按钮的事件地址。
  如下:
  10018BFE   .  0FB78424 7802>movzx   eax, word ptr [esp+278]     ;  Case 111 (WM_COMMAND) of switch 10018BDB
  10018C06   .  3D 0F040000   cmp     eax, 40F                    ;  Switch (cases 1..410)
  10018C0B   .  0F8F F9000000 jg      12Ghosts.10018D0A
  10018C11   .  74 63         je      short 12Ghosts.10018C76
  10018C13   .  83E8 01       sub     eax, 1
  10018C16   .  74 21         je      short 12Ghosts.10018C39
  10018C18   .  83E8 01       sub     eax, 1
  10018C1B   .  74 68         je      short 12Ghosts.10018C85
  10018C1D   >  5F            pop     edi                         ;  Default case of switch 10018C06
  10018C1E   .  5B            pop     ebx
  10018C1F   >  8B8C24 600200>mov     ecx, [esp+260]
  10018C26   .  5E            pop     esi
  10018C27   .  33CC          xor     ecx, esp
  10018C29   .  33C0          xor     eax, eax
  10018C2B   .  E8 CE370000   call    12Ghosts.1001C3FE
  10018C30   .  81C4 60020000 add     esp, 260
  10018C36   .  C2 1000       ret     10
  10018C39   >  68 F3010000   push    1F3                         ;  Case 1 of switch 10018C06
  10018C3E   .  8D4424 79     lea     eax, [esp+79]
  10018C42   .  6A 00         push    0
  10018C44   .  50            push    eax
  10018C45   .  C68424 800000>mov     byte ptr [esp+80], 0
  10018C4D   .  E8 BE370000   call    12Ghosts.1001C410
  10018C52   .  83C4 0C       add     esp, 0C
  10018C55   .  6A 64         push    64                          ; /Count = 64 (100.)
  10018C57   .  8D4C24 78     lea     ecx, [esp+78]               ; |
  10018C5B   .  51            push    ecx                         ; |Buffer
  10018C5C   .  68 29040000   push    429                         ; |ControlID = 429 (1065.)
  10018C61   .  56            push    esi                         ; |hWnd
  10018C62   .  FF15 4C730210 call    [<&USER32.GetDlgItemTextA>] ; \GetDlgItemTextA
  
  看到了吗? 上面竟然用的是GetDlgItemTextA来取的文本, 但是为什么我刚才用GetWindowTextW没断下来了, 真是奇了怪了,
  GetDlgItemText(X)都是先GetDlgItem再GetWindowText(X)的啊, 可能我第一次键盘操作失误吧,不管了。
  
  现在断下来, 我们看一下是不是我们的Edit控件, 看一下Buffer, 嗯, 执行完call后,有了我们的数据, 然后我们对
  Buffer来个内存读或者硬件读断点。 看看程序对我们的注册码打算咋处理。
  
  OK, 如图,第一次断到了lstrlen的里面, 这是在求长度。Alt+F9. 来到这里:
  10016FB2  |.  56            push    esi                         ; /String
  10016FB3  |.  884424 0A     mov     [esp+A], al                 ; |
  10016FB7  |.  884424 0B     mov     [esp+B], al                 ; |
  10016FBB  |.  884424 09     mov     [esp+9], al                 ; |
  10016FBF  |.  C74424 0C 000>mov     dword ptr [esp+C], 0        ; |
  10016FC7  |.  FF15 1C720210 call    [<&KERNEL32.lstrlenA>]      ; \lstrlenA
  10016FCD  |.  83F8 40       cmp     eax, 40
  10016FD0  |.  75 25         jnz     short 12Ghosts.10016FF7
  
  长度不是64,则玩完, 其实上面那个图都说了是64位注册码。
  
  我们改一下ZF,继续。
  10016FE7  |.  50            push    eax
  10016FE8  |.  6A 00         push    0
  10016FEA  |.  56            push    esi
  10016FEB  |.  E8 50EFFFFF   call    12Ghosts.10015F40
  10016FF0  |.  83C4 1C       add     esp, 1C
  10016FF3  |.  85C0          test    eax, eax
  10016FF5  |.  75 68         jnz     short 12Ghosts.1001705F
  10016FF7  |>  6A 00         push    0
  10016FF9  |.  68 D8AE0210   push    12Ghosts.1002AED8           ;  ASCII "The code you entered is not a valid license. Please double-click the file ::attached to your license e-mail.::::Or select the line with the code (64 characters) from your registration ::notification by dragging the mouse over it. Then se"...
  10016FFE  |.  E8 5D56FFFF   call    12Ghosts.1000C660
  10017003  |.  83C4 08       add     esp, 8
  10017006  |.  50            push    eax                         ; /String2
  10017007  |.  8D8C24 300300>lea     ecx, [esp+330]              ; |
  1001700E  |.  51            push    ecx                         ; |String1
  1001700F  |.  FF15 14720210 call    [<&KERNEL32.lstrcpyA>]      ; \lstrcpyA
  10017015  |.  A1 880D0310   mov     eax, [10030D88]
  1001701A  |.  68 41000500   push    50041                       ; /Style = MB_OKCANCEL|MB_ICONASTERISK|MB_APPLMODAL|50000
  1001701F  |.  68 00F00210   push    12Ghosts.1002F000           ; |Title = "12Ghosts NotePad"
  10017024  |.  8D9424 340300>lea     edx, [esp+334]              ; |
  1001702B  |.  52            push    edx                         ; |Text
  1001702C  |.  50            push    eax                         ; |hOwner => 002F1096 ('12Ghosts NotePad',class='#32770',parent=000910BE)
  1001702D  |.  FF15 E0730210 call    [<&USER32.MessageBoxA>]     ; \MessageBoxA
  
  
  
  所以12Ghosts.10015F40这个是我们目前认为的关键call了。 进去看一下,它在干什么了:
  
  // ... ...
  10015FB9  |.  6A 06         push    6                           ; /maxlen = 6
  10015FBB  |.  68 04AD0210   push    12Ghosts.1002AD04           ; |s2 = "YmUbRe"
  10015FC0  |.  56            push    esi                         ; |s1
  10015FC1  |.  E8 84760000   call    <12Ghosts._strncmp>         ; \_strncmp
  10015FC6  |.  83C4 0C       add     esp, 0C
  10015FC9  |.  85C0          test    eax, eax
  10015FCB  |.  0F84 F70E0000 je      <12Ghosts.完蛋了>
  10015FD1  |.  6A 06         push    6                           ; /maxlen = 6
  10015FD3  |.  68 FCAC0210   push    12Ghosts.1002ACFC           ; |s2 = "QBowyN"
  10015FD8  |.  56            push    esi                         ; |s1
  10015FD9  |.  E8 6C760000   call    <12Ghosts._strncmp>         ; \_strncmp
  10015FDE  |.  83C4 0C       add     esp, 0C
  10015FE1  |.  85C0          test    eax, eax
  10015FE3  |.  0F84 DF0E0000 je      <12Ghosts.完蛋了>
  10015FE9  |.  6A 06         push    6                           ; /maxlen = 6
  10015FEB  |.  68 F4AC0210   push    12Ghosts.1002ACF4           ; |s2 = "EJ2kgA"
  10015FF0  |.  56            push    esi                         ; |s1
  10015FF1  |.  E8 54760000   call    <12Ghosts._strncmp>         ; \_strncmp
  10015FF6  |.  83C4 0C       add     esp, 0C
  10015FF9  |.  85C0          test    eax, eax
  10015FFB  |.  0F84 C70E0000 je      <12Ghosts.完蛋了>
  
  // ... ...
  为了不占版面, 我省了很多代码, 这个函数里面全部是是strncmp(注册码,“xxxxxx”,6)的比较。 很长的一大路,
  就像那个我命名的lable“完蛋了”一样,其实是程序在检验黑名单。 只要你的注册码的前面6位和上述的黑名单的是一样的话,
  就会调到惩罚你的入口, 因为12Ghost出品的软件有很多, 它只要发现你用黑名单中的注册码来注册这个notepad的话,它会把
  你机器的注册表里面的其他的所有只要是它公司的软件的键值都删掉。
  
  所以上面那个call根本就不是所谓的关键call。那这个时候我们暂时先不去管算法了。
  我们看你弹错误窗口后,要干啥。 你总得把注册信息保存下吧。  
  
  看看这里:
  100170A1  |.  68 00F00210   push    12Ghosts.1002F000           ;  ASCII "12Ghosts NotePad"
  100170A6  |.  6A 00         push    0
  100170A8  |.  68 B0AE0210   push    12Ghosts.1002AEB0           ;  ASCII "Valid! Thank you for registering %s!"
  100170AD  |.  E8 AE55FFFF   call    12Ghosts.1000C660
  100170B2  |.  83C4 08       add     esp, 8
  100170B5  |.  50            push    eax
  100170B6  |.  8D8C24 400300>lea     ecx, [esp+340]
  100170BD  |.  51            push    ecx
  100170BE  |.  EB 1D         jmp     short 12Ghosts.100170DD
  100170C0  |>  68 9CAE0210   push    12Ghosts.1002AE9C           ;  ASCII "12Ghosts software"
  100170C5  |.  6A 00         push    0
  100170C7  |.  68 B0AE0210   push    12Ghosts.1002AEB0           ;  ASCII "Valid! Thank you for registering %s!"
  
  我们强行调到注册成功的MessageBoxA的, 然后往下跟。
  
  下面都是调用的12Ghost.dll中的函数, 你会发现, 它在里面一会打开注册表HKEY,一会关闭注册表的,大家可以跟
的试一下, 它并没有写入任何信息到注册表中。  
  那我想, 你这么喜欢用注册表,(其实从dll的一些函数的代码的代码里面都可以看出注册信息肯定在注册表中的)  
  那我们用RegMon来监视一下(或者直接下端Reg相关函数)。

  重启程序。
  bp RegQueryValueExW, F9 . 断下来了, 不过是些垃圾注册表信息, shift+F9。 几次之后终于到了我们所要的。
  
  程序要读取 HKCU/SoftWare/12Ghost/NotePad/RegCode的字符串值。 好的, 我们就从这出发,在注册表中建立这个项,
  
  其值就填写为“AAAAAAAA”吧,按从上倒下的思路搞、对buffer下访问断, 结果发现,断是断了几次了,不过基本没用
  
  到我们的注册码。NAG还是出现了。 不要气馁, NAG是吧, 我们断下DialogBoxParamW看看。  嗯:
  
  好,断下来了。 继续往上拉拉代码, 会发现这些东西:
  
  1001BA40   .  68 E8030000   push    3E8
  1001BA45   .  6A 01         push    1
  1001BA47   .  E8 6473FEFF   call    12Ghosts.10002DB0
  1001BA4C   .  83C4 08       add     esp, 8
  1001BA4F   .  3D B6030000   cmp     eax, 3B6
  1001BA54   .  A0 08F70210   mov     al, [1002F708]
  1001BA59   .  0F8F 86000000 jg      12Ghosts.1001BAE5
  1001BA5F   .  3C 4D         cmp     al, 4D
  1001BA61   .  0F84 C4000000 je      12Ghosts.1001BB2B
  1001BA67   .  3C 6D         cmp     al, 6D
  1001BA69   .  74 7A         je      short 12Ghosts.1001BAE5
  1001BA6B   .  3C 77         cmp     al, 77
  1001BA6D   .  74 76         je      short 12Ghosts.1001BAE5
  1001BA6F   .  3C 70         cmp     al, 70
  1001BA71   .  74 72         je      short 12Ghosts.1001BAE5
  1001BA73   .  3C 59         cmp     al, 59
  1001BA75   .  74 6E         je      short 12Ghosts.1001BAE5
  1001BA77   .  3C 79         cmp     al, 79
  1001BA79   .  74 6A         je      short 12Ghosts.1001BAE5
  1001BA7B   .  3C 6B         cmp     al, 6B
  1001BA7D   .  74 66         je      short 12Ghosts.1001BAE5
  1001BA7F   .  3C 4B         cmp     al, 4B
  1001BA81   .  74 62         je      short 12Ghosts.1001BAE5
  1001BA83   .  3C 65         cmp     al, 65
  1001BA85   .  74 5E         je      short 12Ghosts.1001BAE5
  1001BA87   .  8B15 64090310 mov     edx, [10030964]             ;  12Ghosts.10000000
  1001BA8D   .  6A 00         push    0                           ; /lParam = NULL
  1001BA8F   .  68 90990110   push    12Ghosts.10019990           ; |DlgProc = 12Ghosts.10019990
  1001BA94   .  6A 00         push    0                           ; |hOwner = NULL
  1001BA96   .  6A 7A         push    7A                          ; |pTemplate = 7A
  1001BA98   .  52            push    edx                         ; |hInst => 10000000
  1001BA99   .  C705 A4F80210>mov     dword ptr [1002F8A4], 0     ; |
  1001BAA3   .  FF15 C8720210 call    [<&USER32.DialogBoxParamA>] ; \DialogBoxParamA
  
  
  试了一下, 这个DialoagBoxParam就是弹NAG的,看前面的比较。 一堆单字节的比较。 而al = 什么了?
  
  答案在这里:1001BA54   .  A0 08F70210   mov     al, [1002F708] 。
  
  在回过头去看那个巨型函数。 呵呵, 找到最最关键的地方了吧.
  
  对。 就是这个参数:
  00409CEA    6A 4E           push    4E
  
  把这个4E改为4D来试试 。
  
  NAG没有了。  是否感觉被忽悠了 ?。。。。 的确我当时也觉得被忽悠了。
  
  既然无论输入什么注册码都不能成功还让我们输个P的注册码啊, 真是的。。   不过先别生气。
  我们来体验体验下消NAG后的软件, 打开,  点菜单栏的选项--一般选项, 怎么没反应了?  这时别点“一般选项”
  
  选择“Option”就可以了 。 一个一个标签的看啊看。。  翻到了关于标签:
  
  这么几个大字弄的我郁闷了N久 : 仅供评估的测试版,点击这里获得完全版。 晕怪不得啊。 原来是Demo版。
  
  
  看来我眼睛真的是不行了, 或者是太粗心了。。  到此打住。
  
  这个Demo版的里面有很多乱七八糟的信息, 来看看部分:
  1.
  1002A8AC  57 65 20 61 72 65 20 6E 6F 77 20 65 78 61 6D 69  We are now exami
  1002A8BC  6E 69 6E 67 20 79 6F 75 72 20 64 69 73 6B 20 66  ning your disk f
  1002A8CC  6F 72 20 66 75 72 74 68 65 72 20 73 74 6F 6C 65  or further stole
  1002A8DC  6E 20 69 6E 66 6F 72 6D 61 74 69 6F 6E           n information
  
  2、
  1002A8F0  57 65 20 61 72 65 20 63 6F 6E 74 61 63 74 69 6E  We are contactin
  1002A900  67 20 57 65 62 20 50 6F 6C 69 63 65 20 4F 72 67  g Web Police Org
  1002A910  61 6E 69 73 61 74 69 6F 6E 20 77 69 74 68 20 79  anisation with y
  1002A920  6F 75 72 20 49 50 20 6E 75 6D 62 65 72 20 6E 6F  our IP number no
  1002A930  77 2E 2E 2E                                      w...
  
  3.
  1002A930                          59 6F 75 20 75 6E 6C 61          You unla
  1002A940  77 66 75 6C 6C 79 20 75 73 65 64 20 74 68 69 73  wfully used this
  1002A950  20 73 6F 66 74 77 61 72 65 20 77 69 74 68 6F 75   software withou
  1002A960  74 20 61 20 76 61 6C 69 64 20 6C 69 63 65 6E 73  t a valid licens
  1002A970  65 2E                                            e.
  
  4.
  1002A970                          59 6F 75 20 66 72 61 75          You frau
  1002A980  64 75 6C 65 6E 74 6C 79 20 75 73 65 64 20 61 20  dulently used a
  1002A990  73 74 6F 6C 65 6E 20 63 72 65 64 69 74 20 63 61  stolen credit ca
  1002A9A0  72 64 20 74 6F 20 70 75 72 63 68 61 73 65 20 74  rd to purchase t
  1002A9B0  68 69 73 20 73 6F 66 74 77 61 72 65 2E           his software.
  
  5.
  1002A9C0  59 6F 75 20 73 74 6F 6C 65 20 61 20 63 72 65 64  You stole a cred
  1002A9D0  69 74 20 63 61 72 64 20 6F 72 20 61 72 65 20 61  it card or are a
  1002A9E0  20 72 65 63 65 69 76 65 72 20 6F 66 20 73 74 6F   receiver of sto
  1002A9F0  6C 65 6E 20 67 6F 6F 64 73 2E                    len goods.
  
  
  非常搞笑的一些字符串,呵呵。 有兴趣的朋友可以深究一下。

  
  
  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年04月26日 PM 10:19:12

[注意]APP应用上架合规检测服务,协助应用顺利上架!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发 顶 学习之
2009-4-26 22:50
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
下面都是调用的12Ghost.dll中的函数, 你会发现, 它在里面一会打开注册表HKEY,一会关闭注册表的。 什么都没干。
  

我看未必!
2009-4-27 13:02
0
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
4
感谢lxt大侠的纠正, 。 说“什么都没干”的确有点不合适,

不过我发现不管怎么样无论如何它都不会将注册信息写入到注册表中。 虽然它启动时
会去注册表读RegCode这一字符串值,不过和NAG窗口的弹出没半点关系。
毕竟才是个Demo版的 ...  
也可能我分析的不够仔细,忽略了作者的一些技巧。
2009-4-27 19:32
0
游客
登录 | 注册 方可回帖
返回
//