Method to determine if an exe file has been compressed with UPX

5.4k views Asked by At

Is there a method to determine if an exe file has been compressed with UPX?

The function to determine if an exe file has been compressed is excellent except I found a problem with the code. If the function IsUPXCompressed is called then you try to run upx, upx can not save the file it modifies. There is something not sharing rights correctly in the function. I have tested this for several hours. If I do not call the method then UPX can write the files with no problem. You you call it then try to run UPX it will not save the file. UPX reports an IOException Permission denied error when trying to write the file.

Can anyone spot something wrong in the code that would cause this problem?

Thank-you


The function to determine if an exe file has been compressed is excellent except I found a problem with the code. If the function IsUPXCompressed is called then you try to run upx, upx can not save the file it modifies. There is something not sharing rights correctly in the function. I have tested this for several hours. If I do not call the method then UPX can write the files with no problem. You you call it then try to run UPX it will not save the file. UPX reports an IOException Permission denied error when trying to write the file.

Can anyone spot something wrong in the code that would cause this problem?

Thank-you

5

There are 5 answers

9
oddi On

try to uncompress it with upx?

10
Shelwien On

UPX itself does it like this:

if (memcmp(isection[0].name,"UPX",3) == 0)
    throwAlreadyPackedByUPX();

This is the implementation for 32-bit PEs; 64-bit PEs need different offsets, and other executable formats have to be handled separately.

#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;
}
5
RRUZ On

Another Method, when a exe is packed with the UPX tool, the section of the PE header contains sections called UPX0,UPX1, etc. so if read these sections and compare the name with the string UPX you can determine if the exe was compressed using the UPX packer.

enter image description here

check this function

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;
0
Bill On

// Returns IsUPXCompressed - Modified for 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;

Thanks Rob for the pointers.

0
drjackool On

The section names are not included the UPX word always. It mabebe contain another name changed by user. For certain. Ypu must search for UPX copmpressor signature in the whole file.