lal978112 发表于 2008-4-30 10:01:30

Themida/WinLicense Delphi 6.0 寻找Stolen Code!

Themida/WinLicense Delphi 6.0 寻找Stolen Code!
【文章标题】: Themida/WinLicense Delphi 6.0 寻找Stolen Code!
【文章作者】: lal978112
【作者邮箱】: [email protected]
【软件名称】: Project1.exe
【加壳方式】: Themida/WinLicense
【保护方式】: 代码变形 iat加密oep偷取
【编写语言】: Delphi 6.0
【使用工具】: OllyICE(Hideod 0.17) LordPE ImportREC
【操作平台】: XP SP2
【作者声明】: 我是一只小菜鸟,偶得一点心得,愿与大家分享
【详细过程】:

首先OD 载入 ,忽略所有异常,用Hideod 插件隐藏OD!
目标程序是:Project1.exe
PEID查得是:Themida|WinLicense V1.9.2.0-> Oreans Technologies *
我这里用另一种思路,查找程序编写的语言:
运行Project1.exe,然后DUMP出来,再用PEID核心扫描为:Borland Delphi 6.0 - 7.0
知道是什么语言的就好办了,现在我们就开始脱壳
运行脚本:THEMIDA脚本(for IAT restore).txt

运行完脚本,OD停在这里:
00405C60    53            PUSH EBX   记位这个地址,同时记住 EAX=00453A1C(1)
00405C61    8BD8            MOV EBX,EAX
00405C63    33C0            XOR EAX,EAX
00405C65    A3 9C404500   MOV DWORD PTR DS:,EAX
00405C6A    6A 00         PUSH 0
00405C6C    E8 2BFFFFFF   CALL Project1.00405B9C         ; JMP 到 kernel32.GetModuleHandleA
00405C71    A3 64664500   MOV DWORD PTR DS:,EAX
00405C76    A1 64664500   MOV EAX,DWORD PTR DS:
00405C7B    A3 A8404500   MOV DWORD PTR DS:,EAX
00405C80    33C0            XOR EAX,EAX
00405C82    A3 AC404500   MOV DWORD PTR DS:,EAX
00405C87    33C0            XOR EAX,EAX
00405C89    A3 B0404500   MOV DWORD PTR DS:,EAX
00405C8E    E8 C1FFFFFF   CALL Project1.00405C54
00405C93    BA A4404500   MOV EDX,Project1.004540A4
00405C98    8BC3            MOV EAX,EBX
00405C9A    E8 F5DEFFFF   CALL Project1.00403B94
00405C9F    5B            POP EBX
00405CA0    C3            RETN      //在这里F4 F8跟进

来到这里:到VM里面了
006AF013    68 107C3A6C   PUSH 6C3A7C10
006AF018^ E9 16C4FFFF   JMP Project1.006AB433
006AF01D    07            POP ES                           ; 段寄存器修饰
006AF01E    42            INC EDX
006AF01F    56            PUSH ESI
006AF020    DBF4            FCOMI ST,ST(4)
006AF022    15 4672686C   ADC EAX,6C687246

现在我们Alt+M,在代码段下F2断点 到这里了

00C2004F    FF33            PUSH DWORD PTR DS:         ;在这里断下EBX=00455058 (2)
00C20051    8B1C24          MOV EBX,DWORD PTR SS:
00C20054    81EC 04000000   SUB ESP,4
00C2005A    890424          MOV DWORD PTR SS:,EAX

此时停在:00C2004F      PUSH DWORD PTR DS:上,注意代码中用到了EBX,那么我们
就记下EBX的值:00455058 数据窗口跟随,可以看到该处的值为:00456BDC
好了,继续F8一次,再在代码段下F2断点,来到这里:

004039EC    8B4424 04       mov   eax, dword ptr     ;在这里断下 单步向下
004039F0    F740 04 0600000>test    dword ptr , 6      ;这里实际上是一个反调试的地方
004039F7    0F85 89000000   jnz   00403A86                  ;在这里改跳转,不让程序执行下面代码
004039FD    803D 28404500 0>cmp   byte ptr , 0
00403A04    77 0F         ja      short 00403A15
00403A06    8D4424 04       lea   eax, dword ptr
00403A0A    50            push    eax
00403A0B    E8 FCD7FFFF   call    0040120C                ; jmp 到 kernel32.UnhandledExceptionFilter
00403A10    83F8 00         cmp   eax, 0
00403A13    74 71         je      short 00403A86
00403A15    8B4424 04       mov   eax, dword ptr
改完跳转后程序来到这里:
7C9237BF    64:8B25 0000000>mov   esp, dword ptr fs:
7C9237C6    64:8F05 0000000>pop   dword ptr fs:
7C9237CD    8BE5            mov   esp, ebp
7C9237CF    5D            pop   ebp
7C9237D0    C2 1400         retn    14
在代码段下F2断点 到这里了
00C4C574    FF33            push    dword ptr       ;在这里断下
00C4C576    FF3424          push    dword ptr
00C4C579    E9 3C920600   jmp   00CB57BA

