Метод определения, был ли exe-файл сжат с помощью UPX
Есть ли способ определить, был ли exe-файл сжат с помощью UPX?
Функция для определения, был ли сжат exe-файл, превосходен, за исключением того, что я нашел проблему с кодом. Если вызывается функция IsUPXCompressed, то вы пытаетесь запустить upx, upx не может сохранить файл, который она изменяет. Что-то не правильно делится правами в функции. Я проверял это в течение нескольких часов. Если я не вызываю метод, тогда UPX может записать файлы без проблем. Если вы называете это, то попробуйте запустить UPX, он не сохранит файл. UPX сообщает об ошибке "Отказано в разрешении IOException" при попытке записи файла.
Может кто-нибудь определить что-то не так в коде, который может вызвать эту проблему?
Спасибо
Функция для определения, был ли сжат exe-файл, превосходен, за исключением того, что я нашел проблему с кодом. Если вызывается функция IsUPXCompressed, то вы пытаетесь запустить upx, upx не может сохранить файл, который она изменяет. Что-то не правильно делится правами в функции. Я проверял это в течение нескольких часов. Если я не вызываю метод, тогда UPX может записать файлы без проблем. Если вы называете это, то попробуйте запустить UPX, он не сохранит файл. UPX сообщает об ошибке "Отказано в разрешении IOException" при попытке записи файла.
Может кто-нибудь определить что-то не так в коде, который может вызвать эту проблему?
Спасибо
5 ответов
Другой метод, когда исполняемый файл упакован с помощью инструмента UPX, раздел PE-заголовка содержит разделы, называемые UPX0
,UPX1
и т. д., так что если вы прочитаете эти разделы и сравните название со строкой UPX
Вы можете определить, был ли exe сжат, используя упаковщик UPX.
проверьте эту функцию
uses
Windows;
function IsUPXCompressed(const Filename:TFileName): Boolean;
var
i : integer;
pBaseAddress : PByte;
pDosHeader : PImageDosHeader;
pNtHeaders : PImageNtHeaders;
hFile : Cardinal;
hFileMap : Cardinal;
pSectionHeader: PImageSectionHeader;
dwOffset : Cardinal;
SectName : AnsiString;
begin
Result:=False;
hFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile = INVALID_HANDLE_VALUE) then Exit;
hFileMap := CreateFileMapping(hFile, nil, PAGE_READONLY or SEC_IMAGE, 0, 0, nil);
if (hFileMap = 0) then
begin
CloseHandle(hFile);
Exit;
end;
pBaseAddress := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
if (pBaseAddress = nil) then
begin
CloseHandle(hFileMap);
CloseHandle(hFile);
Exit;
end;
try
dwOffset := Cardinal(pBaseAddress);
pDosHeader := PImageDosHeader(pBaseAddress);
pNtHeaders := PImageNtHeaders(dwOffset + Cardinal(pDosHeader._lfanew));
pSectionHeader := pImageSectionHeader(Cardinal(pNtHeaders) + SizeOf(TImageNtHeaders));
for i := 0 to pNtHeaders.FileHeader.NumberOfSections-1 do
begin
SetString(SectName, PAnsiChar(@pSectionHeader.Name), SizeOf(pSectionHeader.Name));
Result:=Pos('UPX',SectName)>0;
If Result then break;
Inc(pSectionHeader);
end;
finally
UnmapViewOfFile(pBaseAddress);
CloseHandle(hFileMap);
CloseHandle(hFile);
end;
end;
Сам UPX делает это так:
if (memcmp(isection[0].name,"UPX",3) == 0)
throwAlreadyPackedByUPX();
Это реализация для 32-битных PE; Для 64-битных PE требуются разные смещения, а другие исполняемые форматы должны обрабатываться отдельно.
#include <stdio.h>
typedef unsigned int uint;
uint peek_d( FILE* f, uint offs ) {
fseek( f, offs, SEEK_SET );
uint a = 0;
fread( &a, 1,sizeof(a), f );
return a;
}
int main( int argc, char** argv ) {
FILE* f = fopen( argv[1], "rb" ); if( f==0 ) return 1;
uint p,n,x,y;
p = peek_d( f, 0x3C ); // PE header offset
n = peek_d( f, p+0x74 ); // pointer table size
x = p + 0x78 + n*8;
y = peek_d( f, x+0*0x28+0 ); // 1st section name
if( (y&0xFFFFFF) == ('U'+('P'<<8)+('X'<<16)) ) {
printf( "UPX detected!\n" );
} else {
printf( "No UPX!\n" );
}
return 0;
}
// Возвращает IsUPXCompressed - модифицировано для Delphi 2010
function IsUPXCompressed( const Filename: TFileName ): Boolean;
var
i: integer;
pBaseAddress: PByte;
pDosHeader: PImageDosHeader;
pNtHeaders: PImageNtHeaders;
hFile: Cardinal;
hFileMap: Cardinal;
pSectionHeader: PImageSectionHeader;
dwOffset: Cardinal;
SectName: AnsiString;
begin
Result := False;
hFile := CreateFile( PChar( Filename ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if ( hFile = INVALID_HANDLE_VALUE ) then
Exit;
hFileMap := CreateFileMapping( hFile, nil, PAGE_READONLY or SEC_IMAGE, 0, 0, nil );
if ( hFileMap = 0 ) then
begin
CloseHandle( hFile );
Exit;
end;
pBaseAddress := MapViewOfFile( hFileMap, FILE_MAP_READ, 0, 0, 0 );
if ( pBaseAddress = nil ) then
begin
CloseHandle( hFileMap );
CloseHandle( hFile );
Exit;
end;
dwOffset := Cardinal( pBaseAddress );
pDosHeader := PImageDosHeader( pBaseAddress );
pNtHeaders := PImageNtHeaders( dwOffset + Cardinal( pDosHeader._lfanew ) );
pSectionHeader := pImageSectionHeader( Cardinal( pNtHeaders ) + SizeOf( TImageNtHeaders ) );
for i := 0 to pNtHeaders.FileHeader.NumberOfSections - 1 do
begin
SetString( SectName, PAnsiChar( @pSectionHeader.name ), SizeOf( pSectionHeader.name ) );
if Pos( 'UPX', SectName ) > 0 then
begin
Result := True;
exit;
end;
Inc( pSectionHeader );
end;
end;
Спасибо Робу за указатели.
Имена разделов не всегда включают слово UPX. Это может содержать другое имя, измененное пользователем. Для определенных. Ypu должен искать сигнатуру UPX-коппрессора во всем файле.