发新话题
打印

[转载]用Ollydbg手脱SafeDisc V2.43.000加壳的DLL

[转载]用Ollydbg手脱SafeDisc V2.43.000加壳的DLL

文章作者:Fly

【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

【调试环境】:WinXP、OllydbgV1.10、PEiD、LordPE、ImportREC、WinHex

—————————————————————————————————
【脱壳过程】:


SafeDisc是著名的光碟保护软件,现在也单独加壳PE文件了。
本教程演示的AdobeLM.dllV1.0.2.38是AdobePremiereProV1.5的文件,SafeDiscV2.43.000保护,不是最新版,况且一般壳保护DLL时强度都要降低,SafeDisc对此DLL没有使用驱动和CC解码,因此相对来说难度不高。但是SafeDisc的输入表和SDK修复比较麻烦。
此文件以前jingulong搞定过,感谢heXer和shoooo的帮忙,SDK由heXer修复。
由于没有主程序测试,可能还会有其他隐藏的暗桩。
此教程不适合新手练习。断断续续整理了很长时间,作为2005年的结笔吧,光阴似箭。
—————————————————————————————————
一、准备动作


设置Ollydbg忽略所有的异常选项。用IsDebug插件去掉OllyDBD的调试器标志。

1005A05E55pushebp
1005A05F8BECmovebp,esp
1005A06160pushad
1005A062BB5EA00510movebx,1005A05E
1005A06733C9xorecx,ecx
1005A0698A0D3DA00510movcl,byteptrds:[1005A03D]
1005A06F85C9testecx,ecx
1005A071740Cjeshort1005A07F
1005A073B8D3A00510moveax,1005A0D3
1005A0782BC3subeax,ebx
1005A07A83E805subeax,5
1005A07DEB0Ejmpshort1005A08D
1005A07F51pushecx
1005A080B919A10510movecx,1005A119
1005A0858BC1moveax,ecx
1005A0872BC3subeax,ebx
1005A089034101addeax,dwordptrds:[ecx+1]
1005A08C59popecx
1005A08DC603E9movbyteptrds:[ebx],0E9
1005A090894301movdwordptrds:[ebx+1],eax
1005A09351pushecx
1005A0946809A00510push1005A009
1005A09933C0xoreax,eax
1005A09B85C9testecx,ecx
1005A09D7405jeshort1005A0A4
1005A09F8B4508moveax,dwordptrss:[ebp+8]
1005A0A2EB00jmpshort1005A0A4
1005A0A450pusheax
1005A0A5E876000000call1005A120
//壳处理
1005A0AA83C408addesp,8
1005A0AD59popecx
1005A0AE83F800cmpeax,0
1005A0B1741Cjeshort1005A0CF
1005A0B3C603C2movbyteptrds:[ebx],0C2
1005A0B6C643010Cmovbyteptrds:[ebx+1],0C
1005A0BA85C9testecx,ecx
1005A0BC7409jeshort1005A0C7
1005A0BE61popad
1005A0BF5Dpopebp
1005A0C0B800000000moveax,0
1005A0C5EB97jmpshort1005A05E
1005A0C750pusheax
1005A0C8A129A00510moveax,dwordptrds:[1005A029]
1005A0CDFFD0calleax
1005A0CF61popad
1005A0D05Dpopebp
1005A0D1EB46jmpshort1005A119
1005A0D3807C240800cmpbyteptrss:[esp+8],0
1005A0D8753Fjnzshort1005A119
1005A0DA51pushecx
1005A0DB8B4C2404movecx,dwordptrss:[esp+4]
1005A0DF890D13A10510movdwordptrds:[1005A113],ecx
1005A0E5B9F1A00510movecx,1005A0F1
1005A0EA894C2404movdwordptrss:[esp+4],ecx
1005A0EE59popecx
1005A0EFEB28jmpshort1005A119
1005A0F150pusheax
1005A0F2B82DA00510moveax,1005A02D
1005A0F7FF7008pushdwordptrds:[eax+8]
1005A0FA8B400Cmoveax,dwordptrds:[eax+C]
1005A0FDFFD0calleax
1005A0FFB82DA00510moveax,1005A02D
1005A104FF30pushdwordptrds:[eax]
1005A1068B4004moveax,dwordptrds:[eax+4]
1005A109FFD0calleax
1005A10B58popeax
1005A10CFF3513A10510pushdwordptrds:[1005A113]
1005A112C3retn
1005A119E9A6CEFCFFjmp10026FC4
//飞向光明之巅


—————————————————————————————————
二、Anti


SafeDiscV2.43.000对OllyDBG的反调试还是很少的,下面没有分析对SoftICE的Anti
SafeDisc会在你的Temp目录下生成~df394b.tmp,这个其实是SecServ.dll,里面Anti
————————————————————————
1、IsDebuggerPresent

BPIsDebuggerPresent
Shift+F9,中断后取消断点,Alt+F9

00879ACAFFD0calleax
00879ACC8BF0movesi,eax
//返回这里
00879ACE66:85F6testsi,si
00879AD17413jeshort00879AE6
//IsDebuggerPresent检测
00879AD3E8A277FFFFcall0087127A
00879AD866:8BF0movsi,ax
00879ADB66:F7DEnegsi
00879ADE1BF6sbbesi,esi
00879AE046incesi
00879AE166:85F6testsi,si
00879AE47513jnzshort00879AF9
00879AE68B442408moveax,dwordptrss:[esp+8]
00879AEA8B08movecx,dwordptrds:[eax]
00879AEC81E1EA894267andecx,674289EA
00879AF28908movdwordptrds:[eax],ecx
00879AF466:8BC6movax,si
00879AF75Epopesi
00879AF8C3retn

因为我们已经使用IsDebug插件了,所以这里不必处理,只是借用此断点来继续下面的流程。

————————————————————————
2、ZwQueryInformationProcess

BPGetCurrentProcess
Shift+F9,中断后取消断点,Alt+F9

00879889FF15B4208C00calldwordptrds:[8C20B4];kernel32.GetCurrentProcess
//返回这里
0087988F50pusheax
00879890FFD7calledi;ntdll.ZwQueryInformationProcess
008798928B44240Cmoveax,dwordptrss:[esp+C]
//检测DebugPort,修改[esp+0C]处为0,或者在下面跳转处改标志位
0087989685C0testeax,eax
008798987502jnzshort0087989C
//跳则Over

