Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 方法确定是否已使用UPX压缩exe文件_Delphi_Compression_Exe_Upx - Fatal编程技术网

Delphi 方法确定是否已使用UPX压缩exe文件

Delphi 方法确定是否已使用UPX压缩exe文件,delphi,compression,exe,upx,Delphi,Compression,Exe,Upx,是否有方法确定是否已使用UPX压缩exe文件 确定exe文件是否已压缩的功能非常出色,但我发现代码有问题。如果调用函数IsUPXCompressed,则尝试运行upx,upx无法保存它修改的文件。函数中存在无法正确共享权限的问题。我已经测试了几个小时了。如果我不调用该方法,那么UPX可以毫无问题地写入文件。您调用它,然后尝试运行UPX,它将不会保存文件。UPX在尝试写入文件时报告IOException Permission denied错误 有人能发现代码中可能导致此问题的错误吗 多谢各位 确

是否有方法确定是否已使用UPX压缩exe文件

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

有人能发现代码中可能导致此问题的错误吗

多谢各位


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

有人能发现代码中可能导致此问题的错误吗


谢谢

尝试用upx解压吗?

upx本身就是这样做的:

if (memcmp(isection[0].name,"UPX",3) == 0)
    throwAlreadyPackedByUPX();
这是32位PEs的实现;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;
}
#包括
typedef无符号整数单元;
uint peek_d(文件*f,uint OFF){
fseek(f,offs,SEEK_SET);
uint a=0;
fread(&a,1,sizeof(a),f);
返回a;
}
int main(int argc,字符**argv){
FILE*f=fopen(argv[1],“rb”);如果(f==0)返回1;
单位p,n,x,y;
p=peek_d(f,0x3C);//PE头偏移量
n=peek_d(f,p+0x74);//指针表大小
x=p+0x78+n*8;
y=peek_d(f,x+0*0x28+0);//第一节名称

如果((y&0xFFFFFF)=('U'+('P'

另一种方法),当使用UPX工具打包exe时,PE头的部分包含名为

UPX0
UPX1
等的部分。因此,如果读取这些部分并将名称与字符串
UPX
进行比较,则可以确定是否使用UPX打包器压缩了exe

检查此功能

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;

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

感谢Rob的指点。

部分名称并不总是包含UPX单词。它可能包含用户更改的另一个名称。当然。Ypu必须在整个文件中搜索UPX压缩机签名。

我认为OP正在寻求一种稍微轻一点的方法。这听起来不像是一种特别重的方法,在没有细节的情况下,我认为这是一个很好的答案!好的。那么,你是怎么做到的呢?(并且以编程方式,记住。)@David,这是一个编程网站。每一个问题都隐含着它。如果Bill不想要一个编程解决方案,那么这个问题属于超级用户,而不是堆栈溢出。@David:这个问题发布在上的事实强烈表明它是以编程方式完成的。如果OP不希望以编程方式完成,我会回答这个问题应该关闭(或移动到SU)。这就是我所说的轻量级方法!+1(但也许你应该详细说明一下:例如,什么是
isection
)神圣的魔法数字,蝙蝠侠!ImageHlp库可以帮助解析二进制文件的内容。没有ImageHlp和windows.h,它至少是可移植的。魔法数字很酷:)@Shelwien,当你阅读Win32可执行文件头以查看它是否被UPX压缩时,为什么可移植性很重要?它是一个WINDOWS可执行文件。而且神奇的数字很难维护。(顺便说一句,你能解释一下“y=peek_d(f,x+0*0x28+0)”吗?零+28h+0=28h,除非我忘记了我的基本数学技能,所以“y=peek_d(f,x+0x28)@Shelwien:如果一个Win32应用程序被压缩了w/UPX,除了Windows应用程序之外,为什么其他应用程序会在意呢?就数学而言,你可以比(x+(0*0x28)+0)更容易地修改“peek_d(f,x)”“。不幸的是,酷函数IsUPXCompressed在这里总是返回false。我对3个新压缩的文件进行了测试,该函数总是返回false。我正在Win 7上运行Delphi 2010。有人知道该函数为什么不工作吗?将
SectName
声明为
AnsiString
(或者
UTF8String
,如果有的话),然后键入cast
@pSectionHeader.Name
PAnsiChar
。图像头名称是UTF-8,而不是UCS-2。或者甚至用
StrLComp
替换
SetString
Pos
,以比较前三个字符。@Bill该函数已被启动,以使用unicode版本的Delphi。(>=2009)@RRUZ:我可能会将for..循环中的测试更改为:
Result:=Pos('UPX',SectName)>0;如果结果是中断的;
这消除了一个退出点(使代码更容易遵循IMO)。多亏了所有这些。我现在可以测试压缩,UPX仍然可以工作。