首页
社区
课程
招聘
[原创]PE文件学习之地址转换器编写
发表于: 2015-5-26 12:43 6021

[原创]PE文件学习之地址转换器编写

2015-5-26 12:43
6021

不记得自己是怎么结识看雪了,但是真的从看雪学到了一些东西,虽然现在还是个菜逼惭愧,但是,我在努力,足矣。看了自己注册看雪的时间,2015-1-1.呵呵,从注册到现在,除了问个几个问题,其他大部分时间都是看客,都说看雪看客多,其实我感觉也不能怪什么,因为大部分人都是像我这种菜鸟,你让咱发啥技术文章,咱也不会啊。记得看雪老大还是谁说过,现在看雪严重断层,就是牛逼的人越牛逼他们发的技术文章新手往往不懂,不懂就越不懂(我乱说的,说的不对的地方请联系我改正)但是毕竟有很大一部分是新手(包括我),这里把我之前写的一个PE地址转换器贴出来,大家一起交流。大牛请忽略它。话说这种东西前辈们不知道发了几百千次了吧,呵呵。。。
源码:
#include<stdio.h>
#include<windows.h>
int main(int argv,char * argc[])
{
        //变量的定义
        BOOL ret=FALSE;  //判断变量
        HANDLE hFile;  //文件句柄
        HANDLE hMap;  //映像句柄
        LPVOID hBase;  //映像基址指针
        DWORD addr;  //地址
        int nSecNum;
        int i;
        DWORD dwVa=0;  //虚拟地址
        DWORD dwRva=0;  // 虚拟偏移
        DWORD dwFileOffset=0;  //文件偏移

        PIMAGE_DOS_HEADER hDos;  //DOS头指针
        PIMAGE_NT_HEADERS hNt;  //NT头指针
        PIMAGE_SECTION_HEADER hSection;  //节表指针

///////////////////////////////////////////////////////////////////////////////
//载入映像
/////////////////////////////////////////////////////////////////////////////////
        hFile=CreateFile(argc[1],GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  //打开文件
        if(hFile==INVALID_HANDLE_VALUE)
        {
                MessageBox(NULL,"打开文件失败","警告",1);
                return ret;
        }
        hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE | SEC_IMAGE,0,0,0);  //载入映像
        if(hMap==NULL)
        {
                MessageBox(NULL,"载入映像失败","警告",1);
                CloseHandle(hFile);  //关闭文件句柄
                return ret;
        }
        hBase=MapViewOfFile(hMap,FILE_MAP_READ | FILE_MAP_WRITE,0,0,0);  //hBase整个文件起始地址
        if(hBase==NULL)
        {
                MessageBox(NULL,"载入映像失败","警告",1);
                CloseHandle(hFile);  //关闭文件句柄
                CloseHandle(hMap);  //关闭映像句柄
                return ret;
        }

//////////////////////////////////////////////////////////////////////////////
//接下来判断是否为有效的PE文件        只用上面的hBase值                                                                                       
/////////////////////////////////////////////////////////////////////////////
        hDos=(PIMAGE_DOS_HEADER)hBase;  //指向DOS头
        if(hDos->e_magic!=IMAGE_DOS_SIGNATURE)  
        {
                MessageBox(NULL,"这不是有效的PE文件","警告",1);
                return ret;
        }
        hNt=(PIMAGE_NT_HEADERS)((DWORD)hBase+hDos->e_lfanew);  //指向NT头
        if(hNt->Signature!=IMAGE_NT_SIGNATURE)
        {
                MessageBox(NULL,"这不是有效的PE文件","警告",1);
                return ret;
        }
        hSection=(PIMAGE_SECTION_HEADER)((DWORD)&(hNt->OptionalHeader)+hNt->FileHeader.SizeOfOptionalHeader);  //指向节表头

/////////////////////////////////////////////////////////////////////////////////////////////////
        nSecNum=hNt->FileHeader.NumberOfSections;  //获取节区数
        for(i=0;i<nSecNum;i++)
        {
                printf("%s->VOffset:%08x  VSize:%08x  ROffset:%08x  RSize:%08x\n",hSection[i].Name,hSection[i].VirtualAddress,hSection[i].Misc.VirtualSize,hSection[i].PointerToRawData,hSection[i].SizeOfRawData);  //输出节区RVA
        }
        printf("-----------------------------------------------------------------------------\n");
        int temp;
        while(1)
        {
        printf("请选择转换类型:1.虚拟地址,2.相对虚拟地址,3.文件偏移:");
        scanf("%d",&temp);
        switch(temp)
        {
        case 1:
                {
                        printf("输入待转换虚拟地址:");
                        scanf("%08x",&addr);
                        //判断地址所在节区
                        for(i=0;i<nSecNum;i++)
                        {
                               
                               
                                if(addr>=(hNt->OptionalHeader.ImageBase)+hSection[i].VirtualAddress && addr<(hNt->OptionalHeader.ImageBase)+hSection[i].VirtualAddress+(hSection[i].Misc.VirtualSize/1000)*1000)
                                {
                                        dwVa=addr;
                                        dwRva=dwVa-hNt->OptionalHeader.ImageBase;
                                        dwFileOffset=hSection[i].PointerToRawData+(dwRva-hSection[i].VirtualAddress);  //文件偏移=文件基址+(RVA-虚拟基址)
                                        printf("虚拟地址是:%08x\t虚拟偏移是:%08x\t文件偏移是:%08x\n",dwVa,dwRva,dwFileOffset);
                               
                                }
                        }
                       
                        break;
                }
        case 2:
                {
                        printf("输入待转化相对虚拟地址:");
                        scanf("%x",&addr);
                        for(i=0;i<nSecNum;i++)
                        {
                                if(addr>=hSection[i].VirtualAddress && addr<=hSection[i].VirtualAddress+(hSection[i].Misc.VirtualSize/1000)*1000)
                                {
                                        dwVa=addr+hNt->OptionalHeader.ImageBase;
                                        dwRva=addr;
                                        dwFileOffset=hSection[i].PointerToRawData+(dwRva-hSection[i].VirtualAddress);  //文件偏移=文件基址+(RVA-虚拟基址)
                                        printf("虚拟地址是:%08x\t虚拟偏移是:%08x\t文件偏移是:%08x\n",dwVa,dwRva,dwFileOffset);
                                               

                                }
                        }
                        break;
                }
        case 3:
                {
                        printf("输入待转换文件偏移:");
                        scanf("%x",&addr);
                        for(i=0;i<nSecNum;i++)
                        {
                                if(addr>=hSection[i].PointerToRawData && addr<=hSection[i].PointerToRawData+hSection[i].SizeOfRawData)
                                {
                                        dwFileOffset=addr;
                                        dwRva=hSection[i].VirtualAddress+(dwFileOffset-hSection[i].PointerToRawData);
                                        dwVa=dwRva+hNt->OptionalHeader.ImageBase;
                                        printf("虚拟地址是:%08x\t虚拟偏移是:%08x\t文件偏移是:%08x\n",dwVa,dwRva,dwFileOffset);
                                }
                        }
                        break;
                }
        default:
                {
                        break;
                }
        }
        printf("\n");
        }
       

        printf("请按任意键退出...");
        if(getchar())
        {
        ret=TRUE;  //否则返回真
        }
        return ret;
}

效果:

注释都写得很详细了,但是兼容性好像不好,只怪自己太弱,感兴趣的就将就着看吧,感觉自己有太多的东西要学了,马上就大三了,唉,希望在两年内自己的水平能有大的提高,感谢看雪。。。继续努力


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (7)
雪    币: 21
活跃值: (78)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
原文见我的博客:http://www.netfairy.net/?post=104
2015-5-26 12:45
0
雪    币: 22
活跃值: (242)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
RVA转Offset
2015-5-26 12:57
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
才大二 加油!
2015-5-26 13:59
0
雪    币: 115
活跃值: (23)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
5
很厉害(⊙o⊙)哦
2015-5-26 15:07
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
加油,现在我C都忘完啦
2015-5-26 15:13
0
雪    币: 21
活跃值: (78)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
我就会点c语言,唉,打算学学c++和python
2015-5-26 15:46
0
雪    币: 21
活跃值: (78)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
哪里不对吗?
2015-5-26 15:47
0
游客
登录 | 注册 方可回帖
返回
//