————————————————————————
3、普通断点检测

脱壳时一般要有好的习惯,用过的断点要立刻清除。在此壳中不要留有普通断点。
如果上面我们没有清掉API断点,那么这里会检测到

0087952053pushebx
008795218B19movebx,dwordptrds:[ecx]
00879523803C03CCcmpbyteptrds:[ebx+eax],0CC
//自kernel32.dll各函数入口检测普通INT3
008795277501jnzshort0087952A
0087952946incesi
0087952A83C104addecx,4
0087952D4Adecedx
0087952E75F1jnzshort00879521
008795305Bpopebx
0087953133D2xoredx,edx
008795333BD6cmpedx,esi
008795355Epopesi
008795361BC0sbbeax,eax
00879538F7D8negeax
0087953A66:85C0testax,ax
//AX要=0
0087953D7512jnzshort00879551

好了,SafeDiscV2.43.000对OllyDBG的Anti手段就这么点
稍有威胁的是ZwQueryInformationProcess,去除Anti不难


—————————————————————————————————
三、获取正确的函数地址


下面用脚本来演示这部分的处理。
重新加载AdobeLM.dll,运行SafeDiscV2.43.000.osc脚本。脚本运行完毕后OllyDBG自动暂停在OEP

10026FC455pushebp
//OEP
10026FC58BECmovebp,esp
10026FC753pushebx
10026FC88B5D08movebx,dwordptrss:[ebp+8]
10026FCB56pushesi
10026FCC8B750Cmovesi,dwordptrss:[ebp+C]
10026FCF57pushedi
10026FD08B7D10movedi,dwordptrss:[ebp+10]
10026FD385F6testesi,esi
10026FD57509jnzshort10026FE0
10026FD7833D80AE041000cmpdwordptrds:[1004AE80],0
10026FDEEB26jmpshort10027006
10026FE083FE01cmpesi,1
10026FE37405jeshort10026FEA
10026FE583FE02cmpesi,2
10026FE87522jnzshort1002700C
10026FEAA108C60410moveax,dwordptrds:[1004C608]
10026FEF85C0testeax,eax
10026FF17409jeshort10026FFC
10026FF357pushedi
10026FF456pushesi
10026FF553pushebx
10026FF6FFD0calleax

随便从程序中找个API调用:
10026EF8FF15E4610310calldwordptrds:[100361E4];kernel32.GetSystemTime
数据窗口跟随100361E4,输入表函数已经全部获得正确的系统地址了。

10036000BBD5DC778E77DA77E7EBDA77F06BDA77
100360101B76DA778378DA77B377DA7700000000
100360203934175D000000003B6AEF77A66CEF77
10036030FCC6EF77D55FEF77105EEF77829AEF77
10036040C06DEF770B5DEF77F15FEF77A75BEF77
1003605021A8EF770CD1EF77A059EF7700000000
10036060D7EF807C0E18807C779B807CC7A0807C
100360707AA1877C8F0C817CAC92807C3797807C
1003608057B3807CA197837C625F827CAD9C807C
100360904B6F827C28AC807C5128817C3103937C
100360A066AA807C3025807CCBCA817C5935817C
100360B0241A807C1990837C299F807C2516807C
100360C04224807C6E9C807CA926827C7217817C
100360D050F8817CCBD8817C57BB807C80A4807C
100360E0B98C837CC09F807CED70837C7ED4807C
100360F0E312817C53C1817C819A807C149B807C
100361002929817C1011817C6A48817C782C817C
1003611023CC817C5F48817C3FDC817CEE1E807C
100361206910817CA92C817CCFC6807C8A2B867C
100361308603817C58CD807CA60D817C9F0F817C
100361402AE8817C4399807C5097807C4003937C
100361505334817C0F2B817CED09937CB39E807C
10036160C42F887C29B5807C1103817CE0C6807C
100361704E99807C4C17817C542A827CED10927C
100361800510927CA19F807C8A18937C8DB7807C
100361906C94807CFEB9807CFCB7807C2F08817C
100361A03FEB807CBDE4817C289C807C7C2F817C
100361B01BEC807CA724807C0DE0807C8D2C817C
100361C0AB14817CAD97807C9497807C7B97807C
100361D0407A957CE1EA817CF59B807CA9CC807C
100361E0AE94837C6B17807CC1C9807C2B2E837C
100361F03D04937CD405937CFD79937CA2CA817C
100362004EA3807CC4CE807CE62B817C93D2807C
10036210161E807C0000000062DBD177AEE2D177
100362206D86D177C5D3D17756B5D1779786D177
10036230DED4D1775ADCD177E188D277A867D277
10036240C96CD277508ED1777C94D177C5B4D177
10036250EF01D377B1B4D177A452D277AE21D277
100362608EC7D177D3DED177758FD1777CB5D177
100362701A8CD177BBD7D17798ECD377B8E7D177
100362803CFCD1772EF8D3779DB4D177FAE8D177
10036290A8C6D177DCE5D1772F3AD277A9F8D377
100362A02C90D17764C0D1774BE3D1772F15D377
100362B032E0D177D4C4D177068CD177DEA2D177
100362C0BCC6D1770B05D5770000000000000000

OEPRVA=00026FC4IATRVA=00036000IATSize=2C8
用LordPE把AdobeLM.dll抓取出来,修复输入表得到dump_.dll

————————————————————————
SafeDiscV2.43.000.osc辅助脚本如下


//////////////////////////////////////////////////
//FileName:SafeDiscV2.43.000.osc
//Comment:SafeDiscV2.43.000FixedImportingFunction
//Environment:WinXPSP2,OllyDbgV1.10,OllyScriptV0.92
//Author:fly
//WebSite:http://www.unpack.cn
//Date:2005-11-2322:00
//////////////////////////////////////////////////
#log
dbh


varEP
varTemp
varIsDebuggerPresent
varGetCurrentProcess
varZwQueryInformationProcess
varCreateEventA
varMagicJmp
varFixedOver


//IsDebuggerPresent————————————————

movEP,eip
logEP

gpa"IsDebuggerPresent","KERNEL32.dll"
movIsDebuggerPresent,$RESULT
eobIsDebuggerPresent
bpIsDebuggerPresent

esto
GoOn0:
esto

IsDebuggerPresent:
logeip
cmpeip,IsDebuggerPresent
jneGoOn0
bcIsDebuggerPresent


