确定exe文件是否使用UPX压缩的方法
有没有一种方法可以确定exe文件是否使用UPX压缩?确定exe文件是否使用UPX压缩的方法
确定exe文件是否已被压缩的功能非常好,除非我发现代码有问题。如果函数IsUPXCompressed被调用,那么你尝试运行upx,upx不能保存它修改的文件。功能中有些东西没有正确共享权限。我已经测试了几个小时。如果我不调用这个方法,那么UPX可以写出没有问题的文件。你叫它然后尝试运行UPX它不会保存文件。尝试写入文件时,UPX报告IOException权限被拒绝错误。
任何人都可以在代码中找到会导致此问题的错误吗?
感谢信
的功能,以确定是否一个exe文件被压缩是优秀的,除了我发现代码中的问题。如果函数IsUPXCompressed被调用,那么你尝试运行upx,upx不能保存它修改的文件。功能中有些东西没有正确共享权限。我已经测试了几个小时。如果我不调用这个方法,那么UPX可以写出没有问题的文件。你叫它然后尝试运行UPX它不会保存文件。尝试写入文件时,UPX报告IOException权限被拒绝错误。
任何人都可以在代码中找到会导致此问题的错误吗?
谢谢你
尝试用upx解压缩它?
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;
}
这就是我称之为轻量级的方法! +1(但也许你应该详细说明一下:例如什么是'isection') – 2011-02-25 17:10:22
神奇的数字,蝙蝠侠! ImageHlp库可以在解析二进制文件的内容方面提供一些帮助。 – 2011-02-25 17:25:13
没有imagehlp和windows.h它至少是便携式的。和神奇的数字是很酷:) – Shelwien 2011-02-25 17:36:41
另一种方法,当一个exe包装用UPX工具,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;
+1这看起来很有希望。 – 2011-02-25 17:46:22
不幸的是,很酷的函数IsUPXCompressed在这里总是返回false。我测试了这3个新压缩的文件,并且该函数总是返回false。我在Win 7上运行Delphi 2010。任何人都知道为什么该函数不起作用? – Bill 2011-02-25 19:36:38
将'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签名。
我认为OP正在寻求一种轻量化的方法。 – 2011-02-25 16:52:02
这听起来不像是一种特别重的方法,加上OP没有任何迹象。在没有细节的情况下,我认为这是一个很好的答案! – 2011-02-25 16:59:46
@David:也许你是对的。我甚至从来没有听说过UPX ...... – 2011-02-25 17:01:03