前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Windows代码,添加一个节,以及RVA跟FOA互相转化,以及内存文件对齐代码.

Windows代码,添加一个节,以及RVA跟FOA互相转化,以及内存文件对齐代码.

作者头像
IBinary
发布2019-05-25 16:06:20
7240
发布2019-05-25 16:06:20
举报
文章被收录于专栏:逆向技术逆向技术

/ 1.修改文件头节个数 +1 2.修改ImageBase 3.遍历节表,拷贝最后一个节表到下面 4.修改节的虚拟大小(节表.virtualSize) 5.修改节的虚拟地址(RVA 节表.virtualAddress) 内存对齐( 上一个节表.virtualAddress + 上一个节表.virtualSize); 6.修改节的文件偏移位置,以及文件大小 /

/ 函数作用: RVA转化为FOA 参数: 传入RVA虚拟地址的值,返回FOA文件偏移. 内部使用: g_szBuffer是文件映射的首地址. /

代码语言:javascript
复制
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 /

代码语言:javascript
复制
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偏移.
}

// 按照内存对齐,以及文件对齐. 第一种方式

代码语言:javascript
复制
//传入PE的原始内存对齐值,然后传入你的要进行对齐的值.  
例子:

RetSectionAlignment(pOptHead.FileAlignment, pSection.virtualsize + pSection.virtualAddress);//返回节表虚拟大小+虚拟地址,按照内存对齐之后的值.

代码语言:javascript
复制
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;

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档