【文章标题】: Aspr2.1 inline patching _Chord Pickout
【文章作者】: clide2000[DFCG]
【作者邮箱】: 54armai@sina.com
【软件名称】: chordpickout v1.6
【下载地址】: 自己搜索下载
【加壳方式】: ASProtect 2.1x SKE -> Alexey Solodovnikov
【保护方式】: 20天试用
【使用工具】: OD,LordPE,WinHex
【操作平台】: Xp_sp2
【作者声明】: 在完成了此次Inline Patching后才发现,这个程序并不是直接修改此Pre-Dip后就可以注册的,和和fly兄的试练品"Tag&Rename V3.2 RC3 "比较像,所以还得找出其他的暗桩才能正式注册。但这并不影响下面讨论的方法。
(因为比较懒,还未找出其他限制的暗桩,所以在Patching后,得到仍是个“试用已过期”的程序。)
  
失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------

【简单说明】
  在正式开始前,讲下自已对Aspr1.X与Aspr2.x的Inline patching不同点:
  对于Aspr1.X:
  1、需要找到"获得ASProtect注册名Pre-Dip处理的地址"(并找出其代码地址在文件中的偏移,和有关数据运算数据 + 求逆);
  2、得到壳重定位后的基址;
  3、RegOpenKeyExA,要得到壳通过读取注册表中的信息判断是否过期的地方。
  4、Patch最终处理。
  
  
  对于Aspr2.X:
  1、需要找到"获得ASProtect注册名Pre-Dip处理的地址"(但已经无法直接在文件中找到其对应的偏移了,因为壳用了循环解码,所以在这增

加了难度)(第一处不同点)▲
  2、增加了对内存代码的检验。(第二处不同点)▲
  2、得到壳重定位后的基址;
  3、RegOpenKeyExA,要得到壳通过读取注册表中的信息判断是否过期的地方。
  4、所以在Patch时,不会像Aspr1.X时那么容易了。必须从壳第一次循环解码时开始Patch(直接修改文件中的相应代码),像传递接力棒一

样。一直Patch到最终完全解码,之后的操作就和Aspr1.X比较相似了,只是要多处理一个CRC校验( MapViewOfFileEx)(第三处不同点)▲
  5、对于Patch代码的存放地也不一样了。像Aspr1.X时的400080那地方太小,已经不够用了。所在一般都要事先用WinHex之类的工具,在文件

尾部增加定量的字节,同进还要用LordPe之类的修改一下文件最后.data段的VSize和RSize都改为对应的新值。(第四处不同点)▲
  
  以上只是个人的感觉,如果错误之处,还请各位兄弟指正。
  
  这次的文章是参考了"Inline Patch ASProtect 2.X 学习笔记 by temerata"和"Inline Patch注册AsPrtect V2.X保护程序——Tag&Rename 

