飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4702|回复: 5

[转贴] ASProtect SKE 2.2 SDK中的API修复

[复制链接]
  • TA的每日心情
    慵懒
    2018-6-6 15:51
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2007-8-25 20:03:54 | 显示全部楼层 |阅读模式
    原文来自看雪学院:http://bbs.pediy.com/showthread.php?t=28790&tcatid=11

    标 题: ASProtect SKE 2.2 SDK中的API修复
    作 者: kanxue
    时 间: 2006-07-10,20:22
    链 接: http://bbs.pediy.com/showthread.php?t=28790

    【文章标题】: ASProtect SKE 2.2 SDK中的API修复
    【文章作者】: kanxue
    --------------------------------------------------------------------------------
    【详细过程】

       有关ASProtect的SDK,近期论坛不少文章涉及到了,如cyto的文章(本文一些补丁代码参考了cyto文章)。SDK的修复VolX、shoooo等大侠更是轻车熟路。这2天也学习了一下SDK修复,有少许心得,现拿出来希望大家帮忙指正一下。

        ASProtect的SDK种类比较多,本文主要介绍如何修复ASProtect自带的一些API,如GetHardwareID,CheckKeyAndDecrypt,GetRegistrationKeys,GetModeInformation,GetRegistrationInformation 等。  
        学习SDK最好的方法是将ASProtect的帮助文档看一遍,并结合其样例掌握用法。

    1.准备工作

       本文以ASProtect自带的样例Examples\Reg Trial\VC\ 来讨论。为了降低难度,我将样例中的REG_CRYPT_BEGIN1与REG_CRYPT_END1注释掉,这对标签是加密代码的,无key代码就不能解密,当然有key还得修复这段代码,修复方法类似stolen OEP。
    //REG_CRYPT_BEGIN1 //注释掉,不加密如下代码
      strcpy( caption, "Registered version!" );
      SetWindowText( hwnd, caption );
            GetModeInformation( 0, &ModeName, &mode_status );
      SetWindowText( GetDlgItem(hwnd,IDCANCEL), "Close" );
      ShowWindow(GetDlgItem(hwnd,IDC_BUYNOW), SW_HIDE);
      ShowWindow(GetDlgItem(hwnd,IDC_REG_BUTTON), SW_HIDE);
      wsprintf( buffer,"Key: %s\nName: \t\t%s\nMode Name: \t%s",UserKey, UserName, ModeName );
      SetDlgItemText(hwnd, IDC_TEXT, buffer);
            //REG_CRYPT_END1 //注释掉
    然后用VC 6.0编译Reg Trial样例,得到trial.exe文件,运行ASProtect主程序,打开该样例提供的reg_trial.aspr2项目文件,本文主要是讨论SDK修复,因此protectin Options全部不选。Modes部分reg_trial.aspr2己设置好,如图:


      然后点击Protect按钮将trial.exe加壳保护,生成的trial.exe无key运行是试用版,需要输入key才能为注册版。key可以在Activation keys栏生成:



    本例将加密标签REG_CRYPT_BEGIN1与REG_CRYPT_END1注释掉了,因此不存在解码问题。


    2.用脚本脱壳

       非常感谢VolX能与大家分享他那强大的脚本!OD加载trial.exe后,用ODbgScript 1.4x插件跑VolX的脚本:Asprotect 2.XX SKE IAT Fixer 。
    http://bbs.pediy.com/showthread.php?s=&threadid=24557
    运行一会儿,脚本有一个提示:“Import table is fixed, you can dump the file now or later. check the address and size of IAT in log window”
    点击确定后,再单击ODbgScript/Resume继续执行脚本,不一会儿就到OEP:“OEP found, no stolen code at the OEP!”。

    00401470    55              push    ebp                              ; trial.00400000
    00401471    8BEC            mov     ebp, esp
    00401473    6A FF           push    -1

    此时就可Dump取trial.exe程序了,并用ImportREC重建输入表:



    这里会发现有一些函数不能识别,这些函数就是ASProtect自己的API,可以直接Cut,就可重建输入表了,得到dumped_.exe。

    在OD里查看这些ASProtect的API,会发现它们与IAT其他函数靠在一起:

    00405000  00AA7FD8
    00405004  00AA7EC4
    00405008  00AA7CCC
    0040500C  00AA8024
    00405010  00AA7BE0
    00405014  00000000
    00405018  7C801D77  kernel32.LoadLibraryA
    0040501C  7C80AC28  kernel32.GetProcAddress
    00405020  7C9379FD  ntdll.RtlReAllocateHeap
    3.修复SDK

      如果此时运行脱壳后的文件dumped_.exe,就会异常,因为程序里会调用ASProtect的API函数:

    00404A18   $- FF25 0C504000 jmp     [40500C]  //F2下断点
    00404A1E   $- FF25 08504000 jmp     [405008]  //F2下断点
    00404A24   $- FF25 04504000 jmp     [405004]  //F2下断点
    00404A2A   $- FF25 00504000 jmp     [405000]  //F2下断点
    00404A30   $- FF25 10504000 jmp     [405010]  //F2下断点
    00404A36   $- FF25 A8504000 jmp     [<&kernel32.RtlUnwind>]          ;  ntdll.RtlUnwind

      接下来就是要猜这些API函数了,运行加壳的trial.exe,来到OEP后,对00404A18~00404A36这段代码下断点。再运行程序,首先会中断在00404A30这行。

    00404A18  - FF25 0C504000   jmp     [40500C]
    00404A1E  - FF25 08504000   jmp     [405008]
    00404A24  - FF25 04504000   jmp     [405004]
    00404A2A  - FF25 00504000   jmp     [405000]
    00404A30  - FF25 10504000   jmp     [405010]     //首先中断这行
    00404A36  - FF25 A8504000   jmp     [4050A8]                         ; ntdll.RtlUnwind

    然后查看堆栈,对返回地址设断:

    0012FA84   004011AA  返回到 trial.004011AA 来自 trial.00404A30
    0012FA88   00000000
    0012FA8C   004086C0  trial.004086C0
    0012FA90   004086C4  trial.004086C4

    对004011AA 设断后,会来到:

    00401196  |.  53            push    ebx
    00401197  |.  56            push    esi
    00401198  |.  57            push    edi
    00401199  |.  68 C4864000   push    004086C4
    0040119E  |.  68 C0864000   push    004086C0
    004011A3  |.  6A 00         push    0
    004011A5  |.  E8 86380000   call    00404A30
    004011AA  |.  8B3D C0864000 mov     edi, [4086C0]  //来到这里

    此时EAX=1,结合源码及ASProtect帮助文档,可以猜出这个是GetRegistrationInformation。
    用这种方法就可确定其他几个函数:

    00404A18  - FF25 0C504000   jmp     [40500C]                         ; GetHardwareID
    00404A1E  - FF25 08504000   jmp     [405008]                         ; CheckKeyAndDecrypt
    00404A24  - FF25 04504000   jmp     [405004]                         ; GetTrialDays
    00404A2A  - FF25 00504000   jmp     [405000]                         ; GetModeInformation
    00404A30  - FF25 10504000   jmp     [405010]                         ; GetRegistrationInformation
    00404A36  - FF25 A8504000   jmp     [4050A8]                         ; ntdll.RtlUnwind

    其中带key脱壳后,只有GetRegistrationInformation与GetModeInformation被调用(其他函数确定,请删除注册文件aspr_keys.ini尝试),因此只需要修复这2个函数即可。

    3.1 构造 GetRegistrationInformation函数的参数及返回值

    函数原型:
    GetRegistrationInformation( 0, &Key, &Name );  


    dumped_.exe程序中的代码:
    00401199  |.  68 C4864000   push    004086C4   //&Name
    0040119E  |.  68 C0864000   push    004086C0   //&Key
    004011A3  |.  6A 00         push    0
    004011A5  |.  E8 86380000   call    00404A30


    00404A30   $ /FF25 10504000 jmp     [405010]                         ;  GetRegistrationInformation

    找一段空地写下如下代码:

    00404A41         mov     eax, [esp+8]
    00404A45         mov     dword ptr [eax], 00404A5E        ;  ASCII "78787878" //参数Key
    00404A4B         mov     eax, [esp+C]
    00404A4F         mov     dword ptr [eax], 00404A68        ;  ASCII "pediy"   //参数Name
    00404A55         mov     eax, 1                           //返回值
    00404A5A         retn    0C

    00404A5E  37 38 37 38 37 38 37 38 00 00 70 65 64 69 79 00  78787878..pediy.

    再将00405010改成如下:
    00405010  41 4A 40 00                                      AJ@.

    这样jmp     [405010] 就能跳到00404A41 执行了。

    3.2 构造GetModeInformation函数的参数及返回值

    函数原型:
    GetModeInformation( 0, &ModeName, &mode_status );

    dumped_.exe程序中的代码:
    00401205    52              push    edx       //&mode_status
    00401206    68 CC864000     push    004086CC  //&ModeName
    0040120B    6A 00           push    0
    0040120D    E8 18380000     call    00404A2A // call GetModeInformation
    ……
    00404A2A  - FF25 00504000   jmp     [405000]                         ; GetModeInformation

    找一段空地写下如下代码:

    00404A79       mov     eax, [esp+8]
    00404A7D       mov     dword ptr [eax], 00404A8D        ;  ASCII "Registered"  //参数ModeName
    00404A83       mov     eax, 1
    00404A88       retn    0C

    00404A8D  52 65 67 69 73 74 65 72 65 64 00 00 00 00 00 00  Registered......

    再将00405000改成如下:
    00405000  79 4A 40 00         

    这样jmp     [405000]  就能跳到00404A79 执行了


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

                                                          2006年07月10日 20:10:21



    例子下载

    [ 本帖最后由 glts 于 2007-8-25 20:10 编辑 ]
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-8-28 13:23:13 | 显示全部楼层
    学习了~~~/:001
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2023-12-2 20:17
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2007-8-29 22:00:14 | 显示全部楼层
    学习学习/:023 /:023
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-5-19 12:19:35 | 显示全部楼层
    学习了,比较详细,相当不错,感谢,呵呵/:014
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-5-29 08:32:25 | 显示全部楼层
    呵呵。原来是段老大的贴。学习了。谢谢。
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2017-3-26 23:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2008-5-29 21:58:10 | 显示全部楼层
    好好学一学.
    每次总有收获
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表