Метод определения, был ли exe-файл сжат с помощью UPX - PullRequest
6 голосов
/ 25 февраля 2011

Есть ли способ определить, был ли exe-файл сжат с помощью UPX?

Функция определения, был ли exe-файл сжат, превосходна, за исключением того, что я обнаружил проблему с кодом.Если вызывается функция IsUPXCompressed, то вы пытаетесь запустить upx, upx не может сохранить файл, который она изменяет.Что-то не правильно делится правами в функции.Я проверял это в течение нескольких часов.Если я не вызываю метод, тогда UPX может записать файлы без проблем.Если вы называете это, то попробуйте запустить UPX, он не сохранит файл.UPX сообщает об ошибке «Отказ в разрешении IOException» при попытке записи файла.

Может ли кто-нибудь определить в коде что-то неправильное, что может вызвать эту проблему?

Спасибо


Функция определения, был ли exe-файл сжат, превосходна, за исключением того, что я обнаружил проблему с кодом.Если вызывается функция IsUPXCompressed, то вы пытаетесь запустить upx, upx не может сохранить файл, который она изменяет.Что-то не правильно делится правами в функции.Я проверял это в течение нескольких часов.Если я не вызываю метод, тогда UPX может записать файлы без проблем.Если вы называете это, то попробуйте запустить UPX, он не сохранит файл.UPX сообщает об ошибке «Отказано в разрешении IOException» при попытке записи файла.

Может ли кто-нибудь обнаружить в коде что-то неправильное, что может вызвать эту проблему?

Спасибо

Ответы [ 5 ]

11 голосов
/ 25 февраля 2011

Другой метод, когда исполняемый файл упакован с помощью инструмента UPX, раздел PE-заголовка содержит разделы, называемые UPX0, UPX1 и т. Д., Поэтому, если прочитать эти разделы и сравнить имя со строкой UPX Вы можете определить, был ли exe сжат, используя упаковщик UPX.

enter image description here

проверить эту функцию

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;
2 голосов
/ 25 февраля 2011

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;
}
2 голосов
/ 25 февраля 2011

попытаться распаковать его с помощью upx?

1 голос
/ 25 февраля 2013

Имена разделов не всегда включают слово UPX. Это может содержать другое имя, измененное пользователем. Для определенных. Ypu должен искать сигнатуру UPX-коппрессора во всем файле.

1 голос
/ 26 февраля 2011

// Возвращает 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;

Спасибо Робу за указатели.

...