我刚刚阅读了关于它们在磁盘上的文件中的偏移,RVA和VA一旦被加载到内存中.我还读到,如果一个PE文件完全像在磁盘中一样加载到内存中,那么RVA将与文件偏移相同(并且发生这种情况将是非常不寻常的).
我怀疑的是 - 在正常情况下,这些RVA相对于什么?特定PE数据结构的开始?
编辑:通过PE数据结构我的意思是 - PE头,DOS头,DOS存根,PE文件头,图像可选头,节表和数据目录.
我有以下C程序:
#include <windows.h>
void __cdecl mainCRTStartup() {
DWORD bw;
HANDLE hfile = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(hfile, "Hello, World!\r\n", 15, &bw, 0);
ExitProcess(0); /* Needed for successful (0) exit. */
}
Run Code Online (Sandbox Code Playgroud)
我使用以下命令行使用GCC 4.8.2编译它:
i686-w64-mingw32-gcc -s -Os -fno-ident -fno-stack-protector -fomit-frame-pointer \
-fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1 \
-mpreferred-stack-boundary=2 -falign-jumps=1 -falign-loops=1 -mconsole \
-nostdlib -nodefaultlibs -nostartfiles -o h.exe h.c -lkernel32
Run Code Online (Sandbox Code Playgroud)
生成的.exe文件长度为2048字节.如何使用MinGW将其缩小,最好是1024字节,或者(甚至更好)最多512字节?
我更喜欢没有编写汇编代码的解决方案,但我也对组装解决方案感兴趣.
我试图-Wl,-N减少部分(段)的数量,但是在Wine中运行.exe时会导致段错误.
该文章认为,480个字节是可能的.它使用以下设置:
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")// Merge sections
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/MERGE:.reloc=.data")
#pragma optimize("gsy", …Run Code Online (Sandbox Code Playgroud) 我需要阅读x64 PE文件的".pdata"部分.
我已经看到".pdata"部分中的结构从一个平台到另一个平台不同
http://msdn.microsoft.com/en-us/library/aa448751.aspx
它在PE规范文档中也说了同样的事情.
但我不明白常规窗户是什么(XP/Vista/Win7等)
有人是什么?
好吧,所以我的想法是将64位和32位Windows可执行文件绑定到一个应用程序的某种方式,所以如果它不运行64位版本,它将尝试32位版本.
我正在阅读有关PE的内容,并了解了一些关于MS-DOS Real Mode Stub的内容,并说明了它如何调用应用程序(通常是错误消息).但每次我尝试研究MS-DOS Real Mode Stub时,它似乎只显示错误消息.所以我的想法是用我的32位应用程序覆盖STUB.
当32位操作系统运行64位可执行文件时,我自己很天真,它会失败,然后运行存根文件.
有没有办法让我的可执行程序32位/ 64位独立?
windows executable fat-binaries portable-executable 32bit-64bit
通过使用 7zip 在 Windows 中打开许多可执行 ( .exe., .msi) 文件,我注意到许多不同的常见文件类型。这些包括 .text、.data、.bss、.rdata、.pdata 等。我试图获取有关它们的信息,但我无法找出它们的全部含义。以下是其中一些:
.text :代码部分,包含程序的指令-只读-。 .data: 一般用于一些初始化的非零内容的可写数据。因此,数据部分包含可以在应用程序执行期间更改的信息,并且必须为每个实例复制该部分。.bss : 用于初始化为零的可写静态数据。 .rdata : 任何类型的常量/只读数据都存储在这里。 .edata : 导出目录、描述符和句柄 .idata:句柄和描述符的导入目录。可执行文件(exe、dll 等)使用它来指定导入和导出的函数。.rsrc :包含可执行文件所需的各种其他资源的信息的部分,例如在资源管理器中查看可执行文件时显示的图标 还有很多其他的,这是常见的,我找不到任何信息。主要是:.pdata, .tls, .reloc, 证书, .rsrc_1, .aspack, .adata, .INIT, DATA, CODE, .ctors。
rsrc其中大多数都包含一个文件夹,其中包含 BITMAP、CURSOR、ICON、GROUP_CURSOR、GROUP_ICON、MENU、VERSION 等文件夹。
一些可执行文件还包含更多的可执行文件、.html文件、.txt文件等。我还打开了一个根本不包含任何内容的可执行文件(至少用 7zip 打开它没有显示任何内容)![我用7zip打开了它们。]
问题
rsrc文件夹有什么用?它拥有什么样的资源?我将不胜感激,如果您能发布更多关于为什么使用所有这些(尽可能低级别)的信息/链接,以及通常可执行结构应该是什么样子,它应该包含什么等。
这就是全部。
编辑 …
在此文章中,定义
DWORD VirtualAddress
在 EXE 中,此字段保存 RVA 到加载程序应将部分映射到的位置。要计算内存中给定节的实际起始地址,请将图像的基地址添加到存储在此字段中的节的 VirtualAddress。
DWORD PointerToRawData
这是可以找到编译器或汇编器发出的原始数据的基于文件的偏移量。如果您的程序内存映射 PE 或 COFF 文件本身(而不是让操作系统加载它),则该字段比 VirtualAddress 字段更重要。在这种情况下,您将拥有一个完全线性的文件映射,因此您将在此偏移量处找到节的数据,而不是在 VirtualAddress 字段中指定的 RVA
也RVA被定义为
PE 文件中的许多字段都是根据 RVA 指定的。RVA 只是某个项目的偏移量,相对于文件的内存映射位置
和
要将 RVA 转换为可用指针,只需将 RVA 添加到模块的基地址即可。基地址是内存映射的 EXE 或 DLL 的起始地址
手头的问题是到达import sectionPE 文件。
hFile = CreateFile(..);
hFileMapping = CreateFileMapping(..);
lpFileBase = MapViewOfFile(..);
ImageBase = (PIMAGE_DOS_HEADER)lpFileBase;
PEHeader = (ImageBase + ImageBase->e_lfanew);
Run Code Online (Sandbox Code Playgroud)
现在要掌握 import table
PIMAGE_OPTIONAL_HEADER PEImageOptionalHeader = &(PEHeader->OptionalHeader);
IMAGE_DATA_DIRECTORY importTable = PEImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
Run Code Online (Sandbox Code Playgroud)
由于importTable.VirtualAddress是 RVA,为了获得可用的指针,我可以添加图像文件的基础。
所以ImageBase …
在IMAGE_DOS_HEADERPE(Windows可执行文件)格式中有一个称为的字段e_lfanew,它起着非常重要的作用,因为它指向实际的PE头数据.
我的问题是,"e_lfanew"实际上代表什么?这是什么意思?它太神秘了.
编辑:我不是在问它做了什么,我知道它做了什么,我想知道这些字母e_lfanew实际上代表什么,为什么给它这个名字?
我正在尝试手动签署现有的便携式可执行文件。
我正在按照本文档中的说明进行操作:
windows ×7
c++ ×2
executable ×2
winapi ×2
32bit-64bit ×1
64-bit ×1
assembly ×1
c ×1
entry-point ×1
exe ×1
fat-binaries ×1
file-format ×1
mingw ×1