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

问题描述:

有没有一种方法可以确定exe文件是否使用UPX压缩?确定exe文件是否使用UPX压缩的方法

确定exe文件是否已被压缩的功能非常好,除非我发现代码有问题。如果函数IsUPXCompressed被调用,那么你尝试运行upx,upx不能保存它修改的文件。功能中有些东西没有正确共享权限。我已经测试了几个小时。如果我不调用这个方法,那么UPX可以写出没有问题的文件。你叫它然后尝试运行UPX它不会保存文件。尝试写入文件时,UPX报告IOException权限被拒绝错误。

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

感谢信


的功能,以确定是否一个exe文件被压缩是优秀的,除了我发现代码中的问题。如果函数IsUPXCompressed被调用,那么你尝试运行upx,upx不能保存它修改的文件。功能中有些东西没有正确共享权限。我已经测试了几个小时。如果我不调用这个方法,那么UPX可以写出没有问题的文件。你叫它然后尝试运行UPX它不会保存文件。尝试写入文件时,UPX报告IOException权限被拒绝错误。

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

谢谢你

尝试用upx解压缩它?

+0

我认为OP正在寻求一种轻量化的方法。 – 2011-02-25 16:52:02

+0

这听起来不像是一种特别重的方法,加上OP没有任何迹象。在没有细节的情况下,我认为这是一个很好的答案! – 2011-02-25 16:59:46

+0

@David:也许你是对的。我甚至从来没有听说过UPX ...... – 2011-02-25 17:01:03

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

这就是我称之为轻量级的方法! +1(但也许你应该详细说明一下:例如什么是'isection') – 2011-02-25 17:10:22

+3

神奇的数字,蝙蝠侠! ImageHlp库可以在解析二进制文件的内容方面提供一些帮助。 – 2011-02-25 17:25:13

+1

没有imagehlp和windows.h它至少是便携式的。和神奇的数字是很酷:) – Shelwien 2011-02-25 17:36:41

另一种方法,当一个exe包装用UPX工具,PE头的部分包含部分称为UPX0UPX1等,所以如果阅读这些章节,以字符串比较名称UPX即可确定是否使用UPX打包器压缩exe文件。

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; 
+0

+1这看起来很有希望。 – 2011-02-25 17:46:22

+0

不幸的是,很酷的函数IsUPXCompressed在这里总是返回false。我测试了这3个新压缩的文件,并且该函数总是返回false。我在Win 7上运行Delphi 2010。任何人都知道为什么该函数不起作用? – Bill 2011-02-25 19:36:38

+0

将'SectName'声明为'AnsiString'(或者'UTF8String',如果有的话),并将'@ pSectionHeader.Name'类型转换为'PAnsiChar'。图像标题名称是UTF-8,而不是UCS-2。甚至用'StrLComp'替换'SetString'和'Pos'来比较前三个字符。 – 2011-02-25 21:21:09

//返回IsUPXCompressed - 修正了德尔福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; 

感谢罗布的指针。

段名不总是包含在UPX字中。它包含另一个用户更改的名称。对于某些。 Ypu必须在整个文件中搜索UPX copmpressor签名。