重新定位图像时如何前进到下一个内存块

how to advance to next block of memory when relocating image

本文关键字:何前进 下一个 内存 图像 新定位 定位      更新时间:2023-10-16

基本上我只想了解这是如何工作的我看到几个人使用current_base_relocation = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<uint64_t>(current_base_relocation) + current_base_relocation->SizeOfBlock);前进到第二个PIMAGE_BASE_LOCATION结构(或第二个重新定位块(,其中current_BASE_RELOCATION是指向PIMAGE_BBASE_RELOCATION的指针,基本上他添加了结构本身+另一个结构和条目大小,然后到达记忆,但有人能解释怎么做吗?例如,为了在映射pe文件时修复导入,我可以简单地使用++struct前进到内存中的第二个结构,以转到数组中的第三个结构,但我不明白这个是如何工作的。

您正在询问,在处理PE文件的IMAGE_DIRECTORY_ENTRY_BASERELOC目录时,为什么以下代码能够前进到下一个IMAGE_BAS_RELOCATION块:

current_base_relocation = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<uint64_t>(current_base_relocation) + current_base_relocation->SizeOfBlock);

IMAGE_BASE_LOCATION结构是块的标头,并不表示整个块。如果该结构确实代表了整个块,那么您可以使用current_base_relocation++来推进它。这就是为您提供size成员(current_base_relocation->SizeOfBlock(的原因。请注意,此大小包括标头结构(IMAGE_BASE_LOCATION(和后面的数组的大小(以字节为单位(。获得WORD大小的数据数组的指针计算将是经过IMAGE_BASE_location结构(标头(的第一个位置,并且可以这样获得:

word* pCurBlockEntry = (word*)((byte*)current_base_relocation + sizeof(*current_base_relocation))) 

现在回答你的问题。您提供的计算很可能是您在循环体中看到的,正如您所指出的,在它处理了第一个块之后。它以指向IMAGE_BASE_LOCATION结构的当前指针开始。然后指针被强制转换为一个64位无符号整数,这样当您向其添加字节大小(current_base_relocation->SizeOfBlock(时,您将按字节数而不是IMAGE_base_LOCATION结构数前进(这将是一个严重的错误(。任何无符号整数都可以。使用64位无符号整数是因为它与指针(对于64位代码(的整数大小相同,否则可以使用32位无符号整型。

例如,没有强制转换并假定current_base_relocation->SizeOfBlock恰好是32,指针算术指示指针将前进32个IMAGE_BASE_LOCATION结构,而不是32个字节到下一个块(在本例中,这将包括当前的IMAGE_BBASE_RELOCATION结构和12个16位条目的尾部数据数组(。事实上,我认为这些区块都是4k,至少根据PE规范

就我个人而言,当我想将指针提前一个字节大小时,我更喜欢在算术之前将其强制转换为字节*,而不是无符号整数。这只是防止在整数和指针之间切换,从而避免在编译为C++时出现编译器警告。然而,这两种方法都会起作用,并获得相同的结果,所以您的代码很好。

如果值适当地提前了正确的字节数,则结果将投射回IMAGE_BASE_LOCATION指针,因为它现在应该指向下一个块(下一个IMAGE_BBASE_RELOCATION结构(的开头。

顺便说一句,当你有一个current_base_relocation->SizeOfBlock为零。