//ZwQueryInformationProcess————————————

/*
00879889FF15B4208C00calldwordptrds:[8C20B4];kernel32.GetCurrentProcess
0087988F50pusheax
00879890FFD7calledi;ntdll.ZwQueryInformationProcess
008798928B44240Cmoveax,dwordptrss:[esp+C]
0087989685C0testeax,eax
008798987502jnzshort0087989C
*/

gpa"GetCurrentProcess","KERNEL32.dll"
movGetCurrentProcess,$RESULT
eobGetCurrentProcess
bpGetCurrentProcess

esto
GoOn1:
esto

GetCurrentProcess:
cmpeip,GetCurrentProcess
jneGoOn1
bcGetCurrentProcess
rtu

findeip,#8B44240C85C0#
cmp$RESULT,0
jeNoFind

movZwQueryInformationProcess,$RESULT
logZwQueryInformationProcess
eobZwQueryInformationProcess
bpZwQueryInformationProcess
esto

ZwQueryInformationProcess:
bcZwQueryInformationProcess
movTemp,esp
addTemp,0C
mov[Temp],0000


//CreateEventA——————————————————

gpa"CreateEventA","KERNEL32.dll"
movCreateEventA,$RESULT
eobCreateEventA
bphwsCreateEventA,"x"

esto
GoOn2:
esto

CreateEventA:
logeip
cmpeip,CreateEventA
jneGoOn2
bphwcCreateEventA
rtu


//EP———————————————————————

addEP,1
movTemp,[EP]
addTemp,4
addEP,Temp
addEP,6
logEP
movTemp,[EP]
andTemp,0FF
logTemp
addEP,1
addEP,Temp
logEP


//jmpSecond

//FixedImportingFunction—————————————

/*
008BF0888B45F4moveax,dwordptrss:[ebp-C]
008BF08B40inceax
008BF08C8945F4movdwordptrss:[ebp-C],eax
008BF08F8B45F4moveax,dwordptrss:[ebp-C]
008BF0923B4514cmpeax,dwordptrss:[ebp+14]
008BF0957355jnbshort008BF0EC
008BF0978B45F4moveax,dwordptrss:[ebp-C]
008BF09AC1E803shreax,3
008BF09D8B4DF8movecx,dwordptrss:[ebp-8]
008BF0A08B15DCEC8D00movedx,dwordptrds:[8DECDC]
008BF0A68B0C8Amovecx,dwordptrds:[edx+ecx*4]
008BF0A90FB60401movzxeax,byteptrds:[ecx+eax]
008BF0AD8B4DF4movecx,dwordptrss:[ebp-C]
008BF0B083E107andecx,7
008BF0B36A01push1
008BF0B55Apopedx
008BF0B6D3E2shledx,cl
008BF0B823C2andeax,edx
008BF0BA85C0testeax,eax
008BF0BC752Cjnzshort008BF0EA
008BF0BE8B45F8moveax,dwordptrss:[ebp-8]
008BF0C169C08D000000imuleax,eax,8D
008BF0C78B0DE0EC8D00movecx,dwordptrds:[8DECE0]
008BF0CD8B44014Cmoveax,dwordptrds:[ecx+eax+4C]
008BF0D18B4DF4movecx,dwordptrss:[ebp-C]
008BF0D4FF3488pushdwordptrds:[eax+ecx*4]
008BF0D7FF75F8pushdwordptrss:[ebp-8]
008BF0DAE8DB000000call008BF1BA
008BF0DF59popecx
008BF0E059popecx
008BF0E18B4DF4movecx,dwordptrss:[ebp-C]
008BF0E48B5518movedx,dwordptrss:[ebp+18]
008BF0E789048Amovdwordptrds:[edx+ecx*4],eax
008BF0EAEB9Cjmpshort008BF088
008BF0ECEB07jmpshort008BF0F5
*/

eobFixedImportingFunction
findeip,#D3E223C285C0752C8B45F8#
cmp$RESULT,0
jeNoFind
add$RESULT,4
movMagicJmp,$RESULT
bphwsMagicJmp,"x"

findMagicJmp,#EB9CEB07#
cmp$RESULT,0
jeNoFind
add$RESULT,2
movFixedOver,$RESULT
bphwsFixedOver,"x"

bphwsEP,"x"

esto
GoOn3:
esto

FixedImportingFunction:
cmpeip,MagicJmp
jeMagicJmp
cmpeip,FixedOver
jeMagicJmp
cmpeip,EP
jeEP

MagicJmp:
bphwcMagicJmp
asmMagicJmp,"xoreax,eax"

esto

FixedOver:
asmMagicJmp,"testeax,eax"
bphwsMagicJmp,"x"
jmpGoOn3

Second:
bphwsEP,"x"
eobEP
esto

EP:
logEP
bphwcMagicJmp
bphwcFixedOver
bphwcEP
sti


//GameOver————————————————————

logeip
cmteip,"ThisistheOEP!FoundBy:fly"
MSG"Just:OEP!DumpandFixIAT/Reloction.GoodLuck"
ret

NoFind:
MSG"Error!MaybeIt'snotSafeDiscV2.43.000!"
ret



—————————————————————————————————
四、修复函数调用地址


虽然已经获得了正确的函数系统地址,但是SafeDisc的输入表呼叫地址乱处理了,麻烦就在这里了。
把SafeDiscV2.43.000.osc中“//jmpSecond”的“//”去掉,新开个OllyDBG,重新加载AdobeLM.dll,运行脚本。现在脚本没有处理输入表函数,直接停在OEP处。
把我们第三步获取的10036000-100362C8函数地址复制到10046000处,以备下面比较、修复。

Alt+M察看AdobeLM.dll内存
1000000000001000(4096.)AdobeLM10000000PEheader
1000100000035000(217088.)AdobeLM10000000.textcode
1003600000008000(32768.)AdobeLM10000000.rdata
1003E0000000F000(61440.)AdobeLM10000000.data
1004D00000005000(20480.)AdobeLM10000000.rsrc
1005200000005000(20480.)AdobeLM10000000.reloc
1005700000003000(12288.)AdobeLM10000000stxt774
1005A00000004000(16384.)AdobeLM10000000stxt371SFX,imports

我们把修复代码放在第3个区段吧,设置这几个区段为完整权限。
Ctrl+G:1003E000,在1003E000处Ctrl+*新建EIP,写入Patch代码:

