吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 6984|回复: 36

[原创逆向图文] 一款商业软件的Themida-2.1.*脱壳

  [复制链接]
zhaohj999 发表于 2015-5-17 10:31 | 显示全部楼层 |阅读模式

大家好,我是zhaohj999,一直来论坛混,感觉对不起大家。下面我就themida2.1.x的脱壳过程发表一下。
大家知道,themida的核心是esi表(解码表)和ebx表(dllbase),从这两个表分析配合脚本就ok了。
【软件地址】http://pan.baidu.com/share/home?uk=1931954324&view=share#category/type=0
【脱壳目的】只是感兴趣,相互交流
脱壳过程:
一:先找这两个表
我用脚本跑:
bpmc            //删除内存断点
BPHWCALL        //清所有硬件断点
BP 7c809b0a     //在VirtualAlloc返回处下F2断点(bp VirtualAlloc+5)
run                   //执行F9后中断在VirtualAlloc返回处
BC 7c809b0a     //删除F2断点
BPHWS eax+8ef1,"x"   // 在新的VirtualAlloc处下硬件执行断点,这个8ef1就是GetProcAddress的偏移
run             //F9

LOOP:           //不是就断续运行
cmp eax,7C80AE40   //eax是不是GetProcAddress
JE IsGetProcAddress
run
jmp LOOP   //中断在VirtualAlloc,并且eax=GetProcAddress,连续中断两次后,可得到esi和ebx的值
IsGetProcAddress:
log "IsGetProcAddress"
run  //中断一次
run  //中断第二次,此时刚好填充好esi表和ebx表
BPHWCALL
var tmp
mov tmp,[esp]
bp tmp  //看堆栈返回地址
run
BC tmp
//上面是TMD2.1.x通用查找esi和ebx表脚本,本程序见下面语句
pause

得到:
00E4A018    8BB5 8D180015   mov esi,dword ptr ss:[ebp+0x1500188D] //ESI表
esi=00E35DEB~00E41EB6
00E35DEB  15 59 38 6D 50 8F 60 54 5E 1D 00 60 AF 1D 00 20 //esi表开头
00E35DFB  0F 9A 00 C0 FF FF FF FF DD DD DD DD 0F AD 27 DA  
...
00E3603B  FF FF FF FF DD DD DD DD 0C 34 90 1A BB BB BB BB
00E3604B  48 F5 60 F4 FF FF FF FF DD DD DD DD FB 74 19 07
00E3605B  BB BB BB BB 49 F5 60 14 81 88 05 C0 AA AA AA AA
00E3606B  FF FF FF FF DD DD DD DD 0C 34 20 6D BB BB BB BB
00E3607B  49 F5 60 34 82 88 05 80 AA AA AA AA FF FF FF FF
00E3608B  DD DD DD DD FB 74 B1 07 BB BB BB BB 49 F5 60 54
00E3609B  83 88 05 40 AA AA AA AA FF FF FF FF DD DD DD DD
...
00E41E9B  AA AA AA AA FF FF FF FF DD DD DD DD EE EE EE EE      
00E41EAB  DD DD DD DD 00 00 00 00 00 00 00 00                 //以8个0结束esi表

00E4A031    8B9D C52D0015   mov ebx,dword ptr ss:[ebp+0x15002DC5] //EBX表
ebx=02F00000
02F00000  10000000  ADSEC.10000000
02F00004  76060000  SETUPAPI.76060000
02F00008  68BE0000  HID.68BE0000
02F0000C  73D30000  offset MFC42.Ordinal1482
02F00010  77BE0000  MSVCRT.77BE0000
02F00014  7C800000  kernel32.7C800000
02F00018  77D10000  USER32.77D10000
02F0001C  77EF0000  GDI32.77EF0000
02F00020  7D590000  offset SHELL32.Ordinal517
02F00024  76990000  ole32.76990000
02F00028  02FB0000  offset OG70AS.Ordinal3998
02F0002C  71A20000  offset WS2_32.Ordinal496
02F00030  00000000
=============================

