【发布时间】:2010-05-05 20:50:12
【问题描述】:
我正在尝试从我计算机上安装的可执行文件列表中检测控制台应用程序。
如何实现?
每个应用程序都有一个“子系统”(Windows 应用程序、控制台应用程序或库;我认为作为选项指定给链接器)。如何仅使用可执行文件来检测它?
是否有替代方法来检测应用程序特征?另外,有什么方法可以检测文件是不是真正的可执行文件?
JAR 可执行文件有什么问题吗?
【问题讨论】:
标签: c# executable file-format
我正在尝试从我计算机上安装的可执行文件列表中检测控制台应用程序。
如何实现?
每个应用程序都有一个“子系统”(Windows 应用程序、控制台应用程序或库;我认为作为选项指定给链接器)。如何仅使用可执行文件来检测它?
是否有替代方法来检测应用程序特征?另外,有什么方法可以检测文件是不是真正的可执行文件?
JAR 可执行文件有什么问题吗?
【问题讨论】:
标签: c# executable file-format
您无需任何编程即可从
收到此信息dumpbin.exe /headers filename
一些信息为您提供 GetBinaryType 和 SHGetFileInfo 函数。您需要的所有信息都可以在每个可执行文件的标题中找到。请参阅http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx 中的 Microsoft 可移植可执行和通用对象文件格式规范。
也可以使用 DbgHelp.dll 中的调试帮助库 API(请参阅 http://msdn.microsoft.com/en-us/library/ms679309(VS.85).aspx)。 IMAGE_DOS_HEADER、IMAGE_DOS_SIGNATURE 和 IMAGE_NT_HEADERS32 结构为您提供完整的信息。
已更新(添加一些代码): 或者您可以只使用在 WinNT.h 中定义的结构。对应的代码可以像下面这样开始
// Open source file
hSrcFile = CreateFile (pszSrcFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hSrcFile == INVALID_HANDLE_VALUE)
__leave;
// Map the source file in memory
hMapSrcFile = CreateFileMapping (hSrcFile, NULL, PAGE_READONLY, 0, 0, NULL); // SEC_IMAGE
if (!hMapSrcFile || hMapSrcFile == INVALID_HANDLE_VALUE)
__leave;
// Map the entire of the source file is memory
pSrcFile = (PBYTE) MapViewOfFile (hMapSrcFile, FILE_MAP_READ, 0, 0, 0);
if (!pSrcFile)
__leave;
pDosHeader = (IMAGE_DOS_HEADER *)pSrcFile;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
printf ("it is not a EXE file.\n");
return 1;
}
printf ("IMAGE_DOS_HEADER size %d (0x%X) bytes\n", sizeof(IMAGE_DOS_HEADER), sizeof(IMAGE_DOS_HEADER));
DumpDosHeader (pDosHeader);
pDosExeStart = (PBYTE)pDosHeader + pDosHeader->e_cparhdr*16;
if (g_bDump)
HexDump (1, pDosExeStart, pDosHeader->e_lfanew - pDosHeader->e_cparhdr*16, (DWORD)pDosExeStart);
if (pDosHeader->e_lfanew) {
IMAGE_NT_HEADERS32 *pNtHeader = (IMAGE_NT_HEADERS32 *)((PBYTE)pDosHeader + pDosHeader->e_lfanew);
//IMAGE_NT_HEADERS64 *pNtHeader64 = (IMAGE_NT_HEADERS64 *)((PBYTE)pDosHeader + pDosHeader->e_lfanew);
IMAGE_SECTION_HEADER *pFirstSectionHeader = (IMAGE_SECTION_HEADER *)((PBYTE)&pNtHeader->OptionalHeader +
pNtHeader->FileHeader.SizeOfOptionalHeader);
if (pNtHeader->Signature == IMAGE_NT_SIGNATURE) {
int i;
printf ("\nPE signature\n");
printf ("\nIMAGE_FILE_HEADER: size %d (0x%X) bytes, offset from the begin of the file: %d (0x%X)\n",
sizeof(IMAGE_FILE_HEADER), sizeof(IMAGE_FILE_HEADER),
((PBYTE)&pNtHeader->FileHeader - (PBYTE)pDosHeader), ((PBYTE)&pNtHeader->FileHeader - (PBYTE)pDosHeader));
DumpFileHeader (1, &pNtHeader->FileHeader);
switch (pNtHeader->OptionalHeader.Magic) {
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
printf ("\nIMAGE_OPTIONAL_HEADER32: size %d (0x%X) bytes, offset from the begin of the file: %d (0x%X)\n",
sizeof(IMAGE_OPTIONAL_HEADER32), sizeof(IMAGE_OPTIONAL_HEADER32),
((PBYTE)&pNtHeader->OptionalHeader - (PBYTE)pDosHeader), ((PBYTE)&pNtHeader->OptionalHeader - (PBYTE)pDosHeader));
DumpOptionalHeader32 (1, &pNtHeader->OptionalHeader);
break;
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
break;
case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
break;
}
【讨论】:
Windows PE 可执行文件在标头中有一个字段,用于指定子系统(控制台、GUI、Posix 等)。它们还具有一般可用于识别可执行文件的字段。从 msdn.com 下载 PE 规范以获取详细信息。
【讨论】:
要确定子系统,您需要读取可执行文件并解析 PE-Header。关于如何做到这一点的详细文章is found here。
JAR 文件只是一个带有一些特定文件和文件夹结构的 ZIP 文件,因此您可以像打开常规 zip 文件一样打开它并查找始终存在的那些文件和文件夹。
【讨论】: