zoukankan      html  css  js  c++  java
  • Windows代码,添加一个节,以及RVA跟FOA互相转化,以及内存文件对齐代码.

    /*
    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;
    
    }
    
    
    
  • 相关阅读:
    第七周作业
    第六周作业
    第五周作业
    第四周作业
    第三周作业
    第二周作业
    求最大值及下标
    查找整数
    抓老鼠
    第五周作业
  • 原文地址:https://www.cnblogs.com/iBinary/p/10749313.html
Copyright © 2011-2022 走看看