1003E00060pushad
1003E001BE00100010movesi,10001000
//代码段开始地址
1003E006BF005F0310movedi,10035F00
//代码段结束地址
1003E00B3BF7cmpesi,edi
1003E00D7C05jlshort1003E014
1003E00FE991000000jmp1003E0A5
//修复结束跳转
1003E0148B06moveax,dwordptrds:[esi]
1003E0163D00600310cmpeax,10036000
//输入表开始地址
1003E01B7D03jgeshort1003E020
1003E01D46incesi
1003E01EEBEBjmpshort1003E00B
1003E0203DC8620310cmpeax,100362C8
//输入表结束地址
1003E0257FF6jgshort1003E01D
1003E0278B18movebx,dwordptrds:[eax]
1003E02985DBtestebx,ebx
1003E02B74F0jeshort1003E01D
1003E02D81FB00000010cmpebx,10000000
//判断是否是壳不加密的API
1003E0337FE8jgshort1003E01D
1003E0358D4EFEleaecx,dwordptrds:[esi-2]
//取函数调用的地址
1003E03866:8B19movbx,wordptrds:[ecx]
1003E03B66:81FBFF15cmpbx,15FF
//比较是否是call
1003E04075DBjnzshort1003E01D
//循环扫描符合calldwordptrds:[10036XXX]条件的
1003E0428B1DF0E00310movebx,dwordptrds:[1003E0F0]
//[1003E0F0]处预先写入1003E100★
1003E0488933movdwordptrds:[ebx],esi
//保存搜索进度
1003E04A83C304addebx,4
1003E04D891DF0E00310movdwordptrds:[1003E0F0],ebx
//保存
1003E0538935F4E00310movdwordptrds:[1003E0F4],esi
1003E059FFE1jmpecx
//跳到函数调用的地址处执行
1003E05A90nop
1003E05B90nop
1003E05C90nop
1003E05D90nop
1003E05E90nop
1003E05F90nop
1003E06090nop
1003E06190nop
1003E06290nop
1003E06390nop
1003E0648B1DF0E00310movebx,dwordptrds:[1003E0F0]
//SafeDisc解密后强制跳到这里
1003E06A8B0424moveax,dwordptrss:[esp]
//[ESP]是解密后的函数系统地址
1003E06D8903movdwordptrds:[ebx],eax
//保存函数系统地址
1003E06FB9C8020000movecx,2C8
1003E074BF00600410movedi,10046000
//把我们第三步获取的10036000-100362C8函数地址复制到10046000处★
1003E079F2:AFrepnescasdwordptres:[edi]
//搜寻相同的函数地址
1003E07B7528jnzshort1003E0A5
//没找到?哦,应该都可以找到的
1003E07D90nop
1003E07E90nop
1003E07F90nop
1003E08090nop
1003E08181EF04000100subedi,10004
//10046000-10036000=100000再减4就是找到的存放函数地址的地址了★
1003E0878B35F4E00310movesi,dwordptrds:[1003E0F4]
//函数调用地址
1003E08D893Emovdwordptrds:[esi],edi
//修复吧
1003E08F83C604addesi,4
1003E092E96FFFFFFFjmp1003E006
//继续循环
1003E0978B35F4E00310movesi,dwordptrds:[1003E0F4]
1003E09D83C604addesi,4
1003E0A0E961FFFFFFjmp1003E006
//继续循环
1003E0A561popad
//GameOver修复完毕
1003E0A6EBFEjmpshort1003E0A6

二进制代码复制如下:
60BE00100010BF005F03103BF77C05E9910000008B063D006003107D0346EBEB
3DC86203107FF68B1885DB74F081FB000000107FE88D4EFE668B196681FBFF15
75DB8B1DF0E00310893383C304891DF0E003108935F4E00310FFE19090909090
909090908B1DF0E003108B04248903B9C8020000BF00600410F2AF7528909090
9081EF040001008B35F4E00310893E83C604E96FFFFFFF8B35F4E0031083C604
E961FFFFFF61EBFE

————————————————————————
SafeDisc解密CALL里面的修改

10001403FF15C4620310calldwordptrds:[100362C4]

00AED180681713EABFpushBFEA1317
00AED1859Cpushfd
00AED18660pushad
00AED18754pushesp
00AED18868C0D1AE00push0AED1C0
00AED18DE80322DDFFcall008BF395

