RVA是相對虛擬地址(Relative Virtual Address)的縮寫。RVA是當PE 文件被裝載到內存中后,某個數據位置相對於文件頭的偏移量。
例如:導入表的位置和大小可以從PE文件頭中IMAGE_OPTIONAL_HEADER32結構的數據目錄字段中獲取,對應的項目是DataDirectory字段的第2個IMAGE_DATA_DIRECTORY結構。從IMAGE_DATA_DIRECTORY結構的VirtualAddress字段得到的是導入表的RVA值,如果在內存中查找導入表,那么將RVA值加上PE文件裝入的基址就是實際的地址;如果在PE文件中查找導入表,需要將RVA轉換成File Offset(也就是數據在文件中的位置)。
RVA轉換到文件偏移地址的方法如下:
步驟一:循環掃描區塊表得出每個區塊在內存中的起始 RVA(根據IMAGE_SECTION_HEADER 中的VirtualAddress 字段),並根據區塊的大小(根據IMAGE_SECTION_HEADER 中的SizeOfRawData 字段)算出區塊的結束 RVA(兩者相加即可),最后判斷目標 RVA 是否落在該區塊內。
步驟二:通過步驟一定位了目標 RVA 處於具體的某個區塊中后,那么用目標 RVA 減去該區塊的起始 RVA ,這樣就能得到目標 RVA 相對於起始地址的偏移量 RVA2.
步驟三:在區塊表中獲取該區塊在文件中所處的偏移地址(根據IMAGE_SECTION_HEADER 中的PointerToRawData 字段), 將這個偏移值加上步驟二得到的 RVA2 值,就得到了真正的文件偏移地址。
既,已知某虛擬地址(如va)和某區塊的虛擬地址(text_va),虛擬地址在區塊中,同時還知道此區塊在文件中的位置(text_file_offset),解出此虛擬地址在文件中的具體位置。解:根據他們的偏移量相同(都是text_va - va)可知,答案為 text_file_offset + (text_va - va)。