能力值:
( LV2,RANK:10 )
|
-
-
2 楼
用文件映射到内存的基地址加上导入表的在文件中的偏移地址就是结构数组 IMAGE_IMPORT_DESCRIPTOR开始的地址,也就是导入表在文件中的开始位置。
这句话有误吧,最后一句应该是导入表在内存中的位置吧,不是文件中的位置。其实就是RVA和VA的关系,基地址加上RVA等于VA。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
哈哈哈哈哈哈哈哈哈哈
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
我觉得这句话怎么说都有错,导入表在文件中的偏移就是导入表的入口地址了,但是这个入口地址只是文件中的,因为对齐的原因,导入表在内存中的地址无论如何是不可能与加载进内存的偏移地址是一样的,除非是数据与节区的相对偏移地址,加载进内存才会不变,所以这句怎么看怎么不对劲
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
导入表在文件中对于其所处的区块的偏移和在内存中对于同一区块的偏移是一样的,例如导入表在区段A中,且对于区段A的文件偏移是B,那么当区段A载入内存后,导入表对区段A的偏移也是B,不同的只是区段A在文件中的偏移和在内存中的偏移,而导入表对于区段A的偏移都是相同的。
导入表在内存中相对于当前区段的偏移加上区段本身的偏移就是RVA再加上模块基地址就是导入表的确切虚拟地址了。
我是这样理解的
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
首先声明:
映像后(如LoadLibrary)文件在内存中的内容与直接读文件(OpenFile. ReadFile)在内存中内容是完全不同的.
所有楼主所说的: "文件中", 标准应该是 " 映像后文件在内存中";
PIMAGE_DOS_HEADER pDosHdr = Buffer; // Buffer 就是文件映像基址
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
...
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS32 pNtHdr = Buffer + pDosHdr->e_lfanew;
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
PIMAGE_EXPORT_DIRECTORY pExportEntry = (PIMAGE_EXPORT_DIRECTORY)(
Buffer +
pNtHdr->OptionalHeader.DataDirectory[0].VirtualAddress
);
PIMAGE_IMPORT_DESCRIPTOR pImportEntry = (PIMAGE_IMPORT_DESCRIPTOR)(
Buffer +
pNtHdr->OptionalHeader.DataDirectory[1].VirtualAddress
);
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)(
Buffer +
pNtHdr->OptionalHeader.DataDirectory[5].VirtualAddress
);
//上面的三个VirtualAddress是RVA, 就是楼主所说的: "(导入表的)在文件中的偏移地址"
// RVA当然要加上 基地址 , 才是在 映像后的实际地址
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
接上面:
/**
*@return 返回FilePos // (即使用: OpenFile.ReadFile)
*/
ULONG RVAToFilePos(
PIMAGE_SECTION_HEADER pSecHdr,
ULONG uSecNum ,
ULONG RVA
)
{
ULONG FilePos = 0;
ULONG i = 0;
for (i = 0; i < uSecNum; i++ )
{
if (RVA >= pSecHdr[i].VirtualAddress &&
RVA < pSecHdr[i].VirtualAddress + pe->pSecHdr[i].SizeOfRawData)
{
FilePos = RVA - pSecHdr[i].VirtualAddress + pSecHdr[i].PointerToRawData;
break;
}
}
return FilePos;
}
/**
*@brief FilePos到RVA的转换
*@return 返回RVA
*/
ULONG FilePosToRVA(
PIMAGE_SECTION_HEADER pSecHdr,
ULONG uSecNum ,
ULONG FilePos)
{
ULONG RVA = 0;
ULONG i = 0;
for (i = 0; i < uSecNum; i++ )
{
if (FilePos >= pSecHdr[i].PointerToRawData &&
FilePos < pSecHdr[i].PointerToRawData + pSecHdr[i].SizeOfRawData)
{
RVA = FilePos - pSecHdr[i].PointerToRawData + pSecHdr[i].VirtualAddress;
break;
}
}
Exit0:
return RVA;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
因为在PE文件静态分析时,偏移是相对于SEEK_SET(0)开始的,但是跑起来后,在虚拟内存中分配到的地址就不是从0开始了,而是基地址+偏移
|
|
|