008BF39555pushebp
008BF3968BECmovebp,esp
008BF39883EC40subesp,40
008BF39B53pushebx
008BF39C56pushesi
008BF39D57pushedi
008BF39EF0:FF05742F8D00lockincdwordptrds:[8D2F74]
008BF3A5740Ejeshort008BF3B5
008BF3A76AFFpush-1
008BF3A9FF3548ED8D00pushdwordptrds:[8DED48]
008BF3AFFF1584208C00calldwordptrds:[8C2084]
008BF3B5EB0Ajmpshort008BF3C1
008BF3D58B4508moveax,dwordptrss:[ebp+8]
008BF3D88B00moveax,dwordptrds:[eax]
008BF3DA8945E0movdwordptrss:[ebp-20],eax
008BF3DD8B4508moveax,dwordptrss:[ebp+8]
008BF3E08B4004moveax,dwordptrds:[eax+4]
008BF3E38945E4movdwordptrss:[ebp-1C],eax
008BF3E6837DE0FFcmpdwordptrss:[ebp-20],-1
008BF3EA0F85A5000000jnz008BF495
008BF3F08365E000anddwordptrss:[ebp-20],0
008BF3F4EB07jmpshort008BF3FD
008BF3F68B45E0moveax,dwordptrss:[ebp-20]
008BF3F940inceax
008BF3FA8945E0movdwordptrss:[ebp-20],eax
008BF3FDA1E0EC8D00moveax,dwordptrds:[8DECE0]
008BF4028B4DE0movecx,dwordptrss:[ebp-20]
008BF4053B480Fcmpecx,dwordptrds:[eax+F]
008BF4080F8387000000jnb008BF495
008BF40EFF75E0pushdwordptrss:[ebp-20]
008BF411E8F7040000call008BF90D
008BF41659popecx
008BF4170FB7C0movzxeax,ax
008BF41A85C0testeax,eax
008BF41C7472jeshort008BF490
008BF41E8365E400anddwordptrss:[ebp-1C],0
008BF422EB07jmpshort008BF42B
008BF4248B45E4moveax,dwordptrss:[ebp-1C]
008BF42740inceax
008BF4288945E4movdwordptrss:[ebp-1C],eax
008BF42B8B45E0moveax,dwordptrss:[ebp-20]
008BF42E69C08D000000imuleax,eax,8D
008BF4348B0DE0EC8D00movecx,dwordptrds:[8DECE0]
008BF43A8B55E4movedx,dwordptrss:[ebp-1C]
008BF43D3B540158cmpedx,dwordptrds:[ecx+eax+58]
008BF4417343jnbshort008BF486
008BF4438B45E0moveax,dwordptrss:[ebp-20]
008BF44669C08D000000imuleax,eax,8D
008BF44C8B4DE4movecx,dwordptrss:[ebp-1C]
008BF44F69C9C3040000imulecx,ecx,4C3
008BF4558B15E0EC8D00movedx,dwordptrds:[8DECE0]
008BF45B8B8402C3000000moveax,dwordptrds:[edx+eax+C3]
008BF4628B5508movedx,dwordptrss:[ebp+8]
008BF4658B5208movedx,dwordptrds:[edx+8]
008BF4683B9408AA040000cmpedx,dwordptrds:[eax+ecx+4AA]
008BF46F7513jnzshort008BF484
008BF4718B4508moveax,dwordptrss:[ebp+8]
008BF4748B4DE4movecx,dwordptrss:[ebp-1C]
008BF477894804movdwordptrds:[eax+4],ecx
008BF47A8B4508moveax,dwordptrss:[ebp+8]
008BF47D8B4DE0movecx,dwordptrss:[ebp-20]
008BF4808908movdwordptrds:[eax],ecx
008BF482EB02jmpshort008BF486
008BF484EB9Ejmpshort008BF424
008BF4868B4508moveax,dwordptrss:[ebp+8]
008BF4898338FFcmpdwordptrds:[eax],-1
008BF48C7402jeshort008BF490
008BF48EEB05jmpshort008BF495
008BF490E961FFFFFFjmp008BF3F6
008BF4958B45E0moveax,dwordptrss:[ebp-20]
008BF49869C08D000000imuleax,eax,8D
008BF49E8B0DE0EC8D00movecx,dwordptrds:[8DECE0]
008BF4A48B8401C3000000moveax,dwordptrds:[ecx+eax+C3]
008BF4AB8945DCmovdwordptrss:[ebp-24],eax
008BF4AE8B45C8moveax,dwordptrss:[ebp-38]
008BF4B18945FCmovdwordptrss:[ebp-4],eax
008BF4B4FF75C8pushdwordptrss:[ebp-38]
008BF4B7FF75E4pushdwordptrss:[ebp-1C]
008BF4BAFF75DCpushdwordptrss:[ebp-24]
008BF4BDE8E1F1FFFFcall008BE6A3
008BF4C283C40Caddesp,0C
008BF4C58945F4movdwordptrss:[ebp-C],eax
008BF4C8837DF400cmpdwordptrss:[ebp-C],0
008BF4CC7439jeshort008BF507
//Patch①、jmp008BF507★强制每次都解密

008BF5078B45E4moveax,dwordptrss:[ebp-1C]
008BF50A8945D8movdwordptrss:[ebp-28],eax
008BF50D8D45CCleaeax,dwordptrss:[ebp-34]
008BF51050pusheax
008BF5118D45D0leaeax,dwordptrss:[ebp-30]
008BF51450pusheax
008BF5158D45F8leaeax,dwordptrss:[ebp-8]
008BF51850pusheax
008BF519FF75C8pushdwordptrss:[ebp-38]
008BF51CE84F040000call008BF970
008BF52183C410addesp,10
008BF5240FB7C0movzxeax,ax
008BF52783F801cmpeax,1
008BF52A0F8575010000jnz008BF6A5
008BF5308B45C8moveax,dwordptrss:[ebp-38]
008BF5332B45CCsubeax,dwordptrss:[ebp-34]
008BF53650pusheax
008BF537E87C0EFCFFcall008803B8
008BF53C50pusheax
008BF53DE87B0EFCFFcall008803BD
008BF54259popecx
008BF54359popecx
008BF5440FB7C0movzxeax,ax
008BF54785C0testeax,eax
008BF5490F84A5000000je008BF5F4
008BF54F8B45C8moveax,dwordptrss:[ebp-38]
//这里是SafeDisc的暗桩,某些符合上面扫描条件的地址含有SafeDisc暗桩
//Patch②代码:★
008BF54FF0:FF0D742F8D00lockdecdwordptrds:[8D2F74]
008BF556780Cjsshort008BF564
008BF558FF3548ED8D00pushdwordptrds:[8DED48]
008BF55EFF154C208C00calldwordptrds:[8C204C]
008BF5648B650Cmovesp,dwordptrss:[ebp+C]
008BF56761popad
008BF5689Dpopfd
008BF56958popeax
008BF56A83C404addesp,4
008BF56DE925EB770Fjmp1003E097
//平衡堆栈后跳回去继续循环

OllyDBG中二进制代码复制如下:
F0FF0D742F8D00780CFF3548ED8D00FF154C208C008B650C619D5883C404E925
EB770F