V3.2 RC3 by fly"。算是对这两篇文章的理解与实际运用,文中依然会有多处这两脱文的影子,包括原文的引用和书写风格:)
  ------------------------------------------------------------------------------------------------------------
  一点建议:
  如果对Aspr1.X的Inline Patching还有没完全掌握的朋友,建议先补下课。(推荐:fly老大的“Patch注册ASProtect V1.X壳保护程序的方

法”),这样再来玩Aspr2.X的Inline Patching就可以循序渐进,轻松一些。
  
  -------------------------------------------------------------------------------------------------------------
  
  
 【详细过程】
 
  一、用OllyDbg打开chordpickout.exe,隐藏OllyDbg(以下不再赘述),寻找注册名的Pre-dip和那三个跳转(方法请参考fly老大的“Patch注

册ASProtect V1.X壳保护程序的方法”)。
  0103CAB9    50                 push eax                        ;; 01023A29
  //◆ 记住这里
  0103CABA    8B47 04            mov eax, dword ptr ds:[edi+4]
  //◆ 记住这里
  0103CABD    FFD0               call eax                        ;;Pre-dip 
  
  
  0048C6C8    55                 push ebp
  0048C6C9    8BEC               mov ebp, esp
  0048C6CB    A1 78D74A00        mov eax, dword ptr ds:[4AD778]
  0048C6D0    8B55 08            mov edx, dword ptr ss:[ebp+8]   ; 01023A29,存放注册名
  0048C6D3    E8 7883F7FF        call chordpic.00404A50
  0048C6D8    5D                 pop ebp
  0048C6D9    C2 0400            retn 4
  
  0048C6D9 处返回到壳的代码之后查找全部命令——>push 20019,可以找到6个跳转:
  
  
  地址       反汇编                                    注释
  0102A299   call 010256D4                             (初始 CPU 选择)
  0102A376   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  0102A3E2   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  0102A495   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  0102A57D   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  0103E1C3   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  0103E260   call 010256D4                             jmp 到 advapi32.RegOpenKeyExA
  
  一般修改后面3个CALL后的跳转就行了,记住这几个地方
  
  //◆ 记住这里
  0102A57D    E8 52B1FFFF        call 010256D4                              ; jmp 到 advapi32.RegOpenKeyExA
  0102A582    85C0               test eax, eax
  0102A584    75 30              jnz short 0102A5B6
  //⑴☆修改成
  //0102A584  eb 30              jmp short 0102A5B6
  
  
  0103E1C3    E8 0C75FEFF        call 010256D4                              ; jmp 到 advapi32.RegOpenKeyExA
  0103E1C8    85C0               test eax, eax
  0103E1CA    75 42              jnz short 0103E20E
  //⑵☆修改成
  //0103E1CA  eb 42              jmp short 0103E20E
  
  
  0103E260    E8 6F74FEFF        call 010256D4                              ; jmp 到 advapi32.RegOpenKeyExA
  0103E265    85C0               test eax, eax
  0103E267    0F85 88000000      jnz 0103E2F5
  //⑶☆修改成
  //0103E267   /E9 89000000        jmp 0103E2F5
  //0103E26C   |90                 nop
  
  ----------------------------------------------------------------------------
  二、获取壳代码重定位基址,设置OD忽略所有异常+壳代码完全解压
  Ctrl+F2重新载入
  HE VirtualAlloc    Shift+F9,中断2次后取消断点,Alt+F9返回
  
  
  0052F496    68 00100000        push 1000
  0052F49B    FFB5 08040000      push dword ptr ss:[ebp+408]
  0052F4A1    6A 00              push 0
  0052F4A3    FF95 F0030000      call dword ptr ss:[ebp+3F0]
  0052F4A9    8985 CC010000      mov dword ptr ss:[ebp+1CC], eax
  0052F4AF    8B9D 00040000      mov ebx, dword ptr ss:[ebp+400]
  0052F4B5    039D 0D040000      add ebx, dword ptr ss:[ebp+40D]
  0052F4BB    50                 push eax
  0052F4BC    53                 push ebx
  0052F4BD    E8 04010000        call chordpic.0052F5C6
  0052F4C2    6A 40              push 40
  0052F4C4    68 00100000        push 1000
  0052F4C9    FFB5 08040000      push dword ptr ss:[ebp+408]
  0052F4CF    6A 00              push 0
  0052F4D1    FF95 F0030000      call dword ptr ss:[ebp+3F0]
  0052F4D7    8985 31040000      mov dword ptr ss:[ebp+431], eax
  //返回到这里
  //[ebp+431]=[0052F823]=01020000 壳代码重定位基址  ★与aspr1.x的一样
  0052F4DD    8985 D0010000      mov dword ptr ss:[ebp+1D0], eax
  0052F4E3    64:67:A1 0000      mov eax, dword ptr fs:[0]
  0052F4E8    8985 2D040000      mov dword ptr ss:[ebp+42D], eax
  0052F4EE    8B55 5B            mov edx, dword ptr ss:[ebp+5B]
  0052F4F1    8B85 D0010000      mov eax, dword ptr ss:[ebp+1D0]
  0052F4F7    8902               mov dword ptr ds:[edx], eax
  0052F4F9    8B85 08040000      mov eax, dword ptr ss:[ebp+408]
  0052F4FF    8942 04            mov dword ptr ds:[edx+4], eax
  0052F502    8D85 9F030000      lea eax, dword ptr ss:[ebp+39F]
  0052F508    8B40 55            mov eax, dword ptr ds:[eax+55]
  0052F50B    8942 08            mov dword ptr ds:[edx+8], eax
  0052F50E    8B85 EC030000      mov eax, dword ptr ss:[ebp+3EC]
  0052F514    8942 10            mov dword ptr ds:[edx+10], eax
  0052F517    8B85 E8030000      mov eax, dword ptr ss:[ebp+3E8]
  0052F51D    8942 14            mov dword ptr ds:[edx+14], eax
  0052F520    8B95 CC010000      mov edx, dword ptr ss:[ebp+1CC]
  0052F526    BB F8010000        mov ebx, 1F8
  0052F52B    8B7C1A 0C          mov edi, dword ptr ds:[edx+ebx+C]
  0052F52F    0BFF               or edi, edi
  0052F531    74 1E              je short chordpic.0052F551
  0052F533    8B4C1A 10          mov ecx, dword ptr ds:[edx+ebx+10]
  0052F537    0BC9               or ecx, ecx
  0052F539    74 11              je short chordpic.0052F54C
  0052F53B    03BD D0010000      add edi, dword ptr ss:[ebp+1D0]
  0052F541    8B741A 14          mov esi, dword ptr ds:[edx+ebx+14]
  0052F545    03F2               add esi, edx
  0052F547    C1F9 02            sar ecx, 2
  0052F54A    F3:A5              rep movs dword ptr es:[edi], dword ptr ds:[esi]
  0052F54C    83C3 28            add ebx, 28
  0052F54F  ^ EB DA              jmp short chordpic.0052F52B
  0052F551    8B85 CC010000      mov eax, dword ptr ss:[ebp+1CC]
  0052F557    50                 push eax
  0052F558    8B95 D0010000      mov edx, dword ptr ss:[ebp+1D0]
  0052F55E    52                 push edx
  0052F55F    8B18               mov ebx, dword ptr ds:[eax]
  0052F561    03DA               add ebx, edx
  0052F563    8B85 E4030000      mov eax, dword ptr ss:[ebp+3E4]
  0052F569    8903               mov dword ptr ds:[ebx], eax
  0052F56B    8B85 E8030000      mov eax, dword ptr ss:[ebp+3E8]
  0052F571    8943 04            mov dword ptr ds:[ebx+4], eax
  0052F574    8B85 EC030000      mov eax, dword ptr ss:[ebp+3EC]
  0052F57A    8943 08            mov dword ptr ds:[ebx+8], eax
  0052F57D    5F                 pop edi
  0052F57E    5E                 pop esi
  0052F57F    8B46 04            mov eax, dword ptr ds:[esi+4]
  0052F582    03C7               add eax, edi
  0052F584    8985 C7010000      mov dword ptr ss:[ebp+1C7], eax
  0052F58A    8B55 5B            mov edx, dword ptr ss:[ebp+5B]
  0052F58D    8B85 C7010000      mov eax, dword ptr ss:[ebp+1C7]
  0052F593    8942 0C            mov dword ptr ds:[edx+C], eax
  0052F596    8D9D 0D040000      lea ebx, dword ptr ss:[ebp+40D]
  0052F59C    53                 push ebx
  0052F59D    6A 00              push 0
  0052F59F    6A 00              push 0
  0052F5A1    6A 01              push 1
  0052F5A3    57                 push edi
  0052F5A4    8B5E 08            mov ebx, dword ptr ds:[esi+8]
  0052F5A7    03DF               add ebx, edi
  0052F5A9    53                 push ebx
  0052F5AA    68 00800000        push 8000
  //◆ 记住这里 
  
  0052F4A3和0052F4D1 分别是第1次和第2次调用VirtualAlloc,在第2次调用以后可以Patch以获得壳的基址,这里我沿用JohnWho的方法,选