二:得到这两个表后,开始分析:
esi=00E35DEB~00E41EB6
ebx=02F00000~002F0030
第一类:带0xbbbbbb api的处理
第二类:不带0xbbbbbb api的处理
第三类:加密api 的处理

  第一类                    第二类            第三类
带0xbbbbbbbb   不带0xbbbbbb     加密的api
  GetApi1                    GetApi2        GetApi2
  GetIat1                    GetIat1         GetIat2
  FillCall1                     FillCall1          FillCall2

对本程序,esi表第一项是不带0xbbbbbbbb的,也就是第二类

1:对ebx表第一个dword下内存访问断点,断在
00E4A086    FF33            push dword ptr ds:[ebx]                  ; ADSEC.10000000
00E4A088    812C24 F03C300F sub dword ptr ss:[esp],0xF303CF0
00E4A08F    59              pop ecx
GetBase=00E4A086 寄存器[ebx]
*******


2:找GetAPi2,对esi表第一个dword下内存访问断点,断在
00E4A9CF    AD              lods dword ptr ds:[esi]
F7,来到
00E4A9E0    BF 00000000     mov edi,0x0
00E4A9E5    897E FC         mov dword ptr ds:[esi-0x4],edi  //edi=0 读完esi表后清0
...
00E4AA15    3D EEEEEEEE     cmp eax,0xEEEEEEEE  //比较一大项是否结束
...
00E4AECB    3B02            cmp eax,dword ptr ds:[edx]
00E4AECD    0F84 1D010000   je 老虎YJK?00E4AFF0
比较函数名的hash值了,edx是函数名hash表,eax是本次函数名hash值
可以在00E4AFF0按F4,说明找到了api的索引表
....
00E4B019    3B8D 89130015   cmp ecx,dword ptr ss:[ebp+0x15001389]    ; USER32.77D10000
00E4B01F    74 10           je short 老虎YJK?00E4B031
00E4B021    3B8D 252D0015   cmp ecx,dword ptr ss:[ebp+0x15002D25]    ; ADVAPI32.77DA0000
00E4B027    74 08           je short 老虎YJK?00E4B031
00E4B029    3B8D C1190015   cmp ecx,dword ptr ss:[ebp+0x150019C1]    ; kernel32.7C800000
00E4B02F    75 31           jnz short 老虎YJK?00E4B062
比较是否是3个加密的api
...
00E4B0FE    8B9D C52D0015   mov ebx,dword ptr ss:[ebp+0x15002DC5]  //取基地址dllbase
...
00E4B13C    8B85 050D0015   mov eax,dword ptr ss:[ebp+0x15000D05]  //eax=7,大概是dll的索引值
00E4B142    60              pushad
...
00E4B16C    0385 71170015   add eax,dword ptr ss:[ebp+0x15001771]    ; ADSEC.10027088
00E4B172    E9 0E000000     jmp 老虎YJK?00E4B185
...
00E4B24A    8138 E8000000   cmp dword ptr ds:[eax],0xE8
执行到00E4B24A,eax=10021ee0 ADSEC._HKSEC+RUN@4 ecx=10000000 ADSEC.10000000
eax=func-addr ecx=imagebase
GetApi2=00E4B24A
*******
...
00E4B4AB    2BD9            sub ebx,ecx  ;USER32.77D10000 //判断dllbase是否属于加密的api
00E4B4AD    0F84 CC000000   je 老虎YJK?00E4B57F //跳说明是加密的api
...
00E4E946    61              popad
00E4E947    0F85 12000000   jnz 老虎YJK?00E4E95F //
    执行到00E4E947 ,eax=func-addr ecx=imagebase
....
00E4B638    3B85 81250015   cmp eax,dword ptr ss:[ebp+0x15002581]   ; kernel32.ExitProcess
00E4B63E    0F85 9E000000   jnz 老虎YJK?00E4B6E2 //判断api是否是kernel32.ExitProcess
    执行到00E4B63E ,eax=func-addr ecx=imagebase
