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

断了今生、忘了曾经 提交于 2019-12-01 02:17:55

问题


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


回答1:


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.

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;



回答2:


try to uncompress it with upx?




回答3:


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;
}



回答4:


// 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.




回答5:


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.



来源:https://stackoverflow.com/questions/5119948/method-to-determine-if-an-exe-file-has-been-compressed-with-upx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!