择0052F5AA处作为Patch点,EDI保存了基址。
  
  
  
  壳代码完全解压
  
  (需要在第3次调用以后VirtualAlloc,先找个patch点,接着才能patch壳代码完全解压后的地方,原因在下边有提示)
  此时F9继续运行,中断后,Alt+F9,F8 返回到:
  
  010510CA    8985 75294400      mov dword ptr ss:[ebp+442975], eax
  //返回到这
  010510D0    8D9D 452A4400      lea ebx, dword ptr ss:[ebp+442A45]
  010510D6    50                 push eax
  010510D7    53                 push ebx
  010510D8    E8 74050000        call 01051651
  010510DD    8BC8               mov ecx, eax
  010510DF    8DBD 452A4400      lea edi, dword ptr ss:[ebp+442A45]
  010510E5    8BB5 75294400      mov esi, dword ptr ss:[ebp+442975]
  010510EB    F3:A4              rep movs byte ptr es:[edi], byte ptr ds:[esi]
  010510ED    8B85 75294400      mov eax, dword ptr ss:[ebp+442975]
  010510F3    68 00800000        push 8000
  //我选择在这里patch,用于在得到基址后,而在壳代码完全解压前的一个patch点,承上启下。
  //◆ 记住这里 
  010510F8    6A 00              push 0
  010510FA    50                 push eax
  010510FB    FF95 7D294400      call dword ptr ss:[ebp+44297D]
  01051101    8D0E               lea ecx, dword ptr ds:[esi]
  01051103    8551 2C            test dword ptr ds:[ecx+2C], edx
  01051106    44                 inc esp
  01051107    07                 pop es                                              ; 段寄存器更改
  01051108    50                 push eax
  01051109    C3                 retn
  
  继续,再次Alt+f9,F8后返回到:
  
  0105130D    8B9D 552A4400      mov ebx, dword ptr ss:[ebp+442A55]
  //返回到这
  01051313    0BDB               or ebx, ebx
  01051315    74 0A              je short 01051321
  01051317    8B03               mov eax, dword ptr ds:[ebx]
  01051319    8785 592A4400      xchg dword ptr ss:[ebp+442A59], eax
  0105131F    8903               mov dword ptr ds:[ebx], eax
  01051321    8DB5 712A4400      lea esi, dword ptr ss:[ebp+442A71]
  01051327    833E 00            cmp dword ptr ds:[esi], 0
  0105132A    0F84 D3000000      je 01051403
  01051330    8DB5 712A4400      lea esi, dword ptr ss:[ebp+442A71]
  
  Ctrl+B向下找B8 01 00 00 00 C2 0C 00,看到AsPrtect解压壳代码的那个循环
  
  010515C1    61                 popad
  //◆ 记住这里
  
  010515C2    75 08              jnz short 010515CC
  010515C4    B8 01000000        mov eax, 1 
  //找到了这里
  010515C9    C2 0C00            retn 0C
  010515CC    68 00000000        push 0
  010515D1    C3                 retn
  
  
  
  {
  //这是fly兄快速度定位到"壳代码完全解压"的方法。
  
  
  壳代码完全解压,设置OD忽略所有异常.
  
  Ctrl+F2重新载入
  HE GetModuleHandleA    Shift+F9,中断2次后取消断点,Alt+F9返回
  010514A6    FF95 EC314400      call dword ptr ss:[ebp+4431EC]
  010514AC    85C0               test eax, eax                       ; kernel32.7C800000
  //返回到这里
  010514AE    75 07              jnz short 010514B7
  010514B0    53                 push ebx
  
  
  Ctrl+F向下找popad,看到AsPrtect解压壳代码的那个循环
  
  010515C1    61                 popad
  //记住这里  ★
  010515C2    75 08              jnz short 010515CC
  010515C4    B8 01000000        mov eax, 1 
  //找到了这里
  010515C9    C2 0C00            retn 0C
  010515CC    68 00000000        push 0
  010515D1    C3                 retn
  
  提示:做到这里时,我产生了一些疑问,因为在fly主脱文中,在对上边这个010515C1  popad的patch之前,也就是其文中第七点的patch是

如何确定的,好像没有交代清楚(也可能是我漏掉了吧)。
  结合temerata的文章得知,在第2次调用VirtualAlloc后,可以得到基址,但上面010515C1  popad这段代码还没有解码,而是等到第3次调用

VirtualAlloc后,才得到完全解码。所以得在第3次调用VirtualAlloc后找个地patch一下。
  这里我找的patch点是:
  010510F3    68 00800000        push 8000
  
  
  }
  
  
  ----------------------------------------------------------------------------------------------------
  四、自校验:
  
  接下来一步是要逃过CRC检验,清除VirtualAlloc处的断点,然后bp MapViewOfFileEx,断下后返回到壳代码:
  
  
  01038668    6A 04              push 4
  0103866A    A1 14B40401        mov eax, dword ptr ds:[104B414]
  0103866F    50                 push eax
  01038670    A1 E4970401        mov eax, dword ptr ds:[10497E4]
  01038675    8B40 08            mov eax, dword ptr ds:[eax+8]
  01038678    FFD0               call eax
  0103867A    8BD8               mov ebx, eax                         ; 返回到这里 
  //记住这里  ★
   
  只要修改01038668处的4改为1,EXE文件的内存映像就会是可写的;
  而返回到0103867A后,EAX保存了EXE文件内存映像的开始地址,在我这里是01230000  ★★★,因而选择这一行作为Patch点。
  
  最后一个Patch点我选择了0103CAB9 ,就是进入注册名Pre-dip前的地方。
  
  所有的Patch点都清楚了。下面要开妈patch了。
  
  
  
  五、Patch
  
  1、准备工作
  
  将源chordpickout.exe复制一份为其它名字,我这里复制为clide.exe。用WinHex 
  
  打开chordpickout.exe,在文件最后添加大小为1000H的90H,用PE Editor将.adata区段的RSize改为1000H。这是因为chordpickout.exe文件

