判断可执行文件
//—– (1008FCB0) ——————————————————–
bool __cdecl _ValidateImageBase(int a1)
{
bool result; // al@2
int v2; // ecx@3
if ( (_WORD )a1 == 23117 ) // 5A4D 应倒过来看 4d5a,即 MZ
{
v2 = a1 + (_DWORD )(a1 + 60); // 00 F0
result = 0;
if ( (_DWORD )v2 == 17744 ) // 4550 ,同上, PE
result = (_WORD )(v2 + 24) == 267; // 010B,为 EXE 文件;020B 为 DLL 文件。
}
else
{
result = 0;
}
return result;
}
//—– (1008FBE0) ——————————————————–
int __cdecl _IsNonwritableInCurrentImage(int a1)
{
int v1; // eax@1
int v2; // eax@2
int result; // eax@3
LOBYTE(v1) = _ValidateImageBase(0x10000000);
if ( v1 && (v2 = _FindPESection(0x10000000, a1 - 0x10000000)) != 0 )
result = ~(unsigned __int8)((_DWORD )(v2 + 36) >> 31) & 1;
else
result = 0;
return result;
}
//—– (1008FB90) ——————————————————–
int __cdecl _FindPESection(int a1, unsigned int a2)
{
unsigned int v2; // edx@1
int v3; // ecx@1
int result; // eax@1
unsigned int v5; // esi@2
v2 = 0;
v3 = a1 + (_DWORD )(a1 + 60); // F0 00
result = v3 + (_WORD )(v3 + 20) + 24;
if ( (_WORD )(v3 + 6) ) // BA 0E
{
while ( 1 )
{
v5 = (_DWORD )(result + 12);
if ( a2 >= v5 && a2 < v5 + (_DWORD )(result + 8) )
break;
++v2;
result += 40;
if ( v2 >= (_WORD )(v3 + 6) )
goto LABEL_5;
}
}
else
{
LABEL_5:
result = 0;
}
return result;
}
1、先判断最前面的两个字节,应该为 MZ,即 4D A5;
2、再后偏移 60 个字节,这两个字节,表示文件头的长度; 这里为 00 F0
3、定位到上面找到的量,值就为 PE,即 50 45
4、再从这里从后偏移 24 个字节,就是结束标志。
EXE 文件:0B 01
DLL 文件:0B 02
5、从 _IsNonwritableInCurrentImage 函数中的调用情况来看, _ValidateImageBase(0x10000000),好像是直接判断 0x10000000 处的内容。