关于ImageRvaToVa与SEC_IMAGE的一些东东

来源:互联网 发布:易语言编程学习 编辑:程序博客网 时间:2024/04/30 06:26
hMapping=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);

第三个参数或上了SEC_IMAGE,指定该属性相当于告诉系统要映射文件的映像并给页面设置相应的保护属性,具体见核心编程P456。我在写PE加载器的时候发现该参数与ImageRvaToVa函数有冲突!!!!具体ImageRvaToVa是怎么实现的微软没公开,大体逆了一下

76C67554 > 8BFF mov edi, edi76C67556 55 push ebp76C67557 8BEC mov ebp, esp76C67559 56 push esi ;保存ESI76C6755A 8B75 14 mov esi, dword ptr [ebp+14] ;将区段结构指针放入ESI76C6755D 85F6 test esi, esi ;如果ESI是否为076C6755F 57 push edi ;保存EDI76C67560 8B7D 10 mov edi, dword ptr [ebp+10] ;EDI=要转换值76C67563 74 16 je short 76C6757B ;ESI为0,直接转换76C67565 8B0E mov ecx, dword ptr [esi] ;不为空,将结构地址放入ECX76C67567 85C9 test ecx, ecx ;ECX为空直接转换76C67569 74 10 je short 76C6757B76C6756B 8B41 0C mov eax, dword ptr [ecx+C] 76C6756E 3BF8 cmp edi, eax76C67570 72 09 jb short 76C6757B76C67572 8B51 10 mov edx, dword ptr [ecx+10]76C67575 03D0 add edx, eax76C67577 3BFA cmp edi, edx76C67579 72 0E jb short 76C6758976C6757B 57 push edi ;要转换值76C6757C FF75 0C push dword ptr [ebp+C] ;BASE基地址76C6757F FF75 08 push dword ptr [ebp+8] ;NT结构指针76C67582 E8 8AFFFFFF call ImageRvaToSection76C67587 8BC8 mov ecx, eax76C67589 85C9 test ecx, ecx ;如果为0就跳出去76C6758B 74 13 je short 76C675A076C6758D 85F6 test esi, esi76C6758F 74 02 je short 76C6759376C67591 890E mov dword ptr [esi], ecx ;保存区段地址76C67593 8B41 14 mov eax, dword ptr [ecx+14] ;EAX=物理地址76C67596 2B41 0C sub eax, dword ptr [ecx+C] ;EAX=物理地址-虚拟地址76C67599 0345 0C add eax, dword ptr [ebp+C] ;EAX=EAX+基地址BASE76C6759C 03C7 add eax, edi ;EAX=EAX+要转换的值76C6759E EB 02 jmp short 76C675A276C675A0 33C0 xor eax, eax76C675A2 5F pop edi76C675A3 5E pop esi76C675A4 5D pop ebp76C675A5 C2 1000 retn 10ImageRvaToSection如下://------------------------------------------------------------------------------------76C67511 > 8BFF mov edi, edi76C67513 55 push ebp76C67514 8BEC mov ebp, esp76C67516 8B4D 08 mov ecx, dword ptr [ebp+8] ;NT结构地址76C67519 0FB741 14 movzx eax, word ptr [ecx+14] ;EAX=SizeOfOptionalHeader76C6751D 8D4408 18 lea eax, dword ptr [eax+ecx+18] ;EAX=区段开始地址76C67521 0FB749 06 movzx ecx, word ptr [ecx+6] ;获得区段总数为676C67525 56 push esi76C67526 33F6 xor esi, esi76C67528 85C9 test ecx, ecx 76C6752A 57 push edi76C6752B 76 1A jbe short 76C67547 ;如果区段数小于等于0,那么就跳出去76C6752D 8B50 0C mov edx, dword ptr [eax+C] ;EDX=区段虚拟地址76C67530 3955 10 cmp dword ptr [ebp+10], edx ;与RVA比较如果大于就跳76C67533 72 0A jb short 76C6753F76C67535 8B78 10 mov edi, dword ptr [eax+10] ;不大于,将物理区段大小放入EDI76C67538 03FA add edi, edx ;EDI=物理区段大小+虚拟区段地址76C6753A 397D 10 cmp dword ptr [ebp+10], edi ;EDI是否大于RVA值,如果大于就跳出去76C6753D 72 0A jb short 76C6754976C6753F 83C0 28 add eax, 28 ;不大于计算下一区段76C67542 46 inc esi76C67543 3BF1 cmp esi, ecx76C67545 ^ 72 E6 jb short 76C6752D76C67547 33C0 xor eax, eax76C67549 5F pop edi76C6754A 5E pop esi76C6754B 5D pop ebp76C6754C C2 0C00 retn 0C


感觉应该是因为ImageRvaToVa会读取段的一些信息,但是SEC_IMAGE在系统把文件映射到进程地址空间中得时候会根据区段的情况设置不同的属性,所以就对该函数产生了影响。

但是VA不就等于RVA+ImageBase呀,这破函数干嘛还要对区段进行操作?


晕。。。今天又看了下明白了,微软提供的这个函数是可以对mRVA(内存节偏移,相对于区段起始地址的偏移)来计算的,但是PE文件哪个字段提供的是mRva呢?