内没
  
  有什么区段间的空隙放置Patch代码,而JohnWho的文章中就是采用这种方法。我想如果有区段间空隙,将Patch代码放在那些空隙里应该也是


  
  以的。
  
  2、写Patch代码的地址
  OD载入clide.exe,忽略所有异常,F9运行,会弹出消息框说文件损坏云云,不用管它,定位到.adata段,可以发现那片本应全是Nop的代码

前面有一块被壳覆盖为0了,往下看没有被覆盖的地方,那里就是我们可以写入Patch代码的地方了。我这里选择00556400。
  
  3、修复文件第一处解码循环
  
  Ctrl+F2重新载入
  00401000 >  68 01F05200        push clide.0052F001
  //OD载入后
  00401005    E8 01000000        call clide.0040100B
  0040100A    C3                 retn
  0040100B    C3                 retn
  
  
  F7单步走,看ASProtect解压壳代码
  
  0052F164    81FF 9CF8FFFF      cmp edi, -764
  0052F16A    0F85 1E000000      jnz chordpic.0052F18E
  0052F170    66:81E8 8E89       sub ax, 898E
  
  //解码循环   第1个点  接口   ★
  0052F16A  - E9 91720200        jmp clide.00556400
  0052F16F    90                 nop
  
  
  在0052F170 处F4,可以看到下面的代码发生了变化,我想这个可以作为是否是解码循环的判断依据吧。0052F16A处是最先要Patch的地方。
  可以用LordPe的FLC功能查出,0052F16A对应的偏移为:0008516A。
  现在关闭OD,用WinHex打开cldie.exe,定位到偏移:0008516A,修改原内容0F85 1E000000为E9 9172020090,保存。
  
  
  4、开始正式编写patch代码
  
  打开OD,载入刚才修改好的clide.exe
  (从现在开始将像接力赛跑一样,从第一处“解码循环”开始,一直patch到“壳的代码完全解码”。
  
  Ctrl+G:00556400
  
  Patch代码:
  00556400  - 0F85 888DFDFF      jnz clide.0052F18E
  //0052F16A 代码挪这里执行
  00556406    C705 6AF15200 0F85>mov dword ptr ds:[52F16A], 1E850F  
  00556410    66:C705 6EF15200 0>mov word ptr ds:[52F16E], 0
  //还原0052F16A处修改的代码
  
  mov dword ptr ds:[52F26F], 271B5
  //Patch 0052F26E处跳转
  
  00556423  - E9 488DFDFF        jmp clide.0052F170
  // 返回原处继续
  
  
  
  第二个解码循环
  0052F256    5E                 pop esi
  0052F257    81FA 80F9FFFF      cmp edx, -680
  0052F25D    0F85 19000000      jnz chordpic.0052F27C
  0052F263    50                 push eax
  0052F264    68 0FBCAC15        push 15ACBC0F
  0052F269    0FB7CF             movzx ecx, di
  0052F26C    59                 pop ecx
  0052F26D    5B                 pop ebx
  0052F26E    E9 23000000        jmp chordpic.0052F296
  //解码循环   Patch 点    ★
  
  改成:
  0052F26E  - E9 B5710200     jmp clide.00556428
  
  
  
  Patch代码:
  00556428    C705 6FF25200 2300>mov dword ptr ds:[52F26F], 23
  //还原0052F26E处修改的代码
  
  00556432    C705 36F35200 E90F>mov dword ptr ds:[52F336], 2710FE9
  0055643C    66:C705 3AF35200 0>mov word ptr ds:[52F33A], 9000
  ////Patch 0052F336处跳转
  
  00556445  - E9 248EFDFF        jmp clide.0052F26E
  // 返回原处继续
  
  
  
  
  第三个解码循环
  0052F311    BE 530C100D        mov esi, 0D100C53
  0052F316    81C6 BCDE271F      add esi, 1F27DEBC
  0052F31C    81EA 9A892B02      sub edx, 22B899A
  0052F322    66:8BCB            mov cx, bx
  0052F325    81C2 96892B02      add edx, 22B8996
  0052F32B    66:81E7 9F0D       and di, 0D9F
  0052F330    81FA 34FAFFFF      cmp edx, -5CC
  0052F336  ^ 0F85 8DFFFFFF      jnz chordpic.0052F2C9
  //解码循环   Patch 点    ★
  0052F33C    53                 push ebx
  
  
  改成:
  //0052F336  - E9 0F710200     jmp clide.0055644A
  //0052F33B    90              nop
  
  
  Patch代码:
  0055644A  - 0F85 798EFDFF      jnz clide.0052F2C9
  //00052F336  代码挪这里执行
  
  00556450    C705 36F35200 0F85>mov dword ptr ds:[52F336], FF8D850F
  0055645A    66:C705 3AF35200 F>mov word ptr ds:[52F33A], 0FFFF
  //还原0052F336处修改的代码
  
  00556432    C705 36F35200 E90F>mov dword ptr ds:[52F3e4], 27092E9
  0055643C    66:C705 3AF35200 0>mov word ptr ds:[52F3e8], 9000
  //Patch 0052F3e4处跳转
  
  00556476  - E9 C18EFDFF        jmp clide.0052F33C
  // 返回原处继续
  
  
  第四个解码循环:
  
  0052F3D9    66:81E3 510A       and bx, 0A51
  0052F3DE    81FA D8FAFFFF      cmp edx, -528
  0052F3E4  ^ 0F85 ADFFFFFF      jnz chordpic.0052F397
  //解码循环   Patch 点    ★
  0052F3EA    66:8BCF            mov cx, di
  
  //改成:
  0052F3E4  - E9 92700200     jmp clide.0055647B
  0052F3E9    90              nop
  
  
  Patch代码:
  
  0055647B  - 0F85 168FFDFF      jnz clide.0052F397
  //0052F3E4  代码挪这里执行
  
  00556481    C705 E4F35200 0F85ADFF     mov dword ptr ds:[52F3E4], FFAD850F
  0055648B    66:C705 E8F35200 FFFF      mov word ptr ds:[52F3E8], 0FFFF
  //还原0052F3e4处修改的代码
  
  00556494    C705 51F55200 E9566F02     mov dword ptr ds:[0052F5AA], 26F56E9
  //Patch  0052F5AA处
  
  0055649E  - E9 478FFDFF                 jmp clide.0052F3EA
  // 返回原处继续
  
  
  
  
  第五个点:获取壳代码重定位基址
  
  0052F5A4    8B5E 08                     mov ebx, dword ptr ds:[esi+8]
  0052F5A7    03DF                        add ebx, edi
  0052F5A9    53                          push ebx
  0052F5AA    68 00800000                 push 8000
  //此时,edi中存放着基址   Patch 点    ★
  0052F5AF    6A 00                       push 0
  0052F5B1    56                          push esi
  
  
  改成: 
  0052F5AA  - E9 F46E0200     jmp clide.005564A3
  
  
  Patch代码:
  005564A3    C705 AAF55200 68008000      mov dword ptr ds:[52F5AA], 800068
  //还原0052F5AA处修改的代码
  
  005564AD    893D 00655500               mov dword ptr ds:[556700], edi
  //找个位置存放壳的基址,我这里选择556700
  
  005564B3    60                          pushad
  005564B4    9C                          pushfd
  005564B5    A1 00655500                 mov eax, dword ptr ds:[556700]
  005564BA    C780 F3100300 E9DA5350      mov dword ptr ds:[eax+310F3], 5053DAE9
  //; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
  
  005564C4    C680 F7100300 FF            mov byte ptr ds:[eax+310F7], 0FF
  //Patch 010510F3 处,当执行到这里时,程序就已经完全解码了
  
  005564CB    9D                          popfd
  005564CC    61                          popad
  005564CD  - E9 D890FDFF                 jmp clide.0052F5AA
  
  
  
  
  
  第六个点:程序已经完全解码
  010510EB    F3:A4           rep movs byte ptr es:[edi], b>
  010510ED    8B85 75294400   mov eax, dword ptr ss:[ebp+44>
  010510F3    68 00800000     push 8000
  //承上启下  Patch 点    ★
  //我选择在这里patch,用于在得到基址后,而在壳代码完全解压前的一个patch点,承上启下。
  
  010510F8    6A 00           push 0
  010510FA    50              push eax
  
  改成:
  010510F3  - E9 DA5350FF     jmp clide.005564D2
  
  
  Patch代码:
  005564D2    60                        pushad                                  ; 保存现场
  005564D3    9C                        pushfd
  005564D4    A1 00675500               mov eax, dword ptr ds:[556700]          ; 取得基址
  005564D9    C780 F3100300 68008000    mov dword ptr ds:[eax+310F3], 800068    ; 还原Patch点代码
  005564E3    C680 F7100300 00          mov byte ptr ds:[eax+310F7], 0
  005564EA    C780 C1150300 68146555    mov dword ptr ds:[eax+315C1], 55651468  ; Patch 010515C1处的代码
  005564F4    C680 C5150300 00          mov byte ptr ds:[eax+315C5], 0
  005564FB    C680 C6150300 C3          mov byte ptr ds:[eax+315C6], 0C3
  00556502    05 F3100300               add eax, 310F3                          ; 取得Patch点地址
  00556507    A3 0F655500               mov dword ptr ds:[55650F], eax          ; 修改下面Push的地址
  0055650C    9D                        popfd                                   ; 恢复现场
  0055650D    61                        popad
  0055650E    68 00000000               push 0                                  ; Push 返回地址,由00556507处设定
  00556513    C3                        retn
  
  
  
  第七个点:
  00F415C1    61              popad
  //patch点,此时壳已经完全解码了
  00F415C2    75 08           jnz short 00F415CC
  00F415C4    B8 01000000     mov eax, 1
  00F415C9    C2 0C00         retn 0C
  00F415CC    68 00000000     push 0
  00F415D1    C3              retn
  
  改成:
  00F415C1    68 14655500     push 556514
  00F415C6    C3              retn
  
  
  
  Patch代码:
  00556514    60                           pushad                                  ; 保存现场
  00556515    9C                           pushfd
  00556516    A1 00675500                  mov eax, dword ptr ds:[556700]          ; 取得基址
  0055651B    C780 C1150300 617508B8       mov dword ptr ds:[eax+315C1], B8087561  ; 还原Patch点代码
  00556525    C680 C5150300 01             mov byte ptr ds:[eax+315C5], 1
  0055652C    C680 C6150300 00             mov byte ptr ds:[eax+315C6], 0
  00556533    C680 69860100 01             mov byte ptr ds:[eax+18669], 1          ; 修改01038668处的Push 4为Push 1,使内存映

像可写
  0055653A    C780 7A860100 68646555       mov dword ptr ds:[eax+1867A], 55656468  ; Patch 0103867A处的代码
  00556544    C680 7E860100 00             mov byte ptr ds:[eax+1867E], 0
  0055654B    C680 7F860100 C3             mov byte ptr ds:[eax+1867F], 0C3
  00556552    05 C1150300                  add eax, 315C1                          ; 取得Patch点地址
  00556557    A3 5F655500                  mov dword ptr ds:[55655F], eax          ; 修改下面Push的地址
  0055655C    9D                           popfd                                   ; 恢复现场
  0055655D    61                           popad
  0055655E    68 00000000                  push 0                                  ; Push 返回地址,由00556557处设定
  00556563    C3                           retn
  
  
  第八个点:
  01038668    6A 01              push 1
  0103866A    A1 14B40401        mov eax, dword ptr ds:[104B414]
  0103866F    50                 push eax
  01038670    A1 E4970401        mov eax, dword ptr ds:[10497E4]
  01038675    8B40 08            mov eax, dword ptr ds:[eax+8]
  01038678    FFD0               call eax
  0103867A    8BD8               mov ebx, eax                         ; 返回到这里 
  //patch点,在执行完  MapViewOfFileEx后,恢复这前的push 4
  
  改成:
  01038668    6A 04              push 4
  
  
  Patch代码:
  00556564    C780 6A510800 0F851E00    mov dword ptr ds:[eax+8516A], 1E850F       ; 还原0052F16A 在内存映像中相应位置的代码,

即是之前直接修改文件中偏移:0008516A的代码
  0055656E    66:C780 6E510800 0000     mov word ptr ds:[eax+8516E], 0
  00556577    C680 99030000 00          mov byte ptr ds:[eax+399], 0               ; 还原内存映像中.adata段的RSize为0,这两句

是为了逃过CRC校验
  0055657E    60                        pushad
  0055657F    9C                        pushfd
  00556580    A1 00675500               mov eax, dword ptr ds:[556700]             ; 取得基址
  00556585    C680 69860100 04          mov byte ptr ds:[eax+18669], 4             ; 还原01038668处的代码
  0055658C    C780 7A860100 8BD850E8    mov dword ptr ds:[eax+1867A], E850D88B     ; 还原0103867A的代码
  00556596    66:C780 7E860100 4A01     mov word ptr ds:[eax+1867E], 14A
  0055659F    C780 B9CA0100 E9069B62    mov dword ptr ds:[eax+1CAB9], 629B06E9     ; Patch 0103CAB9,即Pre-dip前的位置
  //; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
  005565A9    66:C780 BDCA0100 FF90     mov word ptr ds:[eax+1CABD], 90FF
  005565B2    05 7A860100               add eax, 1867A                             ; 取得Patch点地址
  005565B7    A3 BF655500               mov dword ptr ds:[5565BF], eax             ; 修改下面Push的地址
  005565BC    9D                        popfd                                      ; 恢复现场
  005565BD    61                        popad
  005565BE    68 00000000               push 0                                     ; Push 返回地址,由005565B7处设定
  005565C3    C3                        retn                                        
  
  
  
  第九个点:Pre-dip前的位置
  0103CAB9    50                 push eax                        ;; 01023A29
  //Patch点,这是最后一次patch了
  0103CABA    8B47 04            mov eax, dword ptr ds:[edi+4]
  0103CABD    FFD0               call eax                        ;;Pre-dip 
  
   
  改成:
  00F2CAB9  - E9 069B62FF     jmp test_cli.005565C4
  00F2CABE    90              nop
  
  
  Patch代码:
  005565C4    68 60665500               push clide.00556660     ; ASCII "clide2000[DFCG]"
  //; Push 注册名的存放位置,取代原来的Push eax,这个可以在这些Patch代码后面找个地方,并填上自己的大名。
  005565C9    60                        pushad
  005565CA    9C                        pushfd
  005565CB    A1 00675500               mov eax, dword ptr ds:[556700]
  005565D0    C780 B9CA0100 508B4704    mov dword ptr ds:[eax+1CAB9], 4478B50     ; 还原0103CAB9处代码
  005565DA    66:C780 BDCA0100 FFD0     mov word ptr ds:[eax+1CABD], 0D0FF
  005565E3    C680 7DA30000 EB          mov byte ptr ds:[eax+A37D], 0EB           ; Patch试用信息读写跳转
  005565EA    C680 E9A30000 EB          mov byte ptr ds:[eax+A3E9], 0EB
  005565F1    C780 9CA40000 E9940000    mov dword ptr ds:[eax+A49C], 94E9
  005565FB    C680 A1A40000 90          mov byte ptr ds:[eax+A4A1], 90
  00556602    C680 84A50000 EB          mov byte ptr ds:[eax+A584], 0EB
  00556609    C680 CAE10100 EB          mov byte ptr ds:[eax+1E1CA], 0EB
  00556610    C780 67E20100 E9890000    mov dword ptr ds:[eax+1E267], 89E9
  0055661A    C680 6CE20100 90          mov byte ptr ds:[eax+1E26C], 90
  00556621    C780 A0A20000 E9850000    mov dword ptr ds:[eax+A2A0], 85E9
  0055662B    C680 A5A20000 90          mov byte ptr ds:[eax+A2A5], 90
  00556632    05 BACA0100               add eax, 1CABA
  00556637    A3 3F665500               mov dword ptr ds:[55663F], eax
  0055663C    9D                        popfd
  0055663D    61                        popad
  0055663E    68 00000000               push 0
  00556643    C3                        retn
  
  这里要说明一下,按照前人的经验,一般的Aspr只需要修改用"查找全部命令——>push 20019"找到的跳转中的后3个即可。但我这次有点郁

闷,我上面尝试修改了所有找到的跳转后,
  结果发现程序还是未注册,且提示已经过试用期了。估计这个可能和fly兄的试练品"Tag&Rename V3.2 RC3 "比较像,并不是直接修改此Pre

-Dip后就可以注册的。
  
  但这并不影响之前我们讨论的Aspr2.X的 Inline Patching方法。
  —————————————————————————————————
  六、Patch代码汇总
  
  
  00556400  - 0F85 888DFDFF             jnz clide.0052F18E
  00556406    C705 6AF15200 0F851E00    mov dword ptr ds:[52F16A], 1E850F
  00556410    66:C705 6EF15200 0000     mov word ptr ds:[52F16E], 0
  00556419    C705 6FF25200 B5710200    mov dword ptr ds:[52F26F], 271B5
  00556423  - E9 488DFDFF               jmp clide.0052F170
  00556428    C705 6FF25200 23000000    mov dword ptr ds:[52F26F], 23
  00556432    C705 36F35200 E90F7102    mov dword ptr ds:[52F336], 2710FE9
  0055643C    66:C705 3AF35200 0090     mov word ptr ds:[52F33A], 9000
  00556445  - E9 248EFDFF               jmp clide.0052F26E
  0055644A  - 0F85 798EFDFF             jnz clide.0052F2C9
  00556450    C705 36F35200 0F858DFF    mov dword ptr ds:[52F336], FF8D850F
  0055645A    66:C705 3AF35200 FFFF     mov word ptr ds:[52F33A], 0FFFF
  00556463    C705 E4F35200 E9927002    mov dword ptr ds:[52F3E4], 27092E9
  0055646D    66:C705 E8F35200 0090     mov word ptr ds:[52F3E8], 9000
  00556476  - E9 C18EFDFF               jmp clide.0052F33C
  0055647B  - 0F85 168FFDFF             jnz clide.0052F397
  00556481    C705 E4F35200 0F85ADFF    mov dword ptr ds:[52F3E4], FFAD850F
  0055648B    66:C705 E8F35200 FFFF     mov word ptr ds:[52F3E8], 0FFFF
  00556494    C705 AAF55200 E9F46E02    mov dword ptr ds:[52F5AA], 26EF4E9
  0055649E  - E9 478FFDFF               jmp clide.0052F3EA
  005564A3    C705 AAF55200 68008000    mov dword ptr ds:[52F5AA], 800068
  005564AD    893D 00675500             mov dword ptr ds:[556700], edi
  005564B3    60                        pushad
  005564B4    9C                        pushfd
  005564B5    A1 00675500               mov eax, dword ptr ds:[556700]
  005564BA    C780 F3100300 E9DA5361    mov dword ptr ds:[eax+310F3], 6153DAE9    
  //; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
  005564C4    C680 F7100300 FF          mov byte ptr ds:[eax+310F7], 0FF
  005564CB    9D                        popfd
  005564CC    61                        popad
  005564CD  - E9 D890FDFF               jmp clide.0052F5AA
  005564D2    60                        pushad
  005564D3    9C                        pushfd
  005564D4    A1 00675500               mov eax, dword ptr ds:[556700]
  005564D9    C780 F3100300 68008000    mov dword ptr ds:[eax+310F3], 800068
  005564E3    C680 F7100300 00          mov byte ptr ds:[eax+310F7], 0
  005564EA    C780 C1150300 68146555    mov dword ptr ds:[eax+315C1], 55651468
  005564F4    C680 C5150300 00          mov byte ptr ds:[eax+315C5], 0
  005564FB    C680 C6150300 C3          mov byte ptr ds:[eax+315C6], 0C3
  00556502    05 F3100300               add eax, 310F3
  00556507    A3 0F655500               mov dword ptr ds:[55650F], eax
  0055650C    9D                        popfd
  0055650D    61                        popad
  0055650E    68 00000000               push 0
  00556513    C3                        retn
  00556514    60                        pushad
  00556515    9C                        pushfd
  00556516    A1 00675500               mov eax, dword ptr ds:[556700]
  0055651B    C780 C1150300 617508B8    mov dword ptr ds:[eax+315C1], B8087561
  00556525    C680 C5150300 01          mov byte ptr ds:[eax+315C5], 1
  0055652C    C680 C6150300 00          mov byte ptr ds:[eax+315C6], 0
  00556533    C680 69860100 01          mov byte ptr ds:[eax+18669], 1
  0055653A    C780 7A860100 68646555    mov dword ptr ds:[eax+1867A], 55656468
  00556544    C680 7E860100 00          mov byte ptr ds:[eax+1867E], 0
  0055654B    C680 7F860100 C3          mov byte ptr ds:[eax+1867F], 0C3
  00556552    05 C1150300               add eax, 315C1
  00556557    A3 5F655500               mov dword ptr ds:[55655F], eax
  0055655C    9D                        popfd
  0055655D    61                        popad
  0055655E    68 00000000               push 0
  00556563    C3                        retn
  00556564    C780 6A510800 0F851E00    mov dword ptr ds:[eax+8516A], 1E850F
  0055656E    66:C780 6E510800 0000     mov word ptr ds:[eax+8516E], 0
  00556577    C680 99030000 00          mov byte ptr ds:[eax+399], 0
  0055657E    60                        pushad
  0055657F    9C                        pushfd
  00556580    A1 00675500               mov eax, dword ptr ds:[556700]
  00556585    C680 69860100 04          mov byte ptr ds:[eax+18669], 4
  0055658C    C780 7A860100 8BD850E8    mov dword ptr ds:[eax+1867A], E850D88B
  00556596    66:C780 7E860100 4A01     mov word ptr ds:[eax+1867E], 14A
  0055659F    C780 B9CA0100 E9069B62    mov dword ptr ds:[eax+1CAB9], 629B06E9
  //; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
  005565A9    66:C780 BDCA0100 FF90     mov word ptr ds:[eax+1CABD], 90FF
  005565B2    05 7A860100               add eax, 1867A
  005565B7    A3 BF655500               mov dword ptr ds:[5565BF], eax
  005565BC    9D                        popfd
  005565BD    61                        popad
  005565BE    68 00000000               push 0
  005565C3    C3                        retn
  005565C4    68 60665500               push clide.00556660                       ; ASCII 
  "clide2000[DFCG]"
  005565C9    60                        pushad
  005565CA    9C                        pushfd
  005565CB    A1 00675500               mov eax, dword ptr ds:[556700]
  005565D0    C780 B9CA0100 508B4704    mov dword ptr ds:[eax+1CAB9], 4478B50
  005565DA    66:C780 BDCA0100 FFD0     mov word ptr ds:[eax+1CABD], 0D0FF
  005565E3    C680 7DA30000 EB          mov byte ptr ds:[eax+A37D], 0EB
  005565EA    C680 E9A30000 EB          mov byte ptr ds:[eax+A3E9], 0EB
  005565F1    C780 9CA40000 E9940000    mov dword ptr ds:[eax+A49C], 94E9
  005565FB    C680 A1A40000 90          mov byte ptr ds:[eax+A4A1], 90
  00556602    C680 84A50000 EB          mov byte ptr ds:[eax+A584], 0EB
  00556609    C680 CAE10100 EB          mov byte ptr ds:[eax+1E1CA], 0EB
  00556610    C780 67E20100 E9890000    mov dword ptr ds:[eax+1E267], 89E9
  0055661A    C680 6CE20100 90          mov byte ptr ds:[eax+1E26C], 90
  00556621    C780 A0A20000 E9850000    mov dword ptr ds:[eax+A2A0], 85E9
  0055662B    C680 A5A20000 90          mov byte ptr ds:[eax+A2A5], 90
  00556632    05 BACA0100               add eax, 1CABA
  00556637    A3 3F665500               mov dword ptr ds:[55663F], eax
  0055663C    9D                        popfd
  0055663D    61                        popad
  0055663E    68 00000000               push 0
  00556643    C3                        retn
  00556644    90                        nop
  00556645    90                        nop
  00556646    90                        nop
  00556647    90                        nop
  00556648    90                        nop
  00556649    90                        nop
  0055664A    90                        nop
  0055664B    90                        nop
  0055664C    90                        nop
  0055664D    90                        nop
  0055664E    90                        nop
  0055664F    90                        nop
  00556650    90                        nop
  00556651    90                        nop
  00556652    90                        nop
  00556653    90                        nop
  00556654    90                        nop
  00556655    90                        nop
  00556656    90                        nop
  00556657    90                        nop
  00556658    90                        nop
  00556659    90                        nop
  0055665A    90                        nop
  0055665B    90                        nop
  0055665C    90                        nop
  0055665D    90                        nop
  0055665E    90                        nop
  0055665F    90                        nop
  00556660    636C69 64                 arpl word ptr ds:[ecx+ebp*2+64], bp
  00556664    65:3230                   xor dh, byte ptr gs:[eax]
  00556667    3030                      xor byte ptr ds:[eax], dh
  00556669    5B                        pop ebx
  0055666A    44                        inc esp
  0055666B    46                        inc esi
  0055666C    43                        inc ebx
  0055666D    47                        inc edi
  0055666E    5D                        pop ebp
  0055666F    0000                      add byte ptr ds:[eax], al
  
  
  0F 85 88 8D FD FF C7 05 6A F1 52 00 0F 85 1E 00 66 C7 05 6E F1 52 00 00 00 C7 05 6F F2 
  52 00 B5
  71 02 00 E9 48 8D FD FF C7 05 6F F2 52 00 23 00 00 00 C7 05 36 F3 52 00 E9 0F 71 02 66 
  C7 05 3A
  F3 52 00 00 90 E9 24 8E FD FF 0F 85 79 8E FD FF C7 05 36 F3 52 00 0F 85 8D FF 66 C7 05 
  3A F3 52
  00 FF FF C7 05 E4 F3 52 00 E9 92 70 02 66 C7 05 E8 F3 52 00 00 90 E9 C1 8E FD FF 0F 85 
  16 8F FD
  FF C7 05 E4 F3 52 00 0F 85 AD FF 66 C7 05 E8 F3 52 00 FF FF C7 05 AA F5 52 00 E9 F4 6E 
  02 E9 47
  8F FD FF C7 05 AA F5 52 00 68 00 80 00 89 3D 00 67 55 00 60 9C A1 00 67 55 00 C7 80 F3 
  10 03 00
  E9 DA 53 61 C6 80 F7 10 03 00 FF 9D 61 E9 D8 90 FD FF 60 9C A1 00 67 55 00 C7 80 F3 10 
  03 00 68
  00 80 00 C6 80 F7 10 03 00 00 C7 80 C1 15 03 00 68 14 65 55 C6 80 C5 15 03 00 00 C6 80 
  C6 15 03
  00 C3 05 F3 10 03 00 A3 0F 65 55 00 9D 61 68 00 00 00 00 C3 60 9C A1 00 67 55 00 C7 80 
  C1 15 03
  00 61 75 08 B8 C6 80 C5 15 03 00 01 C6 80 C6 15 03 00 00 C6 80 69 86 01 00 01 C7 80 7A 
  86 01 00
  68 64 65 55 C6 80 7E 86 01 00 00 C6 80 7F 86 01 00 C3 05 C1 15 03 00 A3 5F 65 55 00 9D 
  61 68 00
  00 00 00 C3 C7 80 6A 51 08 00 0F 85 1E 00 66 C7 80 6E 51 08 00 00 00 C6 80 99 03 00 00 
  00 60 9C
  A1 00 67 55 00 C6 80 69 86 01 00 04 C7 80 7A 86 01 00 8B D8 50 E8 66 C7 80 7E 86 01 00 
  4A 01 C7
  80 B9 CA 01 00 E9 06 9B 62 66 C7 80 BD CA 01 00 FF 90 05 7A 86 01 00 A3 BF 65 55 00 9D 
  61 68 00
  00 00 00 C3 68 60 66 55 00 60 9C A1 00 67 55 00 C7 80 B9 CA 01 00 50 8B 47 04 66 C7 80 
  BD CA 01
  00 FF D0 C6 80 7D A3 00 00 EB C6 80 E9 A3 00 00 EB C7 80 9C A4 00 00 E9 94 00 00 C6 80 
  A1 A4 00
  00 90 C6 80 84 A5 00 00 EB C6 80 CA E1 01 00 EB C7 80 67 E2 01 00 E9 89 00 00 C6 80 6C 
  E2 01 00
  90 C7 80 A0 A2 00 00 E9 85 00 00 C6 80 A5 A2 00 00 90 05 BA CA 01 00 A3 3F 66 55 00 9D 
  61 68 00
  00 00 00 C3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 
  90 90 90
  63 6C 69 64 65 32 30 30 30 5B 44 46 43 47 5D 00 00
  
  
  
  
  
  
  
  
  
  
--------------------------------------------------------------------------------
【经验总结】
  一篇个人关于Aspr2.X的Inline Patching的学习笔记。
  在此对temerata和fly表示感谢,同时也感谢你能看完这篇冗长的脱文。
  
  另:为了验证其方法的可行性,可换个直接修改Pre-Dip后就可以注册的练习。(现在尝试找出其他的暗桩中...)
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年01月07日 10:52:39