首页 > 其他 > 详细

RVA TO RAW

时间:2021-03-12 22:13:29      阅读:29      评论:0      收藏:0      [点我收藏+]

  将映像的偏移地址转换为文件的偏移地址

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 
  6 typedef unsigned char BYTE;
  7 typedef unsigned short WORD;
  8 typedef unsigned int DWORD;
  9 
 10 #define IMAGE_SIZEOF_SHORT_NAME 8
 11 typedef struct _Section_Header
 12 {
 13     BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
 14     union
 15     {
 16         DWORD Physical_Address;
 17         DWORD Virtual_Size;
 18     }Misc;
 19     DWORD Virtual_Address;
 20     DWORD SizeOfRawData;
 21     DWORD PointerToRawData;
 22     DWORD PointerToRelocations;
 23     DWORD PointerToLinenumbers;
 24     WORD NumberOfRelocations;
 25     WORD NumberOfLinenumbers;
 26     DWORD Characteristics;
 27 
 28 }Section_Header;
 29 
 30 typedef struct _PE_Information
 31 {
 32     DWORD Dos_Header_e_lfanew;
 33     WORD File_Header_NumberOfSections;
 34     WORD File_Header_SizeOfOptionHeader;
 35     DWORD Option_Header_SectionAlignment;
 36     DWORD Option_Header_FileAlignment;
 37     DWORD Option_Header_SizeOfImage;
 38     DWORD Option_Header_SizeOfHeaders;
 39     DWORD File_Header_Offset;
 40     DWORD Optional_Header_Offset;
 41     DWORD Section_Header_Offset;
 42     Section_Header* PSection = (Section_Header*)malloc(sizeof(Section_Header) * File_Header_NumberOfSections);
 43 
 44 }PE_Information;
 45 
 46 typedef struct _Rva_And_Raw
 47 {
 48     DWORD Raw;
 49     DWORD Rva;
 50 }Rva_And_Raw;
 51 
 52 //读取文件长度
 53 int File_Lenth(FILE* p)
 54 {
 55     fseek(p, 0, SEEK_END);
 56     int len = ftell(p);
 57     fseek(p, 0, SEEK_SET);
 58     return len;
 59 }
 60 
 61 //生成文件缓冲区
 62 char* File_Read(const char* p, int& length)
 63 {
 64     //文件指针
 65     FILE* pf = fopen(p, "rb");
 66 
 67     //获得文件长度
 68     length = File_Lenth(pf);
 69 
 70     //分配FileBuffer的空间
 71     char* pt = (char*)malloc(sizeof(char) * length);
 72 
 73     //读入到空间中
 74     fread(pt, length, 1, pf);
 75 
 76     fclose(pf);
 77     return pt;
 78 }
 79 
 80 //读取PE_Header的数据
 81 void Get_PE_Information(PE_Information* PE,char* pt)
 82 {
 83     memcpy(&PE->Dos_Header_e_lfanew, pt + 0x3C, 4);
 84 
 85     PE->File_Header_Offset = PE->Dos_Header_e_lfanew + 4;
 86 
 87     memcpy(&PE->File_Header_NumberOfSections, pt + PE->File_Header_Offset + 2, 2);
 88 
 89     memcpy(&PE->File_Header_SizeOfOptionHeader, pt + PE->File_Header_Offset + 0x10, 2);
 90 
 91     PE->Optional_Header_Offset = PE->File_Header_Offset + 0x14;
 92 
 93     PE->Section_Header_Offset = PE->Optional_Header_Offset + PE->File_Header_SizeOfOptionHeader;
 94 
 95     memcpy(&PE->Option_Header_FileAlignment, pt + PE->Optional_Header_Offset + 0x24, 4);
 96 
 97     memcpy(&PE->Option_Header_SectionAlignment, pt + PE->Optional_Header_Offset + 0x20, 4);
 98 
 99     memcpy(&PE->Option_Header_SizeOfHeaders, pt + PE->Optional_Header_Offset + 0x3c, 4);
100 
101     memcpy(&PE->Option_Header_SizeOfImage, pt + PE->Optional_Header_Offset + 0x38, 4);
102 
103     memcpy(PE->PSection, pt + PE->Section_Header_Offset, sizeof(Section_Header) * PE->File_Header_NumberOfSections);
104 }
105 
106 //创建ImageBuffer
107 char* Image_Read(char* pt,PE_Information PE)
108 {
109     //申请ImageBuffer的空间
110     char* pi = (char*)malloc(PE.Option_Header_SizeOfImage);
111 
112     //填充0
113     memset(pi, 0, PE.Option_Header_SizeOfImage);
114 
115     //复制头
116     memcpy(pi, pt, PE.Option_Header_SizeOfHeaders);
117 
118     //复制节区
119     for (int i = 0; i < PE.File_Header_NumberOfSections; i++)
120     {
121         memcpy(pi + PE.PSection[i].Virtual_Address, pt + PE.PSection[i].PointerToRawData, PE.PSection[i].SizeOfRawData);
122     }
123 
124     return pi;
125 }
126 
127 void Rva_To_Raw(Rva_And_Raw* R,PE_Information PE)
128 {
129     int Pos;//在第几个节区
130 
131     for (int i = 0; i < PE.File_Header_NumberOfSections; i++)
132     {
133         if (R->Rva >= PE.PSection[i].Virtual_Address && R->Rva <= PE.PSection[i].Virtual_Address + PE.PSection[i].SizeOfRawData)
134             Pos = i;
135     }
136 
137     int offset = R->Rva - PE.PSection[Pos].Virtual_Address;
138 //rva相对于virtualaddress的偏移
139     
140     R->Raw = PE.PSection[Pos].PointerToRawData + offset;
141     
142 }
143 
144 int main()
145 {
146     int length;
147 
148     char* pt = File_Read("C:/Windows/System32/notepad.exe", length);
149     PE_Information PE;
150 
151     Get_PE_Information(&PE, pt);
152 
153     char* pi = Image_Read(pt, PE);
154 
155     Rva_And_Raw R;
156 
157     R.Rva = 0x1001;
158 
159     Rva_To_Raw(&R,PE);
160 
161     printf("Raw:%X\n", R.Raw);
162 
163     return 0;
164     
165 }

主要步骤是:

1.映像中地址,减去首地址,获得映像中的偏移RVA

2.与VirtualAddress和VirtualAddress+SizeOfRawData进行比较,确定地址所在的节区

3.将RVA和VirtualAddress相减,得到节区内的偏移大小

4.在文件中找到对应的节区,PointerToRawData+节区内的偏移就是RAW的值了

RVA TO RAW

原文:https://www.cnblogs.com/yanmo/p/14526129.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!