/************************************
-
函数:RVAToFOA
-
说明:从内存偏移转换到文件偏移
-
***********************************/
BOOL PE::RVAToFOA(DWORD RVA,DWORD &FOA,BOOL IsEnableLog)
{
/- 计算公式:
-
1. 先计算出此RVA 属于那个节 2. 该节与文件节的差值k 3. RVA - 差 = FOA
*/
if (IsEnableLog)
{
TRACEEX("\n----RVA信息----\n");
}DWORD min = m_vec_section.begin()->second->VirtualAddress;
DWORD max = (m_vec_section.end()-1) ->second->VirtualAddress;
string max_name = (char*)(m_vec_section.end() - 1)->second->Name;
DWORD max_size = (m_vec_section.end() - 1)->second->Misc.VirtualSize;
DWORD max_foa = (m_vec_section.end() - 1)->second->PointerToRawData;
if (RVA < min || RVA > max)
{
if (IsEnableLog)
{
TRACEEX(“RVA范围错误!\n”);
TRACEEX("-------------\n\n");
}
return FALSE;
}
else
{
//这里直接判断掉是否属于最后一个节,方便后面vector的遍历了.
if (RVA >= max && RVA <= (max+ max_size))
{//根据公式计算 int k = max - max_foa; FOA = RVA - k; if (IsEnableLog) { TRACEEX("隶属于(%s)节,RVA=0x%08X,FOA=0x%08X\n", max_name.c_str(), max, max_foa); TRACEEX("当前文件偏移:[0x%08X]\n", FOA); TRACEEX("-------------\n\n"); } return TRUE; }
}
//遍历属于哪个节,因为最后一个节已经判断过了,所以可以直接排除掉最后一个节.
string BelongToSectionName;
int Currentflag;
for (vector<pair<string, PIMAGE_SECTION_HEADER>>::iterator iter = m_vec_section.begin(); iter != m_vec_section.end()-1; iter++)
{
DWORD address = iter->second->VirtualAddress;
DWORD address_foa = iter->second->PointerToRawData;
if (RVA >= address && RVA < (iter+1)->second->VirtualAddress)
{
//根据公式计算
int k = address - address_foa;
FOA = RVA - k;
if (IsEnableLog)
{
TRACEEX(“隶属于(%s)节,RVA=0x%08X,FOA=0x%08X\n”, iter->second->Name, address, address_foa);
TRACEEX(“当前文件偏移:[0x%08X]\n”, FOA);
TRACEEX("-------------\n\n");
}
return TRUE;
}
}
return TRUE;
//接下来进行判断 属于哪个节. 输入的RVA:0x000b447c
//(.text)节 RVA : 0x00001000, FOA : 0x00000600, 差值(K) = 0x00000A00(2560)
//(.data)节 RVA : 0x0009E000, FOA : 0x0009D600, 差值(K) = 0x00000A00(2560)
//(.rdata)节RVA : 0x000A0000, FOA : 0x0009F400, 差值(K) = 0x00000C00(3072)
//(.bss)节 RVA : 0x000B3000, FOA : 0x00000000, 差值(K) = 0x000B3000(733184)
//(.edata)节RVA : 0x000B4000, FOA : 0x000B1E00, 差值(K) = 0x00002200(8704)
//(.idata)节RVA : 0x000B7000, FOA : 0x000B4200, 差值(K) = 0x00002E00(11776)
//(.CRT)节 RVA : 0x000B8000, FOA : 0x000B5000, 差值(K) = 0x00003000(12288)
//(.tls)节 RVA : 0x000B9000, FOA : 0x000B5200, 差值(K) = 0x00003E00(15872)
//(.rsrc)节 RVA : 0x000BA000, FOA : 0x000B5400, 差值(K) = 0x00004C00(19456)
//(.reloc)节RVA : 0x000BB000, FOA : 0x000B5A00, 差值(K) = 0x00005600(22016)
//(/ 4)节 RVA : 0x000BF000, FOA : 0x000B9000, 差值(K) = 0x00006000(24576)
//(/ 19)节 RVA : 0x000C0000, FOA : 0x000B9400, 差值(K) = 0x00006C00(27648)
//(/ 31)节 RVA : 0x000CA000, FOA : 0x000C2E00, 差值(K) = 0x00007200(29184)
//(/ 45)节 RVA : 0x000CC000, FOA : 0x000C4A00, 差值(K) = 0x00007600(30208)
//(/ 57)节 RVA : 0x000CE000, FOA : 0x000C6600, 差值(K) = 0x00007A00(31232)
//(/ 70)节 RVA : 0x000CF000, FOA : 0x000C7000, 差值(K) = 0x00008000(32768)
//(/ 81)节 RVA : 0x000D0000, FOA : 0x000C7400, 差值(K) = 0x00008C00(35840)
//(/ 92)节 RVA : 0x000D2000, FOA : 0x000C9200, 差值(K) = 0x00008E00(36352)
}