• 标 题:菜鸟脱 UltraFXP 0.9941 壳( SVKP )+ 破解
  • 作 者:pyzpyz
  • 时 间:2004年2月25日 04:26
  • 链 接:http://bbs.pediy.com

这个软件是在很久以前看fly大侠脱文时,fly大侠提到过的,当时我下载后一直没动它,最近才拿出来研究,花了不少时间。这个软件最近版本用了ACProtect加壳,如果要找SVKP壳的就找老一点的版本。虽然不是最新版,但还是要对作者说sorry。


UltraFXP 0.9941 脱壳( SVKP )+破解
 

【软件简介】:一国产ftp,fxp软件。

【下载】:    用google或百度找。

【作者声明】:初学Crack,冒犯及失误之处请诸位大侠指正! 

【调试环境】:WinXP、Ollydbg1.10b、PEiD、LordPE、ImportREC
 
  
用PEiD查看壳为:SVKP 1.3x -> Pavol Cerven
 
1.找oep

隐藏ollydbg,忽略kernel32内存异常,其它的不忽略.下bp GetProcAddress+11,(注意:不能在函数第一
句下断,很多壳都会检测到的),f9运行,异常处shift+f9通过,直到中断在GetProcAddress+11,然后到
memory map窗口在ultrafxp代码段下内存访问断点,f9运行,到下面代码:

0056EEAB      NOP
0056EEAC      NOP
0056EEAD      NOP
0056EEAE      CALL UltraFxp.004079B8           //中断在这,伪oep
0056EEB3      MOV EBXDWORD PTR DS:[58802C]           ; UltraFxp.0058B318
0056EEB9      MOV EAXDWORD PTR DS:[588940]
0056EEBE      MOV EAXDWORD PTR DS:[EAX]
0056EEC0      CALL UltraFxp.0043C18C
0056EEC5      MOV EAXDWORD PTR DS:[588864]
0056EECA      MOV EDX, UltraFxp.0056F5E4               ; ASCII "Unregistered version!"
0056EECF      CALL UltraFxp.00403E2C
0056EED4      PUSHAD
0056EED5      PUSH EAX
0056EED6      PUSH ECX
0056EED7      PUSH EDX
0056EED8      PUSH EBX
0056EED9      PUSH EBP
0056EEDA      PUSH ESI
0056EEDB      PUSH EDI
0056EEDC      MOV EDX, 8E9AF9D6
0056EEE1      XOR EDX, 3159F8D7
0056EEE7      PUSH EDX
             
.............
             
0056EF3A      XOR ECX, 3113B900
0056EF40      XOR EDX, DFB7D6BE
0056EF46      PUSH ECX
0056EF47      PUSH EDX
0056EF48      MOV ECXESP
0056EF4A      XOR EDX, 56EFD6BE
0056EF50      ADD EDXECX
0056EF52      PUSH EDX
0056EF53      XOR ECX, 11B8A811
0056EF59      XOR EDX, 22222222
0056EF5F      RETN



0056EEAE是伪oep,根据eax=56eab0,esp=12fea8以及经验补上stolen bytes,共14字节:


0056EEA0      55                        PUSH EBP
0056EEA1      8BEC                   MOV EBPESP
0056EEA3      81C4 E8FEFFFF   ADD ESP, -118
0056EEA9      B8 B0EA5600      MOV EAX, 0056EAB0
             

用lordpe纠正大小后把它dump出来,并把oep改为0056EEA0。




2.修复IAT

经过查找,找到加密后的IAT,从58C1B8到58ca40共88c个。可以用ImportREC的跟踪层次来修复,有25
个是错误。下面我们来看看怎么修改程序,能得到错误少一点的IAT。重新加载程序。在58C1B8处下个
内存写入断点,运行,异常处shift+f9通过,中断几次后到下面代码:


07346D00       MOV DWORD PTR DS:[EDI], EAX   //中断在这,eax=075775DC(加密后的函数地址)
07346D02       JL SHORT 07346D07
07346D04       JMP SHORT 07346D09
07346D06       JMP EF96687F
07346D0B       ADD DWORD PTR DS:[EAX], EAX
07346D0D       ADD BYTE PTR DS:[EAX], AL


中断后,看看堆栈窗,esp=12ff74,在esp+1c=12ff90处正是正确的函数地址(不要问为什么,我也不知
道,是一高人的妙招),因此我们看能不能在07346D00之前把正确的函数地址放入eax,在代码窗往上
看:


07346CF6       5F                POP EDI
07346CF7       EB 02           JMP SHORT 07346CFB
07346CF9       CD 20           INT 20
07346CFB       58                POP EAX
07346CFC       EB 02           JMP SHORT 07346D00
07346CFE       0F                NOP                             //花指令,nop掉看看
07346CFF       E8                NOP                             //花指令,nop掉看看
07346D00       8907            MOV DWORD PTR DS:[EDI], EAX
            
            
我们可以改成这样:
        
 073C6CF6      5F                    POP EDI
 073C6CF7      58                    POP EAX
 073C6CF8      8B4424 1C       MOV EAXDWORD PTR SS:[ESP+1C]
 073C6CFC      EB 02               JMP SHORT 073C6D00
      
           
 在0056EEA E处下个断,f9运行到0056EEAE。ok,运行ImportREC,填入oep=0016EEA0,RVA=18C1B8, 
 size=88c,按get imports得到基本完整的IAT,但还有12个有问题:
           
 0  0 018C20C  ?  0000  075E33FC
 0  0 018C21C  ?  0000  075E2A23
 0  0 018C22C  ?  0000  075E2085
           
