6

有没有办法确定exe文件是否已用UPX压缩?

除了我发现代码有问题之外,确定 exe 文件是否已被压缩的功能非常好。如果函数 IsUPXCompressed 被调用然后你尝试运行 upx,upx 无法保存它修改的文件。函数中存在无法正确共享权限的内容。我已经测试了几个小时。如果我不调用该方法,那么 UPX 可以毫无问题地写入文件。你调用它然后尝试运行 UPX 它不会保存文件。UPX 在尝试写入文件时报告 IOException Permission denied 错误。

任何人都可以在代码中发现会导致此问题的错误吗?

谢谢


除了我发现代码有问题之外,确定 exe 文件是否已被压缩的功能非常好。如果函数 IsUPXCompressed 被调用然后你尝试运行 upx,upx 无法保存它修改的文件。函数中存在无法正确共享权限的内容。我已经测试了几个小时。如果我不调用该方法,那么 UPX 可以毫无问题地写入文件。你调用它然后尝试运行 UPX 它不会保存文件。UPX 在尝试写入文件时报告 IOException Permission denied 错误。

任何人都可以在代码中发现会导致此问题的错误吗?

谢谢

4

5 回答 5

11

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;
于 2011-02-25T17:30:35.780 回答
4

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;
}
于 2011-02-25T17:09:27.977 回答
2

尝试用upx解压?

于 2011-02-25T16:49:43.530 回答
1

// 返回 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;

感谢罗伯的指点。

于 2011-02-25T22:03:13.867 回答
1

部分名称始终不包含在 UPX 单词中。它可能包含由用户更改的另一个名称。对于某些。Ypu 必须在整个文件中搜索 UPX 压缩器签名。

于 2013-02-25T07:27:23.963 回答