不记得自己是怎么结识看雪了,但是真的从看雪学到了一些东西,虽然现在还是个菜逼惭愧,但是,我在努力,足矣。看了自己注册看雪的时间,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;
}
效果:
注释都写得很详细了,但是兼容性好像不好,只怪自己太弱,感兴趣的就将就着看吧,感觉自己有太多的东西要学了,马上就大三了,唉,希望在两年内自己的水平能有大的提高,感谢看雪。。。继续努力
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!