...
00E4B6E2    3B85 81250015   cmp eax,dword ptr ss:[ebp+0x15002581]   ; kernel32.ExitProcess
00E4B6E8  ^ 0F84 FFFDFFFF   je 老虎YJK?00E4B4ED  //判断api
    执行到00E4B63E ,eax=func-addr ecx=imagebase
...
00E4CADC    3B85 2D100015   cmp eax,dword ptr ss:[ebp+0x1500102D]   ; USER32.wsprintfA
00E4CAE2    0F85 2D000000   jnz 老虎YJK?00E4CB15  //判断api是否是USER32.wsprintfA
这里让它跳
    执行到00E4CAE2 ,eax=func-addr ecx=imagebase
...
00E4CB15    3B85 CD0C0015   cmp eax,dword ptr ss:[ebp+0x15000CCD]   ; kernel32.RaiseException
00E4CB1B    0F85 07010000   jnz 老虎YJK?00E4CC28
...
00E4CC28    3B85 3D8C0E15   cmp eax,dword ptr ss:[ebp+0x150E8C3D]   ; ntdll.RtlEnterCriticalSection
00E4CC2E    0F84 27000000   je 老虎YJK?00E4CC5B
...
00E4CC35    3B85 418C0E15   cmp eax,dword ptr ss:[ebp+0x150E8C41]   ; ntdll.RtlLeaveCriticalSection
00E4CC3B    0F85 20000000   jnz 老虎YJK?00E4CC61
...

3:找GetIat1和FillCall1
因为现在是第二类,先处理GetIat1和FillCall1
这时在代码段下“设置内存写入断点”,断在
00E4D9AF    8938            mov dword ptr ds:[eax],edi        ; ADSEC._HKSEC_RUN@4
此时,[eax]=0,寄存器eax是IAT地址,即当eip=00E4D9AF而且[eax]=0时,是写入iat

GetIat1=00E4D9AF,eip=00E4D9AF [eax]=0,edi是原OrigFuncAddr
*******
...

f9几次
00E4DFE4    AB              stos dword ptr es:[edi]
此时,[edi]=90909090,寄存器edi是代码段地址,即当eip=00E4DFE4而且[edi]=90909090时,是填充code
ECX是OrigFuncAddr
stos dword ptr es:[edi]
执行后(sti),需要
mov [edi-4],eax
mov [esp],ecx

FillCall1=00E4DFE4,eip=00E4DFE4 [edi]=90909090
*********

4:对ebx表对应项下内存写入断点,找 BaseZero
00E4E15C    8919            mov dword ptr ds:[ecx],ebx
BaseZero=00E4E15C,寄存器ecx是ebx表地址
********

5:找GetIat2
取消所有断点,在kernel32.dll的esi表第一个dword下内存访问断点:地址00E3D957
F9运行
00E4A9CF    AD              lods dword ptr ds:[esi] //esi=00E3D957,esi表
再在代码段下内存写入断点,F9
00D9AE64    8F02            pop dword ptr ds:[edx]                   ; 03540000
此时,[edx]=0,[esp]是加密的func addr
GetIat2=00D9AE64 eip=00D9AE64 [edx]=0 ,这时把func addr写入[esp]替换即可
*******

再F9,来到
00D9AE64    8F02            pop dword ptr ds:[edx]
此时,[edx]=90909090,[esp]是加密的func addr
FillCall2=00D9AE64 eip=00D9AE64 [edx]=90909090 ,这时把func addr写入[esp]替换即可
*********

6:找GetApi1
取消所有断点
对esi表含0xbbbbbbbb的下内存访问断点,地址:00E3EDC3
F9,来到
00E4A9CF    AD              lods dword ptr ds:[esi]  //ESI表带bbbbbbbb的第一个dword
F7,来到
00E4A9E0    BF 00000000     mov edi,0x0
00E4A9E5    897E FC         mov dword ptr ds:[esi-0x4],edi //esi表第一个dword读完清0
...
00E4AA15    3D EEEEEEEE     cmp eax,0xEEEEEEEE  //比较是否一个大项结束
...
00E4ABA9    813E BBBBBBBB   cmp dword ptr ds:[esi],0xBBBBBBBB //比较是否是0xbbbbbbbb
此时[esi]=0xbbbbbbbb
...
00E4ABCB    C700 00000000   mov dword ptr ds:[eax],0x0  //清bbbbbbbb对应的dword
...
00E4AC4E    FF33            push dword ptr ds:[ebx]     ; OG70AS.Ordinal3998
取dllbase,[ebx]=[02F00028]=02FB0000  offset OG70AS.Ordinal3998
...
00E4AC60    81E9 FB7ACA6E   sub ecx,0x6ECA7AFB
00E4AC66    F5              cmc  //此时ecx是dllbase
...
00E4AD05    0385 951F0015   add eax,dword ptr ss:[ebp+0x15001F95]
00E4AD0B    F9              stc
...
00E4AD62    2D B75DCF30     sub eax,0x30CF5DB7
00E4AD67    60              pushad
此时,寄存器:
EAX 03020B40 OG70AS.#5462
ECX 02FB0000 offset OG70AS.Ordinal3998
esp 0012FF04 OG70AS.#5462
执行到00E4AD67,eax=func addr , ecx=dll base
...
00E4E946    61              popad
00E4E947    0F85 12000000   jnz 老虎YJK?00E4E95F
执行到00E4E947,eax=func addr , ecx=dll base
00E4B546    50              push eax
00E4B547    8B3C24          mov edi,dword ptr ss:[esp]               ; OG70AS.#5462
执行到00E4B547,eax=func addr , ecx=dll base ,[esp]是func addr

GetApi1=00E4B547
*******

7:
GetApi1=00E4B547       GetApi2=00E4B24A   BaseZero=00E4E15C    GetBase=00E4A086
GetIat1=00E4D9AF       GetIat2=00D9AE64
FillCall1=00E4DFE4     FillCall2=00D9AE64

===============================

三:修复oep

脚本运行到伪OEP了,也就是说OEP已经被偷了代码了。这时候看下参考程序的OEP头代码:

006C4F9A    55              push ebp
006C4F9B    8BEC            mov ebp,esp
006C4F9D    6A FF           push -0x1
006C4F9F    68 000C7000     push 老虎YJK?00700C00  //第一个push
006C4FA4    68 144F6C00     push 老虎YJK?006c4f14  //第二个push push <jmp.&MSVCRT._except_handler3>
006C4FA9    64:A1 00000000  mov eax,dword ptr fs:[0]
006C4FAF    50              push eax
006C4FB0    64:8925 0000000>mov dword ptr fs:[0],esp
006C4FB7    83EC 68         sub esp,0x68
006C4FBA    53              push ebx
006C4FBB    56              push esi
006C4FBC    57              push edi
006C4FBD    8965 E8         mov dword ptr ss:[ebp-0x18],esp
006C4FC0    33DB            xor ebx,ebx
006C4FC2    895D FC         mov dword ptr ss:[ebp-0x4],ebx
006C4FC5    6A 02           push 0x2   《==脚本停在此处

看EBP寄存器,这个地址在堆栈窗中跟随:

0012FF34   0012FFE0  指向下一个 SEH 记录的指针
0012FF38   006C4F14  SE处理程序        //第二个push
0012FF3C   00700C00  老虎YJK?00700C00  //第一个push
0012FF40   00000000
0012FF44   00000000

=====================
四:自校验
00E4A806    83BD 350D0015 6>cmp dword ptr ss:[ebp+0x15000D35],0x64  //超过0x64后加自校验
00E4A80D    0F82 5E010000   jb 老虎YJK?00E4A971  //改成jmp

[00E4A80D],E95F01000090  //修改后代码,脚本用
-------------
五:E8、E9改成FF15、FF25的处理

00E4DE2B    0BDB            or ebx,ebx
00E4DE2D    0F84 15000000   je 老虎YJK?00E4DE48  //ebx=0 跳,此时edi是代码段地址
...
00E4DE48    83F8 50         cmp eax,0x50   //eax<50则跳 ,估计eax记录的是api的index号
00E4DE4B    0F82 88000000   jb 老虎YJK?00E4DED9
...
00E4DE8E    AA              stos byte ptr es:[edi]  //eax>50时填充90的地址,就是说90在E8E9前面
...
00E4DEB7    AA              stos byte ptr es:[edi]  //eax>50时填充E8E9
...
00E4DF58    8803            mov byte ptr ds:[ebx],al //eax<50时填充非90的数据在E8(E9) XXXXXXXX YY中的YY
...
00E4DEFA    AA              stos byte ptr es:[edi] //当eax<50时的填充e8、e9
00E4DEFB    FC              cld
...
00E4DEFD    807F FF E9      cmp byte ptr ds:[edi-0x1],0xE9  //e8 e9不同情况处理
00E4DF01    0F85 8A000000   jnz 老虎YJK?00E4DF91  //e8跳



====================
脚本:
start:
var GetApi1
var GetIat1
var FillCall1

var GetApi2
var GetIat2
var FillCall2

var BaseZero
var GetBase

var CodeStart
var CodeSize

var ModBase //模块基址
var FuncAddr //未加密api地址
var FillAddr //fill地址
var IatMin   
var IatMax
var IatCur  //api所属对应iat地址
var OrigFuncAddr //壳填在iat中的地址
var NewCallValue

mov GetApi1,00E4B547
mov GetIat1,00E4D9AF
mov FillCall1,00E4DFE4

mov GetApi2,00E4B24A
mov GetIat2,00D9AE64
mov FillCall2,00D9AE64

mov BaseZero,00E4E15C
mov GetBase,00E4A086

mov CodeStart,00401000
mov CodeSize,0088b000

mov IatMin,ffffffff
mov IatMax,0
mov nFuncCount,0
mov nIatCount,0

BPHWCALL            //删除所有硬件断点
BPHWS GetBase,"x"   //设置硬件执行断点
BPHWS BaseZero,"x"  //设置硬件执行断点

run   //F9 (或用ESTO=SHIFT-F9)
pause
mov [00E4A80D],#E95F01000090#    //校验
MOV [00E4DE4B],#909090909090#    //填充E8、E9前让它统一填充90
jmp func

//暂停在从ebx表取值
PauseAt_GetBase:
        BPHWS GetApi2,"x"
        BPHWS GetApi1,"x"
        BPWM  CodeStart,CodeSize //代码断设置内存写入断点

        run
        jmp func


//函数8 暂停在ebx表清0处
PauseAt_BaseZero:
//{
        log "BaseZero"
        cmp [ecx+4],0
        JE FINDOEP
        run
        jmp func
//}


//函数1,获取0xbbbbbbbb api地址
PauseAt_GetApi1:
//{
//pause
        mov FuncAddr,eax  //eax=func addr , ecx=dll base
        mov ModBase,ecx
        run
        jmp func


//}

//函数2,fill 非加密iat
PauseAt_GetIat1:
//{
//pause
        mov IatCur,eax  //00E4D9AF  mov dword ptr ds:[eax],edi
        mov OrigFuncAddr,edi
        cmp OrigFuncAddr,FuncAddr
        JE FillIat1_Next
        mov edi,FuncAddr
FillIat1_Next:
        run
        jmp
//}

//函数3 fill非加密call or jmp
PauseAt_FillCall1:
//{
//pause
        sti
        mov FillAddr,edi  //00E4DFE4  stos dword ptr es:[edi]
        sub FillAddr,5
