从内存偏移转换到文件偏移

/************************************

  • 函数: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)
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值