程序在取地址00456BDC中的值,可以不管它
继续F8一次,再在代码段下F2断点,来到这里:

0045207C    53            push    ebx               ;在这里断下,记住这个地址    (3)
0045207D    A1 B44F4500   mov   eax, dword ptr [454FB4>
00452082    8338 00         cmp   dword ptr , 0
00452085    74 0A         je      short 00452091
00452087    8B1D B44F4500   mov   ebx, dword ptr [454FB4>; Project1.00456040
0045208D    8B1B            mov   ebx, dword ptr
0045208F    FFD3            call    ebx
00452091    5B            pop   ebx
00452092    C3            retn                        //在这里F4 F8跟进
又来到VM里面了
006AF025    68 6C23E169   push    69E1236C
006AF02A^ E9 04C4FFFF   jmp   006AB433
006AF02F    91            xchg    eax, ecx
006AF030    AC            lods    byte ptr
继续在代码段下F2断点 到这里了
00C4C574    FF33            push    dword ptr       ;在这里断下EBX=00455138   (4)
00C4C576    FF3424          push    dword ptr
00C4C579    E9 3C920600   jmp   00CB57BA

记下EBX的值:00455138   这里有一个技巧,如果:pushdword ptr 是用的哪个寄存器,就记下那个
寄存器的地址
继续F8一次,再在代码段下F2断点,来到这里:

00C24A6D    FF32            PUSH DWORD PTR DS:          ;在这里断下 EDX=00455058 (5)
00C24A6F    812C24 64103460 SUB DWORD PTR SS:,60341064
00C24A76    E9 9E580000   JMP 00C2A319
00C24A7B    BA 20000000   MOV EDX,20
00C24A80    01FA            ADD EDX,EDI

记下EDX的值:00455058
继续F8一次,再在代码段下F2断点,又来到反调试的这里,继续改跳转:

004039EC    8B4424 04       mov   eax, dword ptr    ;在这里断下 单步向下
004039F0    F740 04 0600000>test    dword ptr , 6
004039F7    0F85 89000000   jnz   00403A86               ;在这里改跳转,不让程序执行下面代码
004039FD    803D 28404500 0>cmp   byte ptr , 0
00403A04    77 0F         ja      short 00403A15
00403A06    8D4424 04       lea   eax, dword ptr
00403A0A    50            push    eax
00403A0B    E8 FCD7FFFF   call    0040120C                   ; jmp 到 kernel32.UnhandledExceptionFilter
00403A10    83F8 00         cmp   eax, 0
00403A13    74 71         je      short 00403A86
改完跳转后程序来到这里:
7C9237BF    64:8B25 0000000>mov   esp, dword ptr fs:
7C9237C6    64:8F05 0000000>pop   dword ptr fs:
7C9237CD    8BE5            mov   esp, ebp
7C9237CF    5D            pop   ebp
7C9237D0    C2 1400         retn    14
在代码段下F2断点 到这里了
00C0004F    FF33            push    dword ptr          ;在这里断下
00C00051    8B1C24          mov   ebx, dword ptr
00C00054    81EC 04000000   sub   esp, 4

程序在取地址00456BDC中的值,可以不管它
继续F8一次,再在代码段下F2断点,来到这里:

00C4C574    FF33             push    dword ptr           ;在这里断下 EBX=00453700 (6)
00C4C576    FF3424         push    dword ptr
00C4C579    E9 3C920600      jmp   00CB57BA
00C4C57E    51               push    ecx
记下EBX的值:00453700
继续F8一次,再在代码段下F2断点:
00452094    55               push    ebp    ;在这里断下,有点象OEP,可是它不是,记住这个地址 (7)
00452095    8BEC             mov   ebp, esp   
00452097    51               push    ecx
00452098    53               push    ebx
00452099    56               push    esi
0045209A    57               push    edi
0045209B    894D FC          mov   dword ptr , ecx
0045209E    8BDA             mov   ebx, edx
F8单步向下一直走
来到这里
00452108    897E 44          mov   dword ptr , edi
0045210B    5F               pop   edi
0045210C    5E               pop   esi
0045210D    5B               pop   ebx
0045210E    59               pop   ecx
0045210F    5D               pop   ebp
00452110    C3               retn               //在这里F4 F8跟进

又来到VM里面了

006AF032    68 634D1A64      push    641A4D63   ;在这里断下
006AF037^ E9 F7C3FFFF      jmp   006AB433
006AF03C    3B59 2D          cmp   ebx, dword ptr
006AF03F    52               push    edx
006AF040    0E               push    cs

再在代码段下F2断点:

00C04A6D    FF32             push    dword ptr           ;在这里断下EDX=00455058 (8)
00C04A6F    812C24 64103460sub   dword ptr , 60341064
00C04A76    E9 9E580000      jmp   00C0A319

记下EDX的值:00455058
继续F8一次,再在代码段下F2断点:
00C4C574    FF33             push    dword ptr     ;在这里断下
00C4C576    FF3424         push    dword ptr
00C4C579    E9 3C920600      jmp   00CB57BA
00C4C57E    51               push    ecx
程序仍然在取地址00456BDC中的值,可以不管它
继续F8一次,再在代码段下F2断点:

00453C3F    E8 D0E4FFFF      call    00452114   ;在这里断下,这里就OEP了,不过需要补代码
00453C44    E8 1301FBFF      call    00403D5C   ;从这里大家就能看出来这是Delphi 6.0 的程序吧
00453C49    8D40 00          lea   eax, dword ptr
00453C4C    0000             add   byte ptr , al
00453C4E    0000             add   byte ptr , al
00453C50    0000             add   byte ptr , al
00453C52    0000             add   byte ptr , al
00453C54    0000             add   byte ptr , al
00453C56    0000             add   byte ptr , al
00453C58    0000             add   byte ptr , al
00453C5A    0000             add   byte ptr , al
00453C5C    0000             add   byte ptr , al
00453C5E    0000             add   byte ptr , al
00453C60    0000             add   byte ptr , al
00453C62    0000             add   byte ptr , al
00453C64    0000             add   byte ptr , al

好,找一个Delphi 6.0 的程序
push    ebp
mov   ebp, esp
add   esp, -10
mov   eax,00453A1C            上面(1)的EAX值
call    00405C60                  (1)
mov   eax, dword ptr    (2)
mov   eax, dword ptr
call    0045207C                  (3)
mov   ecx, dword ptr    (4)
mov   eax, dword ptr    (5)
mov   eax, dword ptr
mov   edx, dword ptr    (6)
call    00452094                  (7)
mov   eax, dword ptr    (8)
mov   eax, dword ptr
call    00452114
call    00403D5C
lea   eax, dword ptr
add   byte ptr , al
add   byte ptr , al

补代码地址如下:

00453C04    55               push    ebp
00453C05    8BEC             mov   ebp, esp
00453C07    83C4 F0          add   esp, -10
00453C0A    B8 1C3A4500      mov   eax, 00453A1C
00453C0F    E8 4C20FBFF      call    00405C60
00453C14    A1 58504500      mov   eax, dword ptr
00453C19    8B00             mov   eax, dword ptr
00453C1B    E8 5CE4FFFF      call    0045207C
00453C20    8B0D 38514500    mov   ecx, dword ptr     ; Project1.00456C00
00453C26    A1 58504500      mov   eax, dword ptr
00453C2B    8B00             mov   eax, dword ptr
00453C2D    8B15 00374500    mov   edx, dword ptr     ; Project1.0045374C
00453C33    E8 5CE4FFFF      call    00452094
00453C38    A1 58504500      mov   eax, dword ptr
00453C3D    8B00             mov   eax, dword ptr

在00453C04处新建EIP 然后DUMP出来,修复都没有问题,可是运行不了,后来一跟踪才知道有VM,请教高手
是不是还需要补区段?

py22 发表于 2008-4-30 16:47:56

赞一个,很详细,很暴力。

hyhnet 发表于 2008-5-5 16:37:26

好贴,顶一下~~~~~~~~~~~~

birdcfly 发表于 2008-5-6 12:35:07

如果把程序也一起带上来方便大家学习研究,那就更好了

笨虫虫 发表于 2008-5-20 00:30:34

一般是要补区段。好还你那没有KEY,有KEY的话就跑不起来了

kangaroo 发表于 2008-5-21 19:03:29

对啊。有个程序就更好了。

lal978112 发表于 2008-5-22 14:18:44

原程序在这里:http://www.namipan.com/d/Project1.exe/c8bd2ba302bb8c0d5fca2bf85a02d5553a435ada00201500
有兴趣的朋友可以练习练习!!

hmily 发表于 2008-5-22 20:01:41

附件没有勒,楼主能不能换个地址~

aspirer 发表于 2008-5-25 02:04:41

要慢慢学习研究下了

雪的思念 发表于 2008-7-16 20:29:44

/:good 好贴啊
页: [1] 2
查看完整版本: Themida/WinLicense Delphi 6.0 寻找Stolen Code!