//当前指针                                ||                                   ||
        find FillAddr,#E8#,2   //90 E8 xx xx xx xx 或者 90 E9 xx xx xx
        cmp $RESULT,0
        sub FillAddr,1
        je  Fillcall1FF25      //不是E8则跳转到E9
        mov [FillAddr],#ff15#
        jmp FillCall1_next

Fillcall1FF25:
        mov [FillAddr],#ff25#

FillCall1_next:
        add FillAddr,2
        mov [FillAddr],IatCur
        run
        jmp func

//函数4,获取非0xbbbbbb api地址,00E4B172
PauseAt_GetApi2:
//{
//pause
        mov FuncAddr,eax  //执行到此,eax=func-addr ecx=imagebase
        mov ModBase,ecx
        cmp FuncAddr,77D1A8AD
        jne PauseAt_GetApi2_next
        GO 00E4CAE2
        pause  //修改USER32.wsprintfA,修改标志位让它跳转。本程序对此api特别处理的

PauseAt_GetApi2_next:
        run
        jmp func

//}

//函数5,填充加密iat 00D9AE64
PauseAt_GetIat2:
//{
//pause   
        mov IatCur,edx  //00D9AE64  pop dword ptr ds:[edx]
        mov OrigFuncAddr,[esp]
        mov [esp],FuncAddr

GetIat2_next:
        jmp GetMinMaxIat
//}


//函数6,填充加密call
PauseAt_FillCall2:
//{
        sti       
        mov FillAddr,edx //00D9AE64  pop dword ptr ds:[edx]
        sub FillAddr,1
//当前指针                            ||                                   ||
        find FillAddr,#E8#,2   // E8 xx xx xx xx 90 或者 E9 xx xx xx xx 90
        cmp $RESULT,0
        je Fillcall2FF25       //不是E8则跳转到E9
        mov [FillAddr],#ff15#  
        jmp Fillcall2_next

Fillcall2FF25:
        mov [FillAddr],#ff25#

Fillcall2_next:
        add FillAddr,2
        mov [FillAddr],IatCur  //改成FuncAddr对应的IAT地址

        run
        jmp func


//}


//函数7,获取最大,最小iat
GetMinMaxIat:
//{
        cmp IatCur,IatMin
        ja Next   //如果IatCur>IatMin 则跳
        mov IatMin,IatCur
Next:
        cmp IatCur,IatMax
        jb Finish  //如果IatCur<IatMax 则跳
        mov IatMax,IatCur
Finish:
        run
        jmp func
//}


//函数9,开始找oep
FINDOEP:
//{
        BPHWCALL //清除所有硬件断点
        bpmc  //清除所有内存断点
        BPRM  CodeStart,CodeSize  //代码断内存访问断点
        run
        log "FINDOEP"
        log IatMin
        log IatMax
        bpmc  //清除所有内存断点
//下面对本程序修补oep
//006C4F9A是真正oep地址
        mov [006C4F9A],#558BEC6AFF68000C700068144F6C0064A100000000506489250000000083EC685356578965E833DB895DFC#
//本程序OEP修补完成
        ret
//结束脚本

//}

//函数10,eip switch case
func:
//{
        mov flag,0
        cmp eip,GetApi1     //分支1, 停在GetApi1
        JE PauseAt_GetApi1

        cmp eip,GetIat1     //分支2 停在GetIat1
        JNE func_next1
        cmp [eax],0
        JE PauseAt_GetIat1
        jmp NotAll

func_next1:
        cmp eip,FillCall1   //分支3 停在FillCall1
        JNE func_next2
        cmp [edi],90909090
        JE PauseAt_FillCall1
        jmp NotAll
     
func_next2:

        cmp eip,GetApi2     // 分支4 停在GetApi2
        je PauseAt_GetApi2


        cmp eip, GetIat2  
        JNE func_next3

        cmp [edx],0
        JE PauseAt_GetIat2  //分支5 停在GetIat2

        cmp [edx],90909090
        JE PauseAt_FillCall2  //分支6 停在FillCall2
        jmp NotAll

