标题:FSG2.0的分析
作者:E病毒
FSG2.0压缩都的程序都只有两个区段。。。。。。。区段1没有什么数据,区段2有待还原的数据.
刚开始各寄存器内容如下:
EAX 00000000
ECX 0007FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFD3000
ESP 0007FFC4
EBP 0007FFF0
ESI FFFFFFFF
EDI 7C930738 ntdll.7C930738
01000154 > 8725 6CF40101 xchg dword ptr [101F46C], esp
//作用是保存esp寄存器到地址101F46C,现在esp= [101F46C]=0101F470
0100015A 61 popad
//各寄存器出栈,如果想知道出栈之前各寄存器的值,在第1句的时候可以查看右边寄存器^_^
EAX 0007FFC4
ECX 00007D00 //不同程序这里都相同
EDX 00000080 //不同程序这里都相同
EBX 0101F470 notepad.0101F470
ESP 0101F470 notepad.0101F470
EBP 01007604 notepad.01007604
ESI 0101ADF4 notepad.0101ADF4 //ESI应该指向区块2,若ESI-VOFFSET(区块2)<>0说明有FSG不能压缩的数据存在
EDI 01001000 notepad.01001000 //现在edi指向区块1
0100015B 94 xchg eax, esp
//eax<-->esp
0100015C 55 push ebp
//ebp寄存器入栈
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@这里都是将区块2中的数据还原到区块1当中@@@@@@@@@@@@@@@@@@@@@@
0100015D A4 movs byte ptr es:[edi], byte ptr [esi>
//堆栈提示:
//ds:[esi]=[0101ADF4]=A3 ('?)
//es:[edi]=[01001000]=00
//地址将0101ADF4开始的数据传送到01001000地址处
0100015E B6 80 mov dh, 80
//dh=80h
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
01000160 FF13 call dword ptr [ebx]
{
010001E8 02D2 add dl, dl
//dl=dl+dl,刚开始的时候dl=80
010001EA 75 05 jnz short 010001F1
//dl结果不是0的话就直接返回
010001EC 8A16 mov dl, byte ptr [esi]
//这里esi=[0101ADF5],原来是movs指令作用的结果,这里要看下DF标志寄存器,[ESI]的内容到dl。
010001EE 46 inc esi
//inc指向下一位
010001EF 12D2 adc dl, dl
//带进位加法
010001F1 C3 retn
}
01000162 ^\73 F9 jnb short 0100015D ↑
//cf=0的时候跳。。也就是没有产生借位的时候跳
01000164 33C9 xor ecx, ecx
//ecx寄存器被清零了
01000166 FF13 call dword ptr [ebx]
01000168 73 16 jnb short 01000180
0100016A 33C0 xor eax, eax
0100016C FF13 call dword ptr [ebx]
0100016E 73 1F jnb short 0100018F
01000170 B6 80 mov dh, 80
//dh=80h
01000172 41 inc ecx
//ECX=ECX+1
01000173 B0 10 mov al, 10
//al=10
01000175 FF13 call dword ptr [ebx]
01000177 12C0 adc al, al
01000179 ^ 73 FA jnb short 01000175 ↑
0100017B 75 3A jnz short 010001B7 ↓
0100017D AA stos byte ptr es:[edi]
//堆栈提示:
al=00
es:[edi]=[01001002]=00
将al保存到地址01001002
01000180 FF53 08 call dword ptr [ebx+8]
{
010001DE 41 inc ecx
010001DF FF13 call dword ptr [ebx]
010001E1 13C9 adc ecx, ecx
010001E3 FF13 call dword ptr [ebx]
010001E5 ^ 72 F8 jb short 010001DF
010001E7 C3 retn
}
01000183 02F6 add dh, dh
01000185 83D9 01 sbb ecx, 1
01000188 75 0E jnz short 01000198
0100018A FF53 04 call dword ptr [ebx+4]
{
010001DC 33C9 xor ecx, ecx
010001DE 41 inc ecx
010001DF FF13 call dword ptr [ebx]
010001E1 13C9 adc ecx, ecx
010001E3 FF13 call dword ptr [ebx]
010001E5 ^ 72 F8 jb short 010001DF
010001E7 C3 retn
}
0100018D EB 24 jmp short 010001B3
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
0100018F AC lods byte ptr [esi]
01000190 D1E8 shr eax, 1
01000192 74 2D je short 010001C1
01000194 13C9 adc ecx, ecx
01000196 EB 18 jmp short 010001B0
01000198 91 xchg eax, ecx
01000199 48 dec eax
0100019A C1E0 08 shl eax, 8
0100019D AC lods byte ptr [esi]
0100019E FF53 04 call dword ptr [ebx+4]
010001A1 3B43 F8 cmp eax, dword ptr [ebx-8]
010001A4 73 0A jnb short 010001B0
010001A6 80FC 05 cmp ah, 5
010001A9 73 06 jnb short 010001B1
010001AB 83F8 7F cmp eax, 7F
010001AE 77 02 ja short 010001B2
010001B0 41 inc ecx
010001B1 41 inc ecx
010001B2 95 xchg eax, ebp
010001B3 8BC5 mov eax, ebp
010001B5 B6 00 mov dh, 0
010001B7 56 push esi
010001B8 8BF7 mov esi, edi
010001BA 2BF0 sub esi, eax
010001BC F3:A4 rep movs byte ptr es:[edi], byte ptr [esi]
010001BE 5E pop esi
010001BF ^ EB 9F jmp short 01000160
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@这里都是将区块2中的数据还原到区块1当中@@@@@@@@@@@@@@@@@@@@@@
还原的过程就不具体分析了,感觉跟分析算法一样麻烦,知道是还原数据就可以了吧!
========================下面的代码开始处理IAT了================================
010001C1 5E pop esi
010001C2 AD lods dword ptr [esi]
010001C3 97 xchg eax, edi
010001C4 AD lods dword ptr [esi]
010001C5 50 push eax //指向dll
004001C6 FF53 10 call dword ptr [ebx+10] ; kernel32.LoadLibraryA
010001C9 95 xchg eax, ebp
010001CA 8B07 mov eax, dword ptr [edi]
010001CC 40 inc eax //EAX指向函数名
010001CD ^ 78 F3 js short 010001C2
010001CF 75 03 jnz short 010001D4
010001D1 FF63 0C jmp dword ptr [ebx+C] //处理完毕就跳到OEP了
010001D4 50 push eax
010001D5 55 push ebp
004001D6 FF53 14 call dword ptr [ebx+14] ; kernel32.GetProcAddress
010001D9 AB stos dword ptr es:[edi] //把获取的函数保存到es:[edi]当中去。
010001DA ^ EB EE jmp short 010001CA
================================================================================
对比脱壳后的文件发现。。IAT保存在新生成的.idata区块中,但不是少写了一个dll就是少写了函数名字。。为什么???
脱壳后的文件RVA=File Offset。
,今天就简单的分析到这里先。。。感觉还有很多东西没有分析出来!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)