Windows代码,添加一个节,以及RVA跟FOA互相转化,以及内存文件对齐代码.
2023-09-27 14:21:04 时间
/*
1.修改文件头节个数 +1
2.修改ImageBase
3.遍历节表,拷贝最后一个节表到下面
4.修改节的虚拟大小(节表.virtualSize)
5.修改节的虚拟地址(RVA 节表.virtualAddress) 内存对齐( 上一个节表.virtualAddress + 上一个节表.virtualSize);
6.修改节的文件偏移位置,以及文件大小
*/
/*
函数作用: RVA转化为FOA
参数: 传入RVA虚拟地址的值,返回FOA文件偏移.
内部使用: g_szBuffer是文件映射的首地址.
*/
DWORD RetRvaToFoA(DWORD RvaValue)
{
int RetRvaValue = 0;
if (RvaValue > pOptHead->ImageBase)
{
RetRvaValue = RvaValue - pOptHead->ImageBase;
}
//定位节表位置,遍历节表.判断是否在节表内.
PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(g_szBuffer); //g_szBuffer是文件映射的首地址.
PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)g_szBuffer + pDosHead->e_lfanew);
//定位节表.
PIMAGE_SECTION_HEADER SectionTableAddress = IMAGE_FIRST_SECTION(pNtHead);//获得了节表的首地址
for (int i = 0; i < pNtHead->FileHeader.NumberOfSections; i++)
{
if (RetRvaValue >= SectionTableAddress[i].VirtualAddress &&
RetRvaValue < (SectionTableAddress[i].VirtualAddress + SectionTableAddress[i].SizeOfRawData))
{
//落在这个节中.
RetRvaValue = RetRvaValue - SectionTableAddress[i].VirtualAddress; // 文件偏移 -文件偏移首地址 = 偏移. 偏移加上自己的VirtuallAddress 就是在内存中的RVA
RetRvaValue = RetRvaValue + SectionTableAddress[i].PointerToRawData;
break;
}
}
return RetRvaValue; //返回FOA在内存中的RVA偏移.
}
/*
函数作用: 填写FOA值,转换为RVA
*/
DWORD RetFoAtoRva(DWORD FoAvalue)
{
int RetFoaValue = 0;
//定位节表位置,遍历节表.判断是否在节表内.
PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(g_szBuffer);
PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)g_szBuffer + pDosHead->e_lfanew);
//定位节表.
PIMAGE_SECTION_HEADER SectionTableAddress = IMAGE_FIRST_SECTION(pNtHead);//获得了节表的首地址
for (int i = 0; i < pNtHead->FileHeader.NumberOfSections; i++)
{
if (FoAvalue >= SectionTableAddress[i].PointerToRawData && FoAvalue < (SectionTableAddress[i].PointerToRawData + SectionTableAddress[i].SizeOfRawData))
{
//落在这个节中.
RetFoaValue = FoAvalue - SectionTableAddress[i].PointerToRawData; // 文件偏移 -文件偏移首地址 = 偏移. 偏移加上自己的VirtuallAddress 就是在内存中的RVA
RetFoaValue = RetFoaValue + SectionTableAddress[i].VirtualAddress;
break;
}
}
return RetFoaValue; //返回FOA在内存中的RVA偏移.
}
// 按照内存对齐,以及文件对齐. 第一种方式
//传入PE的原始内存对齐值,然后传入你的要进行对齐的值.
例子:
RetSectionAlignment(pOptHead.FileAlignment, pSection.virtualsize + pSection.virtualAddress);//返回节表虚拟大小+虚拟地址,按照内存对齐之后的值.
int RetSectionAlignment(DWORD Alignment, DWORD sizeOfImage)
{
//if (Alignment <=0)
//{
// AfxMessageBox(_T("计算内存对其值出错.请检查"));
// return 0;
//}
//while ((sizeOfImage % Alignment) != 0) //当不等于0就说明不是对齐.
//{
//
// sizeOfImage = sizeOfImage + 0x1000;
//}
int ret = 0;
int result = 0;
result = sizeOfImage % Alignment;
if (0 != result)
{
ret = ((sizeOfImage / Alignment) + 1) * Alignment;
}
else
{
ret = sizeOfImage;
}
return ret;
}
int RetFileAlignment(DWORD Alignment, DWORD Value)
{
if (Alignment <= 0)
{
OutputDebugString(TEXT("计算文件对其值出错.请检查"));
return 0;
}
//while ((Value % Alignment) != 0) //当不等于0就说明不是对齐.
//{
// Value = Value + Alignment;
//}
//return Value;
int ret = 0;
int result = 0;
result = Value % Alignment;
if (0 != result)
{
ret = ((Value / Alignment) + 1) * Alignment;
}
else
{
ret = Value;
}
return ret;
}
相关文章
- Windows核心编程 第十七章 -内存映射文件(下)
- Windows核心编程 第十七章 -内存映射文件(上)
- Windows工作集内存
- redis 安装启动及设置密码<windows>
- windows内存结构概述
- MFC中Windows窗口消息循环及多线程之间关系
- Windows系统中安装Python模块pip numpy matplotlib
- PLSQL Developer建表时注释(COMMENT)中文乱码的解决方案(Windows)
- 微软Build 2017:亮点很多但没有Windows更新
- Windows 程序启动性能优化(先载入EXE,后载入DLL,只取有限的代码载入内存,将CPU的IP指向程序的入口点)
- 如何打开Windows Server 2003 内存寻址扩展
- 【历史上的今天】2 月 17 日:谷歌收购 Blogger;英伟达创始人出生;微软发布 Windows 2000
- Windows 消息机制
- windows中怎么添加定时任务
- windows本地eclispe运行linux上hadoop的maperduce程序
- Windows平台Socket通信实例
- Windows进程通信——内存映射
- Windows下C++软件调试——检测内存泄露
- 诺基亚HERE地图套件重返Windows应用商店