۲۳-شهریور-۱۳۸۷, ۱۱:۰۲:۵۳
سلام
شاید واستون سوال شده باشه که آنتی ویروس ها (مثلا کسپراسکای) چطوری پکر رو شناسایی می کنه و زمانی که فایل رو اسکن می کنه میگه برنامه با این پکر پک شده
اینجا یه سورس به زبان دلفی واستون نوشتم که به این سوالاتتون جواب میده
در کد بالا اگه دقت کرده باشید خروجی که تابع از هر فایل به شما میده یک استرینگ هستش که نسبت به هر پکری ثابت هستش
این خروجی در واقع امضایی هست که کامپایلر یا پکر بعد از پک کردن فایل در File offset ثابت می مونه و با روش فوق قابل شناسایی هستش
آنتی ویروس ها یا حتی همون برنامه Peid خودمون هم از این روش استفاده می کنه و امضاهایی که بهد از پک یا کامپایل در فایل به جای میذارن توی یه دیتابیس به همرام اسم پکر جمع آوری میشه و بعد از اسکن کردن فایل با اون امضاها تطبیق داده میشه و بعد هم به راحتی میشه فهمید که از چه کامپایلر یا پکری واسه فایل مورد نظر استفاده شده
شاید واستون سوال شده باشه که آنتی ویروس ها (مثلا کسپراسکای) چطوری پکر رو شناسایی می کنه و زمانی که فایل رو اسکن می کنه میگه برنامه با این پکر پک شده
اینجا یه سورس به زبان دلفی واستون نوشتم که به این سوالاتتون جواب میده
کد:
program FindSignature;
{$APPTYPE CONSOLE}
{$HINTS OFF}
{$WARNINGS OFF}
uses
Windows;
var
Offset:dword;
function IntToHex(dwValue, dwDigits: DWord): String;
const
hex: array[0..$F] of char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
begin
if (dwDigits > 8) then
dwDigits := 8;
Result := Copy(
hex[(dwValue and $F0000000) shr 28]+
hex[(dwValue and $0F000000) shr 24]+
hex[(dwValue and $00F00000) shr 20]+
hex[(dwValue and $000F0000) shr 16]+
hex[(dwValue and $0000F000) shr 12]+
hex[(dwValue and $00000F00) shr 8]+
hex[(dwValue and $000000F0) shr 4]+
hex[(dwValue and $0000000F) shr 0],9-dwDigits,dwDigits);
end;
function FileSeek(Handle, Offset, Origin: Integer): Integer;
begin
{$IFDEF MSWINDOWS}
Result := SetFilePointer(THandle(Handle), Offset, nil, Origin);
{$ENDIF}
{$IFDEF LINUX}
Result := __lseek(Handle, Offset, Origin);
{$ENDIF}
end;
function FileRead(Handle: Integer; var Buffer; Count: LongWord): Integer;
begin
{$IFDEF MSWINDOWS}
if not ReadFile(THandle(Handle), Buffer, Count, LongWord(Result), nil) then
Result := -1;
{$ENDIF}
{$IFDEF LINUX}
Result := __read(Handle, Buffer, Count);
{$ENDIF}
end;
procedure FileClose(Handle: Integer);
begin
{$IFDEF MSWINDOWS}
CloseHandle(THandle(Handle));
{$ENDIF}
{$IFDEF LINUX}
__close(Handle);
{$ENDIF}
end;
// Signature Detector for detecting packers and compilers //
//////////////////////////////////////////////////////////////////////////////////////
function GetSignature(szFilename:string;Lenght:integer;Sept:boolean):string;
var
i,F:integer;
Signature,BytesRead,EP,IVA,RAW,UNL: DWORD;
Dos_Header: IMAGE_DOS_HEADER;
Pe_Header: IMAGE_FILE_HEADER;
Opt_Header: IMAGE_OPTIONAL_HEADER;
ImgSection:_IMAGE_SECTION_HEADER;
Buff:char;
Sep:string;
begin
Result:='';
F := CreateFile(pchar(szFilename), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); // Open file
ReadFile(F,Dos_header,SizeOf(Dos_header),BytesRead,nil);
if dos_header.e_magic <> IMAGE_DOS_SIGNATURE then //Test for validing PE file
begin
Exit;
end;
SetFilePointer(THandle(F), dos_header._lfanew, nil, 0); //reading dos header
ReadFile(F,signature, SizeOf(signature),BytesRead,nil);
if signature <> IMAGE_NT_SIGNATURE then // Test for validing PE file
begin
Exit;
end;
ReadFile(F,pe_header, SizeOf(pe_header),BytesRead,nil); //reading pe header
if pe_header.SizeOfOptionalHeader > 0 then
begin
ReadFile(F,opt_header, SizeOf(opt_header),BytesRead,nil); //reading optional header
ReadFile(F,imgsection, SizeOf(imgsection),BytesRead,nil); //reading image section
EP:=opt_header.AddressOfEntryPoint; // get entrypoint
IVA:=imgsection.VirtualAddress; //get virtual address of image section
RAW:=imgsection.PointerToRawData; //get pointer of raw data
UNL:=opt_header.SizeOfUninitializedData; //get size of uninitialized data
UNL:=IVA+UNL;
Offset:=EP-UNL+RAW; //get offset of signatures to read
end;
for i:=Offset to Offset+Lenght do //finding signatures
begin
FileSeek(F,i,0);
FileRead(F,Buff,SizeOf(Byte));
if Sept=True Then
if i <= Offset+Lenght-1
then Sep:=','
else Sep:='';
Result:=Result+IntToHex(Ord(Char(Buff)),2)+Sep; // <- result
end;
FileClose(f);
end;
begin
if (ParamStr(1) = '/?')or(ParamStr(1)='')or(GetSignature(ParamStr(1),0,True)='') then
begin
WriteLn;
WriteLn(' ***************** Signature Finder by : Arash Veyskarami *****************');
WriteLn;
WriteLn(' [FindOffset.exe] [Filename.exe]');
WriteLn;
WriteLn(' Ex: FindOffset C:\Windows\Explorer.exe');
ReadLn;
Exit;
end;
WriteLn;
WriteLn(' ***************** Signature Finder by : Arash Veyskarami *****************');
WriteLn;
WriteLN(' Filename= ',ParamStr(1)+'');
WriteLn;
WriteLN(' Offset= $',IntToHex(Offset,8)+'');
WriteLn;
WriteLN(' First Bytes= ',GetSignature(ParamStr(1),20,True)+'');
readln
end.
(***** By Veyskarami ;) *********)
در کد بالا اگه دقت کرده باشید خروجی که تابع از هر فایل به شما میده یک استرینگ هستش که نسبت به هر پکری ثابت هستش
این خروجی در واقع امضایی هست که کامپایلر یا پکر بعد از پک کردن فایل در File offset ثابت می مونه و با روش فوق قابل شناسایی هستش
آنتی ویروس ها یا حتی همون برنامه Peid خودمون هم از این روش استفاده می کنه و امضاهایی که بهد از پک یا کامپایل در فایل به جای میذارن توی یه دیتابیس به همرام اسم پکر جمع آوری میشه و بعد از اسکن کردن فایل با اون امضاها تطبیق داده میشه و بعد هم به راحتی میشه فهمید که از چه کامپایلر یا پکری واسه فایل مورد نظر استفاده شده