008BF5F48B45F8moveax,dwordptrss:[ebp-8]
008BF5F70345CCaddeax,dwordptrss:[ebp-34]
008BF5FA8B4DC8movecx,dwordptrss:[ebp-38]
008BF5FD2BC8subecx,eax
008BF5FF894DF0movdwordptrss:[ebp-10],ecx
008BF602FF75F0pushdwordptrss:[ebp-10]
008BF605E814070000call008BFD1E
008BF60A59popecx
008BF60B0FB7C0movzxeax,ax
008BF60E83F801cmpeax,1
008BF6110F858E000000jnz008BF6A5
008BF6178B45E4moveax,dwordptrss:[ebp-1C]
008BF61A69C0C3040000imuleax,eax,4C3
008BF6208B4DFCmovecx,dwordptrss:[ebp-4]
008BF6238B55DCmovedx,dwordptrss:[ebp-24]
008BF6268B4902movecx,dwordptrds:[ecx+2]
008BF6293B8C02AA040000cmpecx,dwordptrds:[edx+eax+4AA]
008BF6307573jnzshort008BF6A5
008BF6328B45FCmoveax,dwordptrss:[ebp-4]
008BF6350FB600movzxeax,byteptrds:[eax]
008BF6383DFF000000cmpeax,0FF
008BF63D7566jnzshort008BF6A5
008BF63F8B45FCmoveax,dwordptrss:[ebp-4]
008BF6420FB64001movzxeax,byteptrds:[eax+1]
008BF64683F815cmpeax,15
008BF649755Ajnzshort008BF6A5
008BF64B8B45E4moveax,dwordptrss:[ebp-1C]
008BF64E8945D8movdwordptrss:[ebp-28],eax
008BF651A1E0EC8D00moveax,dwordptrds:[8DECE0]
008BF6568B4026moveax,dwordptrds:[eax+26]
008BF6590345F0addeax,dwordptrss:[ebp-10]
008BF65C50pusheax
008BF65DFF75D8pushdwordptrss:[ebp-28]
008BF6608B45E0moveax,dwordptrss:[ebp-20]
008BF66369C08D000000imuleax,eax,8D
008BF6698B0DE0EC8D00movecx,dwordptrds:[8DECE0]
008BF66FFF740158pushdwordptrds:[ecx+eax+58]
008BF673E8AA020000call008BF922
008BF67883C40Caddesp,0C
008BF67B8945D8movdwordptrss:[ebp-28],eax
008BF67E8B45D8moveax,dwordptrss:[ebp-28]
008BF681C1E803shreax,3
008BF6848B4DE0movecx,dwordptrss:[ebp-20]
008BF6878B15DCEC8D00movedx,dwordptrds:[8DECDC]
008BF68D8B0C8Amovecx,dwordptrds:[edx+ecx*4]
008BF6900FB60401movzxeax,byteptrds:[ecx+eax]
008BF6948B4DD8movecx,dwordptrss:[ebp-28]
008BF69783E107andecx,7
008BF69A6A01push1
008BF69C5Apopedx
008BF69DD3E2shledx,cl
008BF69F23C2andeax,edx
008BF6A185C0testeax,eax
008BF6A374ACjeshort008BF651
008BF6A58B45E0moveax,dwordptrss:[ebp-20]
008BF6A869C08D000000imuleax,eax,8D
008BF6AE8B0DE0EC8D00movecx,dwordptrds:[8DECE0]
008BF6B48B44014Cmoveax,dwordptrds:[ecx+eax+4C]
008BF6B88B4DD8movecx,dwordptrss:[ebp-28]
008BF6BB8B0488moveax,dwordptrds:[eax+ecx*4]
008BF6BE8945D8movdwordptrss:[ebp-28],eax
008BF6C18B45D8moveax,dwordptrss:[ebp-28]
008BF6C469C0C3040000imuleax,eax,4C3
008BF6CA8B4DDCmovecx,dwordptrss:[ebp-24]
008BF6CD8B840172040000moveax,dwordptrds:[ecx+eax+472]
008BF6D48945F4movdwordptrss:[ebp-C],eax
008BF6D7837DF400cmpdwordptrss:[ebp-C],0
008BF6DB7526jnzshort008BF703
008BF6DDFF75D8pushdwordptrss:[ebp-28]
008BF6E0FF75E0pushdwordptrss:[ebp-20]
008BF6E3E8D2FAFFFFcall008BF1BA
008BF6E859popecx
008BF6E959popecx
008BF6EA8945F4movdwordptrss:[ebp-C],eax
008BF6ED8B45D8moveax,dwordptrss:[ebp-28]
008BF6F069C0C3040000imuleax,eax,4C3
008BF6F68B4DDCmovecx,dwordptrss:[ebp-24]
008BF6F98B55F4movedx,dwordptrss:[ebp-C]
008BF6FC89940172040000movdwordptrds:[ecx+eax+472],edx
008BF703FF75F4pushdwordptrss:[ebp-C]
008BF706FF75C8pushdwordptrss:[ebp-38]
008BF709FF75E4pushdwordptrss:[ebp-1C]
008BF70CFF75DCpushdwordptrss:[ebp-24]
008BF70FE8F0EFFFFFcall008BE704
008BF71483C410addesp,10
008BF7178B450Cmoveax,dwordptrss:[ebp+C]
008BF71A83C024addeax,24
008BF71D8945C0movdwordptrss:[ebp-40],eax
008BF7208B45C0moveax,dwordptrss:[ebp-40]
008BF7238B4DF4movecx,dwordptrss:[ebp-C]
008BF7268908movdwordptrds:[eax],ecx
008BF7288B45C0moveax,dwordptrss:[ebp-40]
008BF72B83C004addeax,4
008BF72E50pusheax
008BF72FE81F61FDFFcall00895853
008BF73459popecx
008BF735F0:FF0D742F8D00lockdecdwordptrds:[8D2F74]
008BF73C780Cjsshort008BF74A
008BF73EFF3548ED8D00pushdwordptrds:[8DED48]
008BF744FF154C208C00calldwordptrds:[8C204C]
008BF74A8B650Cmovesp,dwordptrss:[ebp+C]
008BF74D61popad
008BF74E9Dpopfd
008BF74FC3retn
//Patch③:jmp1003E064解密完毕后跳回去控制处理,[ESP]是解密后的函数系统地址


—————————————————————————————————
五、类SDK输入表函数调用地址


上面修复完毕后不要关闭OllyDBG,还有一些类似SDK的函数调用需要修复
此SDK同样使用上面的解码CALL,但是Patch②不需要修改,Patch①依旧。
修改上面Patch③的008BF74F处为jmp1003E0DD,控制流程。

1002DE3F33C0xoreax,eax
1002DE416A00push0
1002DE4339442408cmpdwordptrss:[esp+8],eax
1002DE476800100000push1000
1002DE4C0F94C0seteal
1002DE4F50pusheax
1002DE50E9D3990200jmpAdobeLM.10057828
//类似SDK的函数调用需要修复
1005782853pushebx
10057829E898FCFFFFcallAdobeLM.100574C6

100574C6870424xchgdwordptrss:[esp],eax
100574C99Cpushfd
100574CA05DF100000addeax,10DF
100574CF8B18movebx,dwordptrds:[eax]
100574D16BDB2Eimulebx,ebx,2E
100574D4035804addebx,dwordptrds:[eax+4]
100574D79Dpopfd
100574D858popeax
100574D9871C24xchgdwordptrss:[esp],ebx
100574DCC3retn
//入壳处理