0  0018C2E0  ?  0000  075E33FC

0  0018C3C8  ?  0000  075EB008
0  0018C3CC  ?  0000  075EAC83
0  0018C3F0  ?  0000  075E33FC
0  0018C424  ?  0000  075E3077

0  0018CA2C  ?  0000  075E85D2
0  0018CA30  ?  0000  075E8098
0  0018CA34  ?  0000  075E6FC4
0  0018CA38  ?  0000  075E6E2C


不管用什么插件都修复不了,没办法只好手工了。保存好IAT,重载软件,一个一个慢慢跟。


004079BB      CALL UltraFxp.004078B8  (JMP DWORD PTR DS:[58C2E0])


过了这个call,eax=400000,这应该是GetModuleHandleA。其他的我不详细写了,我得出的前面8个为:


1  0018C20C  kernel32.dll  016F  GetModuleHandleA
1  0018C21C  kernel32.dll  0103  GetCommandLineA
1  0018C22C  kernel32.dll  00B0  ExitProcess

1  0018C2E0  kernel32.dll  016F  GetModuleHandleA

1  0018C3C8  kernel32.dll  01D5  GetVersionExA
1  0018C3CC  kernel32.dll  01D4  GetVersion
1  0018C3F0  kernel32.dll  016F  GetModuleHandleA

1  0018C424  kernel32.dll  0135  GetCurrentProcess


其中0018C22C处的我跟到了VirtualFree,但后来运行退出时总有问题,改成ExitProcess就好了,不知
有没有道理。


0018CA2C~0018CA38四个,一开始怎么也跟不到系统函数中,一生气干脆把相应的调用nop掉了,嘿,
就行了。后来再静下心来跟了一下,第一个函数是检测有没有调试器,调用了IsDebuggerPresent函数
,可以用IsDebuggerPresent代替。第三个是用来复制注册信息的,其他两个好像没什么用。因此相应
的调用改为:


004EE33F      CALL 004E4EDC       //nop掉
             
004EE352      CALL 004E4ECC      //nop掉
             
004EE361      PUSH EAX          //eax里是注册信息地址,调用返回eax=1,表示已注册,0是未注册
004EE362      CALL 004E4EC4     //因此这两句改成:mov eax,1
             
004EE392      CALL 004E4ED4      //nop掉
004EE397      RETN
           
           
好,IAT修改好了,修复dump.exe。运行dump_.exe,出错。真麻烦啊,看看吧:         


0012FE24      LODS BYTE PTR DS:[ESI]
0012FE25      XOR ALDL
0012FE27      STOS BYTE PTR ES:[EDI]
0012FE28      LOOPD SHORT 0012FE24
0012FE2A      POP ECX
0012FE2B      POP ESI
0012FE2C      CALL DWORD PTR DS:[4EEAA4]   //出错!解码函数,指向壳内
0012FE32      ADD ESP, 54
0012FE38      POPAD
0012FE39      PUSH 1010101
0012FE3E      RETN


程序在堆栈中运行,开始我以为搞错了,怎么跑到堆栈中去了?后来发现这些代码都是动态生成的,是
类似前面0056EED4~0056EF5F的代码生成的,然后由这段代码再解码正常的程序段。0012FE2C 处是解
码函数,指向壳内,脱壳后当然会出错了。这样的地方有100多处。看来只好自己编程模拟壳来解码了
。还好解码函数很简单。还有一处类似的解码函数,CALL DWORD PTR DS:[4F18D5]。在程序末端加入以
下代码:

0056FFA0      TEST ALAL
0056FFA2      JE SHORT 0056FFC0
0056FFA4      MOV EDIESI
0056FFA6      MOV EBX, 52E4B8F8
0056FFAB      LODS BYTE PTR DS:[ESI]
0056FFAC      XOR EBXECX
0056FFAE      XOR ALBL
0056FFB0      ROL ALCL
0056FFB2      XOR ALBH
0056FFB4      STOS BYTE PTR ES:[EDI]
0056FFB5      LOOPD SHORT 0056FFAB
0056FFB7      RETN
0056FFB8      NOP
           
0056FFBF      NOP
0056FFC0      MOV EDIESI
0056FFC2      MOV EBX, 52E4B8F8
0056FFC7      LODS BYTE PTR DS:[ESI]
0056FFC8      XOR EBXECX
0056FFCA      XOR ALBH
0056FFCC      ROR ALCL
0056FFCE      XOR ALBL
0056FFD0      STOS BYTE PTR ES:[EDI]
0056FFD1      LOOPD SHORT 0056FFC7
0056FFD3      RETN
            
            
再把[4EEAA4]内容改为0056FFC0,[4F18D5]改为0056FFA0,保存。运行,OK。

注册信息放在4ee3e0处,你爱怎么改就怎么改。


终于写完了,好累。有些地方说起来简单,但都是经过若干遍试出来的,希望对感兴趣的人有点帮助。
错误之处,还请各位大侠指正。


pyzpyz

2004.2.25