-
-
[分享]ExtOverlay插件判定是否存在Overlay方法
-
发表于: 2007-8-9 23:39 6481
-
前几天,写了个判定Overlay的东东,都在瞎闭门造车,今天分析了下PEid的ExtOverlay插件的判定算法,这玩意其实很简单。
分析了下别人的东东,对自己写的东东也更自信了几分:)
bp CreateFileA,F9,Alt + F9返回后,到0x0121391F处
0121391A E8 6DFEFFFF call 0121378C ; jmp 到 kernel32.CreateFileA
0121391F A3 7C562101 mov dword ptr [121567C], eax //保存文件句柄
01213924 833D 7C562101 F>cmp dword ptr [121567C], -1
0121392B 0F84 30020000 je 01213B61
01213931 6A 00 push 0
01213933 A1 7C562101 mov eax, dword ptr [121567C]
01213938 50 push eax
01213939 E8 5EFEFFFF call 0121379C ; jmp 到 kernel32.GetFileSize
0121393E A3 84562101 mov dword ptr [1215684], eax //保存文件大小
01213943 A1 84562101 mov eax, dword ptr [1215684]
01213948 E8 FBEAFFFF call 01212448
0121394D A3 80562101 mov dword ptr [1215680], eax //保存文件缓冲指针
01213952 33C0 xor eax, eax
01213954 55 push ebp
01213955 68 5A3B2101 push 01213B5A
0121395A 64:FF30 push dword ptr fs:[eax]
0121395D 64:8920 mov dword ptr fs:[eax], esp
01213960 6A 00 push 0
01213962 8D45 F8 lea eax, dword ptr [ebp-8]
01213965 50 push eax
01213966 A1 84562101 mov eax, dword ptr [1215684]
0121396B 50 push eax
0121396C A1 80562101 mov eax, dword ptr [1215680]
01213971 50 push eax
01213972 A1 7C562101 mov eax, dword ptr [121567C]
01213977 50 push eax
01213978 E8 27FEFFFF call 012137A4 ; jmp 到 kernel32.ReadFile
0121397D E8 CEFEFFFF call 01213850
01213850 53 push ebx
01213851 56 push esi
01213852 57 push edi
01213853 33C0 xor eax, eax
01213855 A3 70562101 mov dword ptr [1215670], eax //[1215670]用来保存Overlay起始地址
0121385A 33C0 xor eax, eax
0121385C A3 74562101 mov dword ptr [1215674], eax //[1215674]用来保存Overlay长度
01213861 33F6 xor esi, esi
01213863 A1 80562101 mov eax, dword ptr [1215680] //ReadFile读出内容放在
01213868 8B40 3C mov eax, dword ptr [eax+3C]
0121386B 0305 80562101 add eax, dword ptr [1215680]
01213871 8D58 18 lea ebx, dword ptr [eax+18]
01213874 0FB750 14 movzx edx, word ptr [eax+14] //SizeOfOptionHeader
01213878 03DA add ebx, edx //ebx指向节表位置
0121387A 0FB778 06 movzx edi, word ptr [eax+6] //NumberOfSections
0121387E 4F dec edi
0121387F 85FF test edi, edi
01213881 7C 1F jl short 012138A2
01213883 47 inc edi
01213884 BA 00020000 mov edx, 200
01213889 8B43 10 mov eax, dword ptr [ebx+10] //SizeOfRawData
0121388C E8 ABFFFFFF call 0121383C //这个函数作用:SizeOfRawData按0x200向上取整
01213891 8B53 14 mov edx, dword ptr [ebx+14] //PointerToRawData
01213894 03D0 add edx, eax
01213896 3BF2 cmp esi, edx
01213898 73 02 jnb short 0121389C
0121389A 8BF2 mov esi, edx //上面三行代码:把SizeOfRawData + PointerToRawData最大值放esi,其中SizeOfRawData为0x200向上取整值,PointerToRawData未按0x200向下作对齐处理
0121389C 83C3 28 add ebx, 28 //指向下个节
0121389F 4F dec edi //节计数减1
012138A0 ^ 75 E2 jnz short 01213884
012138A2 85F6 test esi, esi
012138A4 76 20 jbe short 012138C6
012138A6 3B35 84562101 cmp esi, dword ptr [1215684] //esi与文件大小比较(esi为PE文件有效大小,不含Overlay大小)
012138AC 73 18 jnb short 012138C6
012138AE A1 80562101 mov eax, dword ptr [1215680] //esi小于文件大小情况(有Overlay)
012138B3 03C6 add eax, esi
012138B5 A3 70562101 mov dword ptr [1215670], eax //保存Overlay起始地址到[1215670]
012138BA A1 84562101 mov eax, dword ptr [1215684]
012138BF 2BC6 sub eax, esi
012138C1 A3 74562101 mov dword ptr [1215674], eax //保存Overlay长度到[1215674]
012138C6 5F pop edi
012138C7 5E pop esi
012138C8 5B pop ebx
012138C9 C3 retn //返回到下面语句
01213982 833D 70562101 0>cmp dword ptr [1215670], 0
01213989 0F84 7E010000 je 01213B0D //没有发现Overlay则跳
0121398F 8D45 FC lea eax, dword ptr [ebp-4] //底下代码大致是再作善后处理了,保存Overlay到文件...
01213992 8B15 B0402101 mov edx, dword ptr [12140B0]
01213998 E8 B7F6FFFF call 01213054
0121399D EB 13 jmp short 012139B2
0121399F 8B45 FC mov eax, dword ptr [ebp-4]
012139A2 E8 7DF7FFFF call 01213124
012139A7 8BD0 mov edx, eax
012139A9 4A dec edx
012139AA 8D45 FC lea eax, dword ptr [ebp-4]
012139AD E8 DEF8FFFF call 01213290
012139B2 8B45 FC mov eax, dword ptr [ebp-4]
012139B5 E8 6AF7FFFF call 01213124
012139BA 8B55 FC mov edx, dword ptr [ebp-4]
012139BD 807C02 FF 2E cmp byte ptr [edx+eax-1], 2E
012139C2 ^ 75 DB jnz short 0121399F
012139C4 8D45 FC lea eax, dword ptr [ebp-4]
012139C7 BA 903B2101 mov edx, 01213B90 ; ovr
012139CC E8 5BF7FFFF call 0121312C
012139D1 8B45 FC mov eax, dword ptr [ebp-4]
012139D4 E8 23F8FFFF call 012131FC
012139D9 8BD8 mov ebx, eax
下面给出ExtOverlay的Overlay判定C代码(不容错处理):
int has_overlay(char * pBuf, int nBufLen)
{
IMAGE_DOS_HEADER * pIDH = (IMAGE_DOS_HEADER *)pBuf;
IMAGE_NT_HEADERS * pINH = (IMAGE_NT_HEADERS *)(pBuf + pIDH->e_lfanew);
int nSectionNum = pINH->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER * pISH = (IMAGE_SECTION_HEADER *)((char *)pINH + 0x18 + pINH->FileHeader.SizeOfOptionalHeader);
int nPESize = 0;
for(int nIndex = 0; nIndex < nSectionNum; nIndex++, pISH++)
{
int nTemp = ((pISH->SizeOfRawData + 0x200 - 1) / 0x200) * 0x200;
nTemp += pISH->PointerToRawData;
if(nTemp > nPESize)
{
nPESize = nTemp;
}
}
if(nBufLen > nPESize)
{
//pBuf + nPESize是Overlay开始地址
//nBufLen - nPESize是Overlay长度
return 1; //有Overlay
}
else
{
return 0;
}
}