不懂这些怎么理解啊
//ntHeader->FileHeader.NumberOfSections //if(VirtualAddress>SectionHeader->VirtualAddress&&VirtualAddress <SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData) 

DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress; 
DWORD Offset=SectionHeader->PointerToRawData+AposRAV; 
return Offset; 
上面这些看不明白啊?????
全部源码:
#include "stdafx.h" 
#include <stdio.h> 
#include <windows.h> /*DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress) 

IMAGE_DOS_HEADER *dosHeader; 
IMAGE_NT_HEADERS *ntHeader; 
IMAGE_SECTION_HEADER *SectionHeader; 
int NumOfSections; 
dosHeader=(IMAGE_DOS_HEADER*)lpBase; 
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew); 
NumOfSections=ntHeader->FileHeader.NumberOfSections; 
for (int i=0;i <NumOfSections;i++) 

SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i; 
if(VirtualAddress>SectionHeader->VirtualAddress&&VirtualAddress <SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData) 

DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress; 
DWORD Offset=SectionHeader->PointerToRawData+AposRAV; 
return Offset; 


return 0; 

*/ 
int main(int argc, char* argv[]) 

//打开文件 
HANDLE hFile=CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
if(hFile==INVALID_HANDLE_VALUE) 

printf("CreateFile Failed\n"); 
return 0; 

//创建内存映射文件的内核对象 
HANDLE hMap=CreateFileMapping(hFile,NULL,PAGE_READONLY,NULL,NULL,NULL); 
if(hMap==INVALID_HANDLE_VALUE) 

printf("CreateFileMapping Failed\n"); 
return 0; 

//把文件映射入内存 
LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_READ,0,0,0); 
if(lpBase==NULL) 

printf("MapViewOfFile Failed\n"); 
return 0; 

IMAGE_DOS_HEADER *dosHeader; 
IMAGE_NT_HEADERS *ntHeader; 
IMAGE_IMPORT_BY_NAME *ImportName; 
//lpBase由MapViewOfFile函数返回 
dosHeader=(IMAGE_DOS_HEADER*)lpBase; 
//检测是否是有效的PE文件 
if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE) 

printf("This is not a windows file\n"); 
return 0; 

//定位到PE header 
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew); 
if(ntHeader->Signature!=IMAGE_NT_SIGNATURE) 

printf("This is not a win32 file\n"); 
return 0; 

//定位到导入表 
IMAGE_IMPORT_DESCRIPTOR *ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); 
while(ImportDec->FirstThunk) 

//得到DLL文件名 
char *pDllName=(char*)((BYTE*)lpBase+RVAToOffset(lpBase,ImportDec->Name)); 
printf("\nDLL文件名:%s\n",pDllName); 
//通过OriginalFirstThunk定位到PIMAGE_THUNK_DATA结构数组 
PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)((BYTE*)lpBase+RVAToOffset(lpBase,ImportDec->OriginalFirstThunk)); 
while(pThunk->u1.Function) 

//判断函数是用函数名导入的还是序号导入的 
if(pThunk->u1.Ordinal& IMAGE_ORDINAL_FLAG32) 

//输出序号 
printf("从此DLL模块导出的函数的序号:%x\n",pThunk->u1.Ordinal&0xFFFF); 

else 

//得到IMAGE_IMPORT_BY_NAME结构中的函数名 
ImportName=(IMAGE_IMPORT_BY_NAME*)((BYTE*)lpBase+RVAToOffset(lpBase,(DWORD)pThunk->u1.AddressOfData)); 
printf("从此DLL模块导出的函数的函数名:%s\n",ImportName->Name); 

pThunk++; 

ImportDec++; 

UnmapViewOfFile(lpBase); 
CloseHandle(hMap); 
CloseHandle(hFile); 
return 0; 

解决方案 »

  1.   

    我要的是他们之间的对应关系啊
    不懂这些怎么理解啊 
    //ntHeader->FileHeader.NumberOfSections //if(VirtualAddress>SectionHeader->VirtualAddress&&VirtualAddress <SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData) 

    DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress; 
    DWORD Offset=SectionHeader->PointerToRawData+AposRAV; 
    return Offset; 
    上面这些看不明白啊????? 
      

  2.   

    http://download.csdn.net/source/400882?
      

  3.   

    RVAToOffset从程序理解是把RVA转换成file offset,就是相对内存地址转换成文件偏移。。因为内存对齐和文件对齐是不一样的,所以要先算出相对便宜量再加上文件起始偏移算出文件实际偏移。DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress; 
    算出数据从结头开始的偏移
    DWORD Offset=SectionHeader->PointerToRawData+AposRAV; 
    结头偏移加上文件起始为止,那么offset就是文件偏移了。
      

  4.   

    内存对齐基本是4K。而文件对齐一般是200字节。
    假设一个PE有三个节。大小分别是3.5K,4K,5K。那么在内存里面的范围分别是:
    0~4K,4k~8k,8k~16K.
    而文件里面分别是:(为了好计算,假设硬盘上的PE文件按照1K对齐)
    0~4K,4~8K,8~13K.
    计算大概是这样的,可能有误,但算法是正确的,我也写过PE分析程序。
      

  5.   

    在前面的贴子当中我已经说了:
    SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i; 
    这代码是有问题的。后面的i不能使用一个单步增量,而是以sizeof(IMAGE_SECTION_HEADER)为步长的增量。对于PE格式,最好还是自己去了解,如果你一点也不了解的话,那么需要解释的问题太多了。
      

  6.   

    SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i; 
    -----------
    这个是没问题的,因为只有段数据才需要对齐,其他数据是不需要对齐的。当然,导入数据可能存放在edata或者text段,那么就需要按照段对齐去计算偏移了。总的来说,PE被映射到内存形成IMAGE和硬盘上的文件只有段的基址和大小不一样。