定位提取eXPressor1.71加壳软件IAT FF15处理的特征码
先找来eXPressor.v1.4.5我想以前作者写的程序可能间单一点吧。
很快来到oep看其特征应该是vc 6.0写的吧
代码:
0042C9FE 55 push ebp ; kernel32.7C817077
0042C9FF 8BEC mov ebp,esp
0042CA01 6A FF push -0x1
0042CA03 68 68594500 push eXPresso.00455968
0042CA08 68 F0164300 push eXPresso.004316F0
0042CA0D 64:A1 00000000 mov eax,dword ptr fs:[0]
0042CA13 50 push eax
0042CA14 64:8925 0000000>mov dword ptr fs:[0],esp
0042CA1B 83EC 58 sub esp,0x58
0042CA1E 53 push ebx
0042CA1F 56 push esi
0042CA20 57 push edi
0042CA21 8965 E8 mov dword ptr ss:[ebp-0x18],esp
0042CA24 FF15 5C134500 call dword ptr ds:[0x45135C] ; kernel32.GetVersion
于是从中取了这个GetStartupInfoA函数来找eXPressor 1.71的oep,在这个函数下F2断点,F9运行断下了
Ctrl+F9一下在单步一下来到了
代码:
0049CB37 FF15 18534C00 call dword ptr ds:[0x4C5318] ; kernel32.GetStartupInfoA
0049CB3D C745 FC FEFFFFF>mov dword ptr ss:[ebp-0x4],-0x2
0049CB44 BF 94000000 mov edi,0x94
向上看看可以发现这段代码有点vc 7.0-8.0的特征应该是eXPressor 1.71的oep
代码:
0049CB23 6A 60 push 0x60
0049CB25 68 68264F00 push eXPresso.004F2668
0049CB2A E8 95120000 call eXPresso.0049DDC4
0049CB2F 8365 FC 00 and dword ptr ss:[ebp-0x4],0x0
0049CB33 8D45 90 lea eax,dword ptr ss:[ebp-0x70]
0049CB36 50 push eax
0049CB37 FF15 18534C00 call dword ptr ds:[0x4C5318] ; kernel32.GetStartupInfoA
0049CB3D C745 FC FEFFFFF>mov dword ptr ss:[ebp-0x4],-0x2
0049CB44 BF 94000000 mov edi,0x94
0049CB49 57 push edi
0049CB4A 6A 00 push 0x0
0049CB4C 8B1D EC514C00 mov ebx,dword ptr ds:[0x4C51EC]
0049CB52 FFD3 call ebx
0049CB54 50 push eax
0049CB55 FF15 B0514C00 call dword ptr ds:[0x4C51B0] ; ntdll.RtlAllocateHeap
0049CB37 FF15 18534C00 call dword ptr ds:[0x4C5318] ; kernel32.GetStartupInfoA
在这个位置我们数据地址跟随一下看IAT的处理情况并找到iAT起始及结束地址
004C4FFC 00000000
004C5000 77DC9BBF ADVAPI32.RegEnumValueA
这是起始位置
004C5748 74CA096A oledlg.OleUIBusyA
004C574C 00000000
004C5750 00000000
这应该是结束地址了我们在去看看对FF 15函数调用处理
代码:
0040116B FF15 A8534C00 call dword ptr ds:[0x4C53A8] ; kernel32.SetHandleCount
00401171 8BF0 mov esi,eax
00401173 85F6 test esi,esi
00401175 74 2D je XeXPresso.004011A4
00401177 57 push edi
00401178 53 push ebx
00401179 E8 94EE7400 call 00B50012
看到call 00B50012了吗把FF 15处理成这样了
我要基本资料找的差不多了,那我们就要找处理IAT 和 FF 15 的特征吗了.
先找IAT 的的处理,我想大家都知道加壳软件对某些函数地址加密处理后替换原始的
IAT.因此只要找到填充加密数据的代码,就OK了
好了动手吧!!!!!!!!!!!!!!!!!!
004C5000 77DC9BBF ADVAPI32.RegEnumValueA
004C5004 77DA7852 ADVAPI32.RegOpenKeyExA
004C5008 00B30C00
重载一下我在004C5008 下硬件写入断点,运行一下断下来了.
代码:
00C117B2 /EB 01 jmp X00C117B5
00C117B4 |8841 42 mov byte ptr ds:[ecx+0x42],al
00C117B7 837D 10 00 cmp dword ptr ss:[ebp+0x10],0x0
00C117BB ^ 75 EE jnz X00C117AB
00C117BD 8BC6 mov eax,esi
00C117BF 5E pop esi
00C117C0 5D pop ebp
00C117C1 C3 retn
取消硬件写入断点在
00C117C1 C3 retn
下F2断点运行取消断点
再一次在004C5008 下硬件写入断点会断在
代码:
00C617B2 /EB 01 jmp X00C617B5
00C617B4 |8841 42 mov byte ptr ds:[ecx+0x42],al
00C617B7 837D 10 00 cmp dword ptr ss:[ebp+0x10],0x0
00C617BB ^ 75 EE jnz X00C617AB
00C617BD 8BC6 mov eax,esi
00C617BF 5E pop esi
00C617C0 5D pop ebp
00C617C1 C3 retn
F8单步一直来到,
代码:
00C652B0 59 pop ecx ; ADVAPI32.RegDeleteValueA
00C652B1 59 pop ecx
00C652B2 85C0 test eax,eax
00C652B4 75 17 jnz X00C652CD
00C652B6 6A 04 push 0x4
00C652B8 8D85 4CFDFFFF lea eax,dword ptr ss:[ebp-0x2B4]
00C652BE 50 push eax
00C652BF FFB5 CCFDFFFF push dword ptr ss:[ebp-0x234]
00C652C5 E8 CFC4FFFF call 00C61799
认真分析这代码可以知道第一个POP ECX 弹进去API地址 ,第二个POP ECX就是加密后的数据,00C652B4 75 17 jnz X00C652CD
跳转实现就把加密数写入IAT了。
59 59 85 C0 75 17 6A 04 8D 85 4C FD FF FF 50 FF B5 CC FD FF FF提取出特征码,C3 E8 ?? ?? ?? ?? 00 00把IAT处理完的返回特征码
也提取一下吧!!!!
那我可以写个脚本来处IAT,好多大牛是PATH代码实现的.
1.在IAT处理代码段出下个断点,用来判断IAT是否处理完成.如果处理OK就跳向FF 15的处理!!
2.我特征码定位的是第一个POP ECX,把ECX的值存到mid中
3.第二个POP ECX执行后ECX的值是加密后数据,因此我们要把刚刚保存的数据写回去
4.要想跳转不实现就要把eax置0
这样就完成IAT的处理
代码:
var addr1
var addr
var addr2
var addr3
var addr4
var addr5
mov addr4,004C4FFC
var mid
bc
bphwcall
////////////////////////////////////////////////////////////
///
/////////////////////////////////////////////////////////////
bpwm 401000,1
esto
bpmc
GMEMI eip,MEMORYBASE
cmp $RESULT,0
je exit
mov addr1,$RESULT
find addr1,#595985C075176A048D854CFDFFFF50FFB5CCFDFFFF#
cmp $RESULT,0
je exit
mov addr,$RESULT
bphws addr,"x"
esto
find eip,#C3E8????????0000#
cmp $RESULT,0
je exit
mov addr2,$RESULT
bp addr2
//////这个loop是修复IAT
loop:
esto
cmp eip,addr2
je IATEND
sto
mov mid,ecx
sto
mov ecx,mid
mov eax,0
jmp loop
IATEND:
bc addr2
///处理FF 15 型函数调了
exit:
ret
接下来我们就要来找找FF 15 型函数调的关健地方并提取特征码吧,看看这段代码吧
代码:
0040116B FF15 A8534C00 call dword ptr ds:[0x4C53A8] ; kernel32.SetHandleCount
00401171 8BF0 mov esi,eax
00401173 85F6 test esi,esi
00401175 74 2D je XeXPresso.004011A4
00401177 57 push edi
00401178 53 push ebx
00401179 E8 94EE7400 call 00B50012
加壳程序把FF 15 函数调用写成了call 00B50012这种形式的.重载一下吧,在数把窗口Cetl+G来到00401179
00401179 00000000
0040117D 00000000
00401181 00000000
00401185 00000000
00401189 00000000
0040118D 00000000
00401191 00000000
00401195 00000000
00401199 00000000
0040119D 00000000
004011A1 00000000
在00401179地址下硬件写入吧!!!!F9运行,断下来了
代码:
00B017B2 /EB 01 jmp X00B017B5
00B017B4 |8841 42 mov byte ptr ds:[ecx+0x42],al
00B017B7 837D 10 00 cmp dword ptr ss:[ebp+0x10],0x0
00B017BB ^ 75 EE jnz X00B017AB
00B017BD 8BC6 mov eax,esi
00B017BF 5E pop esi
00B017C0 5D pop ebp
00B017C1 C3 retn
取消断点,并00B017C1下F2断点运行后消失断点并在00401179在下一个内存写入运行会断在
代码:
00B0323D C600 E8 mov byte ptr ds:[eax],0xE8
00B03240 8B45 D4 mov eax,dword ptr ss:[ebp-0x2C]
00B03243 40 inc eax
00B03244 8945 D0 mov dword ptr ss:[ebp-0x30],eax
00B03247 50 push eax
00B03248 E8 03000000 call 00B03250
00B0324D 01EB add ebx,ebp
00B0324F 0B8B 04240FB6 or ecx,dword ptr ds:[ebx+0xB60F2404]
00B03255 0001 add byte ptr ds:[ecx],al
00B03257 04 24 add al,0x24
00B03259 C3 retn
F7单步要不了几步就会来到
代码:
00C9325B 58 pop eax ; eXPresso.0040117A
00C9325C 8B45 D4 mov eax,dword ptr ss:[ebp-0x2C] ------->
00C9325F 83C0 05 add eax,0x5
00C93262 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10]
;EBP-10在存放的是加密地址
////////////////////////////////////////
EBP堆栈窗口跟随一下,会看到
EBP-18 > 7C80BD09 kernel32.SizeofResource
Ebp-18存放的的是API地址
$-1C > 00BF0000
$-18 > 7C80BD09 kernel32.SizeofResource
$-14 > 00000012
$-10 > 00BF0012
$-C > 00000000
$-8 > 00B10754
$-4 > 00000000
$ ==> > 0012FFC0
///////////////////////////////////////////
代码:
00C93265 2BC8 sub ecx,eax
00C93267 8B45 D0 mov eax,dword ptr ss:[ebp-0x30]
00C9326A 8908 mov dword ptr ds:[eax],ecx <------------------
00C9326C EB 01 jmp X00C9326F
经分析上面的那二段后 CALL [xxxxxxxx] 就变成了 CAll xxxxxxxx
00C9326C到就个地址后你再去00401179就会发现己变成了CAll xxxxxxxx后再也不对00401179进行写操作
了.因此我选择在
00C9326C EB 01 jmp X00C9326F
把FF 15 还原这应该是比理想的时机吧
那接着写脚本吧
代码:
IATEND:
bc addr2
///处理FF 15 型函数调了晕忘了提取特征码去00C9325B提取一下
//58 8B 45 D4 83 C0 05 8B 4D F0 2B C8 8B 45 D0 89 08
find addr1,#588B45D483C0058B4DF02BC88B45D08908#
cmp $RESULT,0
je exit
mov addr,$RESULT
bphws addr,"x"
//在OEP处也下个断点吧它的作用用判断FF15是否处理完成
bphws 0049CB23,"x"
loop1:
esto
cmp eip,0049CB23
je exit
sto
sub eax,1
mov addr3,eax
sto
sto
sto
sto
sto
sto
loop2:
add addr4,4
cmp [addr4],0
je loop2
cmp addr4,004C574C
je loop1
mov addr5,[ebp-18]
cmp [addr4],addr5
jnz loop2
mov [addr3],#FF15#
mov [addr3+2],addr4
mov addr4,004C4FFC
jmp loop1
exit:
ret
呵呵分析完成了脚本也OK了
上OD测试一下脚本吧
LordPEC脱壳
ImportREC修复一下吧
eXPressor1.71脚本:http://up.2cto.com/2012/1119/20121119122719629.rar
上一篇: Linux Bash之变量和数学运算讲解
下一篇: 买电脑坑两千 过半玩家不知道这四大骗局