func_next3:
        cmp eip,BaseZero    //分支7,停在BaseZero
        je PauseAt_BaseZero

        cmp eip,GetBase     //分支8,停在GetBase
        je PauseAt_GetBase
   
NotAll:
        run
        jmp func
//}







评分

参与人数 33威望 +1 HB +56 THX +20 收起 理由
lies + 1
24567 + 1
Jawon + 2
sjtkxy + 1 + 1
bnjzzheng + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
Soul1999 + 1
消逝的过去 + 1
冷亦飞 + 1
l278785481 + 1
车太震 + 1
jaunic + 2
liugu0hai + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
汇编先行 + 1
ldljlzw + 1
hnymsh + 2
oawxx + 1 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
s1986q + 1 + 1 好人有好报!你的热心我永远不忘!谢谢!
Jrack泽 + 1 + 1 膜拜脱TMD
fzx118 + 1 + 1 好人有好报!你的热心我永远不忘!谢谢!
ningzhonghui + 2 + 1 评分=感恩!简单却充满爱!感谢您的作品!
Shark恒 + 1 + 10 + 1 如果配有图片讲解的话。我相信会帮助更多的人,赞!
Journey + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!
哎呦呦 + 5 + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!
逍遥枷锁 + 4 + 1 好人有好报!你的热心我永远不忘!谢谢!
860269996 + 1 + 1 评分=感恩!简单却充满爱!感谢您的作品!
kangda666 + 1 + 1 评分=感恩!简单却充满爱!感谢您的作品!
有何不可 + 2 + 1 评分=感恩!简单却充满爱!感谢您的作品!
虚竹 + 5 + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!
怕怕吓一跳 + 2 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!
我爱张海强 + 1 + 1 评分=感恩!简单却充满爱!感谢您的作品!
mjsz + 1 + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!
yuzhiboqianyuan + 1 + 1 评分=感恩!简单却充满爱!感谢您的作品!
1322317605 + 1 + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
yuzhiboqianyuan 发表于 2015-5-17 11:04 | 显示全部楼层

本帖最后由 yuzhiboqianyuan 于 2015-5-17 11:32 编辑

论坛到现在,我第一次看到敢搞TMD,赞一个,好好研究。
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
yuzhiboqianyuan 发表于 2015-5-17 11:09 | 显示全部楼层

yuzhiboqianyuan 发表于 2015-5-17 11:04
论坛到现在,我第一看到敢搞TMD,赞一个,好好研究。

要想看懂真是不容易啊,
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
mjsz 发表于 2015-5-17 11:30 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
虚竹 发表于 2015-5-17 12:48 | 显示全部楼层

.....精华的节奏 ?如果是原创的话应该是精华了
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
 楼主| zhaohj999 发表于 2015-5-17 12:52 | 显示全部楼层

TMD实际上不难的,关键是两个表即解码表和api基址表。
这两个表也可不用脚本,在代码段设置内存写入断点,断下后一直F7就可跟踪到的。
象这种 lods dword ptr ds:[esi]的语句,一看就是读esi表了。
TMD很有意思的是对E8E9的处理,5字节要还原成6字节,前后90部分的处理
00E4DE48    83F8 50         cmp eax,0x50
这里花了点时间,不统一的话脚本很难处理。
至于校验与oep修复就相对简单。
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
yuzhiboqianyuan 发表于 2015-5-17 18:33 | 显示全部楼层

楼主,再加把劲,出个视频教程,或者图文教程,
造福后来人!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ningzhonghui 发表于 2015-5-17 19:53 | 显示全部楼层

过来支持下大牛分享知识,表示看着头都痛.... 大牛有空录个视频上来更好
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
Shark恒 发表于 2015-5-17 19:54 | 显示全部楼层

期待下次教程可以带有图片
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
fzx118 发表于 2015-5-17 22:10 | 显示全部楼层

我还看得不是很懂  但是谢谢分享精神哟
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

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