博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PE文件RV转FOA及FOA转RVA
阅读量:6718 次
发布时间:2019-06-25

本文共 2768 字,大约阅读时间需要 9 分钟。

/************************************************************************//*功能:虚拟内存相对地址和文件偏移的转换参数:stRVA:    虚拟内存相对偏移地址lpFileBuf: 文件起始地址返回:转换后的文件偏移地址*//************************************************************************/size_t RVAToOffset(size_t stRVA, PVOID lpFileBuf){    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;    size_t stPEHeadAddr = (size_t)lpFileBuf + pDos->e_lfanew;    PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;    //区段数    DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;    //内存对齐大小    DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment;    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);    //距离命中节的起始虚拟地址的偏移值。    DWORD  dwDiffer = 0;    for (DWORD i = 0; i < dwSectionCount; i++)    {        //模拟内存对齐机制        DWORD dwBlockCount = pSection[i].SizeOfRawData / dwMemoruAil;        dwBlockCount += pSection[i].SizeOfRawData%dwMemoruAil ? 1 : 0;        DWORD dwBeginVA = pSection[i].VirtualAddress;        DWORD dwEndVA = pSection[i].VirtualAddress + dwBlockCount * dwMemoruAil;        //如果stRVA在某个区段中        if (stRVA >= dwBeginVA && stRVA < dwEndVA)        {            dwDiffer = stRVA - dwBeginVA;            return pSection[i].PointerToRawData + dwDiffer;        }        else if (stRVA < dwBeginVA)//在文件头中直接返回        {            return stRVA;        }    }    return 0;}
/************************************************************************//*功能:文件偏移地址和虚拟地址的转换参数:stOffset:文件偏移地址lpFileBuf:虚拟内存起始地址返回:转换后的虚拟地址*//************************************************************************/size_t Offset2VA(size_t stOffset, PVOID lpFileBuf){    //获取DOS头    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;    //获取PE头    //e_lfanew:PE头相对于文件的偏移地址    size_t stPEHeadAddr = (size_t)lpFileBuf + pDos->e_lfanew;    PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;    //区段数    DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;    //映像地址    DWORD dwImageBase = pNT->OptionalHeader.ImageBase;    //区段头    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);    //相对大小    DWORD  dwDiffer = 0;    for (DWORD i = 0; i < dwSectionCount; i++)    {        //区段的起始地址和结束地址        DWORD dwBeginVA = pSection[i].PointerToRawData;        DWORD dwEndVA = pSection[i].PointerToRawData + pSection[i].SizeOfRawData;        //如果文件偏移地址在dwBeginVA和dwEndVA之间        if (stOffset >= dwBeginVA && stOffset < dwEndVA)        {            //相对大小            dwDiffer = stOffset - dwBeginVA;            //进程的起始地址 + 区段的相对地址 + 相对区段的大小            return dwImageBase + pSection[i].VirtualAddress + dwDiffer;        }        else if (stOffset < dwBeginVA)    //如果文件偏移地址不在区段中        {            return dwImageBase + stOffset;        }    }    return 0;}

 

转载于:https://www.cnblogs.com/wumac/p/5278853.html

你可能感兴趣的文章
java图形用户界面边界布局管理器
查看>>
java web 程序---注册页面密码验证
查看>>
Linux修改环境变量步骤
查看>>
PyQt4 / PyQt5
查看>>
使用vue开发输入型组件更好的一种解决方式(子组件向父组件传值,基于2.2.0)
查看>>
linux 服务器安装 nginx
查看>>
108. Convert Sorted Array to Binary Search Tree
查看>>
Android 学习开发笔记《Service 与 Thread 的区别 》
查看>>
grep:Binary file (standard input) matches
查看>>
云计算
查看>>
centos7.2下部署 python3
查看>>
Shell 编程(实例一)
查看>>
C++Primer笔记——文本查询程序(原创,未使用类)
查看>>
Matplotlib 知识点整理
查看>>
Django问题 TypeError: __init__() missing 1 required positional argument: 'on_delete'
查看>>
面向对象(上)之一
查看>>
Spring学习篇:AOP知识整理
查看>>
jq 获取各个元素的宽度高度的方法
查看>>
AJAX实现仿Google Suggest效果
查看>>
[ACM]A + B Problem (大数相加3种方法)
查看>>