- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
是否有我可以在 Linux 中使用的库,该库将返回资源管理器的版本选项卡中列出的 Windows EXE 文件的属性?这些是产品名称、产品版本、描述等字段。
对于我的项目,EXE 文件只能从内存中读取,不能从文件中读取。我想避免将 EXE 文件写入磁盘。
最佳答案
该文件的版本在 VS_FIXEDFILEINFO
struct,但你必须在可执行数据中找到它。有两种方法可以做你想做的事:
VS_FIXEDFILEINFO
直接构造。 .rsrc
部分,解析资源树,找到RT_VERSION
资源,解析它并提取 VS_FIXEDFILEINFO
数据。 typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef uint8_t BYTE;
#define READ_BYTE(p) (((unsigned char*)(p))[0])
#define READ_WORD(p) ((((unsigned char*)(p))[0]) | ((((unsigned char*)(p))[1]) << 8))
#define READ_DWORD(p) ((((unsigned char*)(p))[0]) | ((((unsigned char*)(p))[1]) << 8) | \
((((unsigned char*)(p))[2]) << 16) | ((((unsigned char*)(p))[3]) << 24))
#define PAD(x) (((x) + 3) & 0xFFFFFFFC)
const char *FindVersion(const char *buf)
{
//buf is a IMAGE_DOS_HEADER
if (READ_WORD(buf) != 0x5A4D) //MZ signature
return NULL;
//pe is a IMAGE_NT_HEADERS32
const char *pe = buf + READ_DWORD(buf + 0x3C);
if (READ_WORD(pe) != 0x4550) //PE signature
return NULL;
//coff is a IMAGE_FILE_HEADER
const char *coff = pe + 4;
WORD numSections = READ_WORD(coff + 2);
WORD optHeaderSize = READ_WORD(coff + 16);
if (numSections == 0 || optHeaderSize == 0)
return NULL;
//optHeader is a IMAGE_OPTIONAL_HEADER32
const char *optHeader = coff + 20;
if (READ_WORD(optHeader) != 0x10b) //Optional header magic (32 bits)
return NULL;
//dataDir is an array of IMAGE_DATA_DIRECTORY
const char *dataDir = optHeader + 96;
DWORD vaRes = READ_DWORD(dataDir + 8*2);
//secTable is an array of IMAGE_SECTION_HEADER
const char *secTable = optHeader + optHeaderSize;
.rsrc
的节。 .
int i;
for (i = 0; i < numSections; ++i)
{
//sec is a IMAGE_SECTION_HEADER*
const char *sec = secTable + 40*i;
char secName[9];
memcpy(secName, sec, 8);
secName[8] = 0;
if (strcmp(secName, ".rsrc") != 0)
continue;
DWORD vaSec = READ_DWORD(sec + 12);
const char *raw = buf + READ_DWORD(sec + 20);
vaRes
的偏移量我们之前得到的 VA 很容易。
const char *resSec = raw + (vaRes - vaSec);
WORD numNamed = READ_WORD(resSec + 12);
WORD numId = READ_WORD(resSec + 14);
int j;
for (j = 0; j < numNamed + numId; ++j)
{
//resSec is a IMAGE_RESOURCE_DIRECTORY followed by an array
// of IMAGE_RESOURCE_DIRECTORY_ENTRY
const char *res = resSec + 16 + 8 * j;
DWORD name = READ_DWORD(res);
if (name != 16) //RT_VERSION
continue;
DWORD offs = READ_DWORD(res + 4);
if ((offs & 0x80000000) == 0) //is a dir resource?
return NULL;
//verDir is another IMAGE_RESOURCE_DIRECTORY and
// IMAGE_RESOURCE_DIRECTORY_ENTRY array
const char *verDir = resSec + (offs & 0x7FFFFFFF);
numNamed = READ_WORD(verDir + 12);
numId = READ_WORD(verDir + 14);
if (numNamed == 0 && numId == 0)
return NULL;
res = verDir + 16;
offs = READ_DWORD(res + 4);
if ((offs & 0x80000000) == 0) //is a dir resource?
return NULL;
//and yet another IMAGE_RESOURCE_DIRECTORY, etc.
verDir = resSec + (offs & 0x7FFFFFFF);
numNamed = READ_WORD(verDir + 12);
numId = READ_WORD(verDir + 14);
if (numNamed == 0 && numId == 0)
return NULL;
res = verDir + 16;
offs = READ_DWORD(res + 4);
if ((offs & 0x80000000) != 0) //is a dir resource?
return NULL;
verDir = resSec + offs;
DWORD verVa = READ_DWORD(verDir);
const char *verPtr = raw + (verVa - vaSec);
return verPtr;
NULL
.
}
return NULL;
}
return NULL;
}
int PrintVersion(const char *version, int offs)
{
offs = PAD(offs);
WORD len = READ_WORD(version + offs);
offs += 2;
WORD valLen = READ_WORD(version + offs);
offs += 2;
WORD type = READ_WORD(version + offs);
offs += 2;
char info[200];
int i;
for (i=0; i < 200; ++i)
{
WORD c = READ_WORD(version + offs);
offs += 2;
info[i] = c;
if (!c)
break;
}
offs = PAD(offs);
type
不为0,则为字符串版本数据。
if (type != 0) //TEXT
{
char value[200];
for (i=0; i < valLen; ++i)
{
WORD c = READ_WORD(version + offs);
offs += 2;
value[i] = c;
}
value[i] = 0;
printf("info <%s>: <%s>\n", info, value);
}
VS_VERSION_INFO
那么它是一个
VS_FIXEDFILEINFO
结构。否则它是二进制数据。
else
{
if (strcmp(info, "VS_VERSION_INFO") == 0)
{
//fixed is a VS_FIXEDFILEINFO
const char *fixed = version + offs;
WORD fileA = READ_WORD(fixed + 10);
WORD fileB = READ_WORD(fixed + 8);
WORD fileC = READ_WORD(fixed + 14);
WORD fileD = READ_WORD(fixed + 12);
WORD prodA = READ_WORD(fixed + 18);
WORD prodB = READ_WORD(fixed + 16);
WORD prodC = READ_WORD(fixed + 22);
WORD prodD = READ_WORD(fixed + 20);
printf("\tFile: %d.%d.%d.%d\n", fileA, fileB, fileC, fileD);
printf("\tProd: %d.%d.%d.%d\n", prodA, prodB, prodC, prodD);
}
offs += valLen;
}
while (offs < len)
offs = PrintVersion(version, offs);
return PAD(offs);
}
main
功能。
int main(int argc, char **argv)
{
struct stat st;
if (stat(argv[1], &st) < 0)
{
perror(argv[1]);
return 1;
}
char *buf = malloc(st.st_size);
FILE *f = fopen(argv[1], "r");
if (!f)
{
perror(argv[1]);
return 2;
}
fread(buf, 1, st.st_size, f);
fclose(f);
const char *version = FindVersion(buf);
if (!version)
printf("No version\n");
else
PrintVersion(version, 0);
return 0;
}
关于从Linux读取EXE版本的C库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12396665/
我正在努力处理不同的 R 可执行文件。在批处理文件中运行命令行时,R.exe(带或不带 CMD BATCH 选项)、Rcmd.exe、Rscript.exe 和 Rterm.exe 有什么区别? 两者
这个问题是我之前问题的一个答案的扩展:how to save user registration in the exe... (C#) . 这个想法本身对我来说仍然很新,但它似乎是合理的。我第一次尝试
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 12 年前。 Improve thi
我正在使用 React VR 制作一个 WebVR 应用程序。我将使用 Oculus Rift 和 HTC-Vive 测试该应用程序。我正在使用浏览器 Firefox Nightly 来访问 WebV
当我从 A.exe(位于 c:/my_software/FOLDER_A/A.exe)运行 B.exe(位于 c:/my_software/FOLDER_B/B.exe)时,两者均使用 cx_Free
我有一个以前的程序员留下的exe(GUI),它是在cpp中完成的,但是我需要禁用程序中的一些键盘键,因为当它们被意外击中时,这是不可取的。我正在使用 Windows。 我能否编写一个程序来在 Wind
这不是以下 SO 问题的重复: How do I tell if a win32 application uses the .NET runtime . 如果给定的 exe 文件是 .net exe
我刚刚安装了 ActivePython 3.6 的 64 位版本,发现它包含三个可执行文件,它们报告相同的版本信息,大小相同,但不完全相同,即peer fc.exe。我有 python.exe pyt
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
有哪些方法可以保护exe文件免遭逆向工程。有很多打包工具可以打包exe文件。这种方法在http://c-madeeasy.blogspot.com/2011/07/protecting-your-c-
仅当应用“X”(Inspect.exe | Narrator.exe | Magnify.exe)正在运行时,我才能在 Windows 应用程序中获取一些 IUIAutomationElements。
我正在编写一个创建 Windows 服务的程序。所以我需要两个 .exe 文件——一个用于程序,创建服务,另一个用于服务本身。但是我想将这两个文件合二为一。我有以下想法 - 打开 .exe 文件,我想
我有一个 UWP 应用,我需要从 users %appdata% 文件夹中启动一个 .Exe 文件。 我不知道如何找到 %appdata% 或如何启动 Exe 文件。 我已经查看了所有解决方案,但没有
我最近安装了 Visual Studio 2017,MSBuild.exe 不是应该自带的吗? bash 脚本之一正在调用它,但找不到任何东西。 这是 build.bat 产生错误的部分(您可以看到整
我正在我自己的代码中尝试来自 Mad-collections(用于在 exe 中添加/删除或更新资源的单元)中 Madres 单元的不同功能。这适用于小型资源(小于 50 MB),但对于较大的资源(大
什么是PreEmptive Protection Dotfuscator exe文件的Map.Xml和Dotfuscator1.Xml文件。我应该出于某种原因保留它们,还是项目 exe 文件组装需要它
我最近接手了一个项目,我不确定最后一个人是如何调试这个的......我有两个可执行文件,一个最终运行另一个。我将它们称为 exe1 和 exe2。这些是用 C# 创建的,我使用 Visual Stud
如何从 REBOL 脚本创建 Windows 可执行文件 (.exe)?有任何说明或视频吗? 最佳答案 使用 Rebol 2 最简单的方法是使用 SDK - 尽管这需要花钱购买许可证。该方法称为封装。
我正在尝试打开下载的 .exe 文件,但它在打开后立即关闭。有什么可能的方法可以让我打开它更长的时间来阅读内容。 最佳答案 它可能是一个控制台应用程序而不是一个 GUI 应用程序。使用命令提示符运行
我想运行一个位于以下目录中的应用程序: C:\LCR 12\stu.exe 使用 AutoIt,运行上述 stu.exe 文件的代码是什么? 最佳答案 像这样: Run("C:\LCR 12\stu.
我是一名优秀的程序员,十分优秀!