00AFCBC96856DE0210push1002DE56
00AFCBCE680A13EABFpushBFEA130A
00AFCBD39Cpushfd
00AFCBD460pushad
00AFCBD554pushesp
00AFCBD66809CCAF00push0AFCC09
00AFCBDBE8B527DCFFcall~df394b.008BF395
00AFCBE083C408addesp,8
00AFCBE36A00push0
00AFCBE558popeax
00AFCBE661popad
00AFCBE79Dpopfd
00AFCBE8C3retn

00AE0000区段里面包含了需要处理的函数调用地址,可以依此为突破点
写Patch代码,在1003E0A8处新建EIP

1003E0A860pushad
1003E0A9BE0000AE00movesi,00AE0000
1003E0AEBF00600410movedi,10046000
1003E0B346incesi
1003E0B481FE0050B100cmpesi,00B15000
//00B15000是00AE0000区段的结束地址
1003E0BA7D53jgeshort1003E10F
//扫描完毕后跳转
1003E0BC803E68cmpbyteptrds:[esi],68
1003E0BF75F2jnzshort1003E0B3
1003E0C166:817E041068cmpwordptrds:[esi+4],6810
1003E0C775EAjnzshort1003E0B3
1003E0C9817E0A9C605468cmpdwordptrds:[esi+A],6854609C
1003E0D075E1jnzshort1003E0B3
1003E0D2817E0100000010cmpdwordptrds:[esi+1],10000000
1003E0D97430jeshort1003E10B
//搜索符合条件的地址
1003E0DBFFE6jmpesi
//跳过去执行

1003E0DD3E:8B0424moveax,dwordptrds:[esp]
//SafeDisc解密后强制跳到这里★
//[ESP]是解密后的函数系统地址
1003E0E18B5E01movebx,dwordptrds:[esi+1]
1003E0E466:C743FAFF15movwordptrds:[ebx-6],15FF
1003E0EA33C9xorecx,ecx
1003E0EC3B0439cmpeax,dwordptrds:[ecx+edi]
//自10046000搜寻相同的函数地址
1003E0EF740Fjeshort1003E100
1003E0F183C104addecx,4
1003E0F481F9D0020000cmpecx,2D0
1003E0FA72F0jbshort1003E0EC
1003E0FCEBFEjmpshort1003E0FC
//留一个出错的处理点,不过没用到
1003E0FE90nop
1003E0FF90nop
1003E1008D0C39leaecx,dwordptrds:[ecx+edi]
1003E10381E900000100subecx,10000
//10046000-10036000=100000找到的存放函数地址的地址
1003E109894BFCmovdwordptrds:[ebx-4],ecx
/修复函数调用地址
1003E10CEBA5jmpshort1003E0B3
//循环
1003E10E90nop
1003E10F61popad
//修复完成
1003E110EBFEjmpshort1003E110

二进制代码复制如下:
60BE0000AE00BF006004104681FE0050B1007D53803E6875F266817E04106875
EA817E0A9C60546875E1817E01000000107430FFE63E8B04248B5E0166C743FA
FF1533C93B0439740F83C10481F9D002000072F0EBFE90908D0C3981E9000001
00894BFCEBA59061EBFE

注意:由于目标程序是DLL所以需要考虑重定位表,而这部分地址并没有包含在加壳后DLL的重定位表中,因此可以在上面的修复代码中加点代码保存每次修复时的地址,便于最后修复重定位表。


—————————————————————————————————
六、类CC的SDK


1、DLL虽然无法使用CC,但是却有SDK来控制流程

10002463E8611D0000call100041C9
//有很多call100041C9

100041C951pushecx
100041CA50pusheax
100041CBE813F3FFFFcall100034E3

100034E3B87BEFFFFFmoveax,-1085
100034E859popecx
100034E98D0408leaeax,dwordptrds:[eax+ecx]
100034EC8B00moveax,dwordptrds:[eax]
100034EEFFE0jmpeax;~df394b.0088127D
//进入~df394b.tmp

————————————————————————
2、需要说明的是,文件中有不少假的SDK,SafeDisc真狡猾。

可以手动察看,搜索所有的call100041C9命令,把假的SDK去掉再扫描修复。
如何识别,看你的火眼金睛了,呵呵,举例来说:
1000109BE829310000callAdobeLM.100041C9
滚动一下鼠标,会发现这里有了变化:
1000109A6AE8push-18
1000109C2931subdwordptrds:[ecx],esi
1000109E0000addbyteptrds:[eax],al
100010A08B4C2404movecx,dwordptrss:[esp+4]
100010A485C9testecx,ecx
100010A67406jeshortAdobeLM.100010AE

还有一种有点难判断:
1002AF0AC3retn
1002AF0BE8B992FDFFcallAdobeLM.100041C9
1002AF1055pushebp
1002AF118BECmovebp,esp
看到这个CALL在retn附近,Ctrl+A后没有其他地方调用这里,可以判定是烟雾弹了。

把以下地址暂时修改为call100041CC
1000109Bcall100041C9
10001FABcall100041C9
10002F0Bcall100041C9
1000380Bcall100041C9
10003B8Bcall100041C9
1000476Bcall100041C9
10004FBBcall100041C9
1000572Bcall100041C9
100066ABcall100041C9
1000EB5Bcall100041C9
1000FE3Bcall100041C9
1000FEEBcall100041C9
10011B9Bcall100041C9
10011DDBcall100041C9
1001379Bcall100041C9
10013A5Bcall100041C9
10013BDBcall100041C9
10013C3Bcall100041C9
10013D0Bcall100041C9
1001409Bcall100041C9
1001439Bcall100041C9
1001441Bcall100041C9
1002908Bcall100041C9
1002913Bcall100041C9
1002AF0Bcall100041C9
1002D53Bcall100041C9
等扫描完毕后再全部恢复回来,免得误修复。

————————————————————————
3、写Patch代码,在1003E112处新建EIP

1003E11260pushad
1003E113BE00100010movesi,10001000
1003E11846incesi
1003E11981FE905A0310cmpesi,10035A90
1003E11F7718jashort1003E139
//扫描完毕后跳转
1003E121803EE8cmpbyteptrds:[esi],0E8
1003E12475F2jnzshort1003E118
1003E1268B4601moveax,dwordptrds:[esi+1]
1003E12903C6addeax,esi
1003E12B83C005addeax,5
1003E12E3DC9410010cmpeax,100041C9
1003E13375E3jnzshort1003E118
//循环扫描所有call100041C9的地方
1003E135FFD6callesi
//调用
1003E137EBDFjmpshort1003E118
//循环
1003E13961popad
//解码完毕后中断在这里
1003E13AEBFEjmpshort1003E13A

二进制代码复制如下:
60BE001000104681FE905A03107718803EE875F28B460103C683C0053DC94100
1075E3FFD6EBDF61EBFE

————————————————————————
4、SafeDisc解密CALL里面的修改,和上面的解码地方不同了

0088127D58popeax
0088127E59popecx
0088127F6800004000push400000
008812849Cpushfd
0088128560pushad
0088128654pushesp
00881287E8D2FFFFFFcall0088125E
0088128C5Cpopesp
0088128D61popad
0088128E9Dpopfd
0088128FC3retn
//Patch④修改为:
0088128FBCC0E10600movesp,6E1C0
//控制流程,返回Patch代码的地方
00881294C3retn
注意,这里的movesp,XXXXXXXX具体是何要看此时的堆栈。
如这次中断在0088128F处堆栈为:
0006E1BC1000F0FEAdobeLM.1000F0FE
0006E1C01003E137返回到AdobeLM.1003E137

0088119255pushebp
008811938BECmovebp,esp
0088119581ECD0020000subesp,2D0
0088119B53pushebx
0088119C8BD9movebx,ecx
0088119E56pushesi
0088119F57pushedi
008811A08D4320leaeax,dwordptrds:[ebx+20]
008811A350pusheax
008811A48945FCmovdwordptrss:[ebp-4],eax
008811A7FF1570208C00calldwordptrds:[8C2070]
008811AD8D8530FDFFFFleaeax,dwordptrss:[ebp-2D0]
008811B38BCBmovecx,ebx
008811B550pusheax
008811B6FF7508pushdwordptrss:[ebp+8]
008811B9E8E5FEFFFFcall008810A3
008811BE8B85E8FDFFFFmoveax,dwordptrss:[ebp-218]
008811C4B960ED8D00movecx,8DED60
008811C98BF8movedi,eax
008811CB2B4304subeax,dwordptrds:[ebx+4]
008811CE50pusheax
008811CFE8E6FE0300call008C10BA
008811D450pusheax
008811D5E8F1010000call008813CB
008811DA8BC8movecx,eax
008811DCE8FC010000call008813DD
//判断是否是SDK
008811E18BF0movesi,eax
008811E385F6testesi,esi
008811E5743Fjeshort00881226
008811E766:837B0801cmpwordptrds:[ebx+8],1
008811EC753Djnzshort0088122B
008811EE8D8530FDFFFFleaeax,dwordptrss:[ebp-2D0]
008811F48BCEmovecx,esi
008811F650pusheax
008811F7E8E7550100call008967E3
008811FC8BCBmovecx,ebx
008811FEE88AFEFFFFcall0088108D
0088120383F804cmpeax,4
//记数
008812067214jbshort0088121C
//Patch⑤:NOP强制解码
008812088BCEmovecx,esi
0088120AE8BA540100call008966C9
0088120F83F804cmpeax,4
//Patch⑥:cmpeax,6解码字节数
008812127208jbshort0088121C
//Patch⑦:jashort0088121C超过6位则不解码
0088121457pushedi
008812158BCEmovecx,esi
00881217E8FE540100call0089671A
//解码
0088121C56pushesi
0088121D8BCBmovecx,ebx
0088121FE833FEFFFFcall00881057
00881224EB05jmpshort0088122B

0088140E39442414cmpdwordptrss:[esp+14],eax
00881412740Bjeshort0088141F
0088141445incebp
0088141581FD80000000cmpebp,80
0088141B72CFjbshort008813EC
0088141DEB0Cjmpshort0088142B
0088141F8D1C76leaebx,dwordptrds:[esi+esi*2]
00881422C1E304shlebx,4
0088142581C3E0EE8D00addebx,8DEEE0
0088142B5Fpopedi
0088142C5Epopesi
0088142D8BC3moveax,ebx
0088142F5Dpopebp
008814305Bpopebx
00881431C20400retn4
00881434A1DCED8D00moveax,dwordptrds:[8DEDDC]
00881439C3retn
//Patch⑧修改为:
0088141DEB15jmpshort00881434
0088141F8D1C76leaebx,dwordptrds:[esi+esi*2]
00881422C1E304shlebx,4
0088142581C3E0EE8D00addebx,8DEEE0
0088142B5Fpopedi
0088142C5Epopesi
0088142D8BC3moveax,ebx
0088142F5Dpopebp
008814305Bpopebx
00881431C20400retn4
0088143433DBxorebx,ebx
//若不是SDK,则ebx清0使其跳转
00881436EBF3jmpshort0088142B

————————————————————————

好了,当我们中断在1003E139处时所有SDK都修复完毕了。
现在把代码段10001000-10036000数据复制下来,用WinHex复制数据写入到dump_.dll相应处


—————————————————————————————————
七、PE优化+修复重定位表


把dump_.dll复制一份,另存为UnPacKed.dll
用LordPE把UnPacKed.dll后面2个壳区段删除,用WinHex删除0X00057000至末尾的数据
可以用ImportREC把输入表放在RVA=0003D380处,当然,也可以放在其他可用的空白处
修正各区段的RSize和VSize为实际值

由于删除了壳区段,重定位表部分需要调整
把下面壳区段的重定位表数据清0
000560A000A00500
000560B02000000063306B30743081309530C930
000560C0E130E630F33000310E31000000C00500
000560D0100000008A339233733F000000000000
000560E000000000603B683B703B783B803B883B
000560F0903B983BA03BA83BB03BB83BC03BC83B
00056100D03B6C3C703C00000000000000000000

最重要的一点是,第五步的“类SDK输入表函数调用地址”要加到重定位表里面,如:
1002DE50FF1500610310calldwordptrds:[10036100];kernel32.HeapCreate
这部分操作比较麻烦,可以手动添加后修正相应Size。
也可以在完成上面六步修复后复制AdobeLM.dll,在当前OllyDBG里面直接写代码Load复制的AdobeLM.dll,同样的方法修复SDK后再用Relox修复最终的重定位表。


TOP

发新话题