在这一章中我们给出RVA转FOA程序的源代码:
代码我们就不一一解释了,自己看懂或者是自己编写出来会有更深的理解
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include "Function.h" int main(int argc, char** argv) { char* File_Buffer; char* Image_Buffer; //打开文件 File_Buffer=openfile(); //将File_Buffer转为Image_Buffer Image_Buffer=FileBufferToImageBuffer(File_Buffer); //RVA转FOA char* foa=NULL; char* address=NULL; printf("请输入需要转换的地址:"); scanf("%d",address); foa=RVATOFOA(File_Buffer,Image_Buffer,address); return 0; }
在这里给出函数说明文件Function.h:
//打开文件函数 //该函数完成将内存数据复制到File_Buffer char* openfile(){ FILE *fp=NULL; char* File_Buffer=NULL; //打开文件 if((fp=fopen("E:\\个人\\逆向\\练习.exe","rb"))==NULL){ printf("文件打开失败!\n"); }else{ printf("文件打开成功。\n"); } //计算文件大小 fseek(fp,0,SEEK_END); int length=ftell(fp); fseek(fp,0,SEEK_SET); //动态申请内存 File_Buffer=(char*)malloc(length); if(File_Buffer==NULL){ printf("FileBuffer内存申请失败!\n"); exit(0); }else{ printf("FileBuffer内存申请成功。\n"); } //将文件数据读取到File_Buffer if(fread(File_Buffer,1,length,fp)){ printf("文件读取到FileBuffer成功。\n"); }else{ printf("文件读取到FileBuffer失败!\n"); exit(0); } //关闭文件 if(fclose(fp)){ printf("文件关闭失败!\n"); }else{ printf("文件关闭成功。\n"); } return File_Buffer; } //将File_Buffer转到Image_Buffer函数 //该函数需要一个指针,指向File_Buffer //该函数返回一个指针,指向Image_Buffer char* FileBufferToImageBuffer(char* File_Buffer){ char *Image_Buffer=NULL; //定义PE头部结构 IMAGE_DOS_HEADER *pDosHeader=(IMAGE_DOS_HEADER*)File_Buffer; IMAGE_FILE_HEADER *pFileHeader=(IMAGE_FILE_HEADER*)(File_Buffer+pDosHeader->e_lfanew+4); IMAGE_OPTIONAL_HEADER *pOptionalHeader=(IMAGE_OPTIONAL_HEADER*)((char*)pFileHeader+20); IMAGE_SECTION_HEADER* pSectionHeader=(IMAGE_SECTION_HEADER*)((char*)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); //动态申请Image_Buffer内存 Image_Buffer=(char*)malloc(pOptionalHeader->SizeOfImage); if(Image_Buffer==NULL){ printf("ImageBuffer内存申请失败!\n"); }else{ printf("ImageBuffer内存申请成功。\n"); } //初始化申请的内存 int i; for(i=0;i<pOptionalHeader->SizeOfImage;i++){ *(Image_Buffer+i)=0; } //复制所有头 int j; for(j=0;j<pOptionalHeader->SizeOfHeaders;j++){ *(Image_Buffer+j)=*(File_Buffer+j); } //复制所有节到Image_Buffer中 int k,x; for(k=0;k<pFileHeader->NumberOfSections;k++){ for(x=0;x<pSectionHeader->SizeOfRawData;x++){ *(Image_Buffer+pSectionHeader->VirtualAddress+x)=*(File_Buffer+pSectionHeader->PointerToRawData+x); } pSectionHeader++; } return Image_Buffer; } //RVA转FOA函数 //该函数需要两个指针,一个指向File_Buffer另一个指向Image_buffer //该函数需要一个地址,指向要寻找的数据 //若转化成功,该函数返回一个地址,表示FOA,若转化失败,则返回NULL char* RVATOFOA(char* File_Buffer,char* Image_Buffer,char* address){ //定义PE头部结构体 IMAGE_DOS_HEADER* pDosHeader=(IMAGE_DOS_HEADER*)File_Buffer; IMAGE_FILE_HEADER* pFileHeader=(IMAGE_FILE_HEADER*)(File_Buffer+pDosHeader->e_lfanew+0x4); IMAGE_OPTIONAL_HEADER* pOptionalHeader=(IMAGE_OPTIONAL_HEADER*)((char*)pFileHeader+0x20); IMAGE_SECTION_HEADER* pSectionHeader=(IMAGE_SECTION_HEADER*)((char*)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); //地址转换 int i; for(i=0;i<pFileHeader->NumberOfSections;i++){ if(address>(pSectionHeader->VirtualAddress)&&address<(pSectionHeader->VirtualAddress+pSectionHeader->Misc.VirtualSize)){ break; } pSectionHeader++; } if(i==pFileHeader->NumberOfSections){ printf("该地址不在任何一个节中!\n"); }else{ printf("该地址在第%d个节中。\n",i-1); } int pianyi=0; pianyi=address-((int)Image_Buffer+pSectionHeader->VirtualAddress); char* ret=(File_Buffer+pianyi); return ret; }
代码中有许多可以优化的地方或者是可能有不对的地方,希望大家及时指出,我会非常虚心地学习,希望我们共同进步!