吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8867|回复: 9
收起左侧

[原创] PE 重定位表

  [复制链接]
朱朱你堕落了 发表于 2016-12-6 16:00
本帖最后由 hahacker 于 2016-12-6 16:04 编辑

网上的代码是错的,书上的解释是错的。一直不明白。后来看了看雪上有大牛的文章:也谈PE重定位表,这个文章是对的,重定位表有多少个,就是多少个,根本就没有所谓的:
直至某个块首结构的VirtualAddress为 0,表明重定位表结束。

网上的代码也是按这个思路这些写的,当然也是错的。
如某DLL,loadpe显示最后一个重定位块是:00025000
1_1.png

打开对应的十六进制模式为:
1.png

这已经是最后一个重定位块了,下面的00区域已经不是了,所以网上的:最后一个重定块的virtualaddress为零,是判断结束的条件,的确是错的,还好有大牛发文章指出来。

真的好久不写代码,已经不会写了,思路僵硬,想了半天,折腾了半天,终于算是搞出来了一段,测试没有问题。高手求放过。

[C++] 纯文本查看 复制代码
void CchongdingweiDlg::OnBnClickedBtnOpenfile()
{
        //IDC_EDIT_FILEPATH

        CString strFilePath;
        CFileDialog fileDlg(TRUE);
        if (fileDlg.DoModal() == IDOK) 
        {
                strFilePath = fileDlg.GetPathName();
                SetDlgItemText(IDC_EDIT_FILEPATH, strFilePath);
        }

        if (strFilePath.IsEmpty())
                return;


        hFile = CreateFile(strFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
                return;



        HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, 0);
        if (hMap == NULL)
        {
                CloseHandle(hMap);
                MessageBox("创建文件映像失败");

                return;
        }


        LPVOID pMapData;
        pMapData = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
        if (pMapData == NULL)
        {
                CloseHandle(hMap);
                MessageBox("映像数据为空!");
                return;
        }

        PIMAGE_DOS_HEADER pImageDosHeader = NULL;
        pImageDosHeader = (PIMAGE_DOS_HEADER)pMapData;

        PIMAGE_NT_HEADERS pImageNtHeaders;
        pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pMapData + pImageDosHeader->e_lfanew);
        if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
        {
                MessageBox("这不是一个pe文件");
                return;
        }


        DWORD dwRelocRva = 0;
        DWORD dwRelocSize = 0;

        dwRelocRva = pImageNtHeaders->OptionalHeader.DataDirectory[5].VirtualAddress;
        dwRelocSize = pImageNtHeaders->OptionalHeader.DataDirectory[5].Size;


        CString str;
        str.Format("rva: 0x%08x, size: 0x%08x", dwRelocRva, dwRelocSize);
        MessageBox(str);
        
        
        DWORD dwOffset = 0;

        CString strSectionName;
        dwOffset = RvaToOffset(pImageNtHeaders, dwRelocRva, strSectionName);
        str.Format("section: %s,offset: 0x%08x", strSectionName, dwOffset);

        MessageBox(str);

        DWORD SizeOfBlock = 0;
        DWORD sum = 0;
        int index = 0;
        do 
        {
                index++;

                PIMAGE_BASE_RELOCATION pImageBaseRelocation;
                pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pMapData + dwOffset + sum);

                DWORD VirtualAddress = pImageBaseRelocation->VirtualAddress;
                CString strSectionName;
                RvaToOffset(pImageNtHeaders, VirtualAddress, strSectionName);

                str.Format("项数:%d, 所属区段:%s, rva: 0x%08x", index, strSectionName, VirtualAddress);
                OutputDebugString(str);

                SizeOfBlock = pImageBaseRelocation->SizeOfBlock;

                sum += SizeOfBlock;

                dwRelocSize -= SizeOfBlock;

        } while (dwRelocSize);



        CloseHandle(hMap);
        CloseHandle(hFile);

}

DWORD CchongdingweiDlg::RvaToOffset(PIMAGE_NT_HEADERS pImageNtHeaders, DWORD dwRva, CString & strSectionName)
{
        DWORD dwOffset = 0;

        int NumberOfSections = 0;
        NumberOfSections = pImageNtHeaders->FileHeader.NumberOfSections;
        PIMAGE_SECTION_HEADER pImageSectionHeader;
        pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
        for (int i = 0; i < NumberOfSections; i++)
        {
                if ((dwRva >= pImageSectionHeader->VirtualAddress) && (dwRva < pImageSectionHeader->VirtualAddress + pImageSectionHeader->SizeOfRawData ))
                {
                        dwOffset = dwRva - (pImageSectionHeader->VirtualAddress - pImageSectionHeader->PointerToRawData);

                        strSectionName = pImageSectionHeader->Name;
                        break;
                }
                pImageSectionHeader++;
        }


        return dwOffset;
}


这样和LoadPE的结果是一样的。
3.png

为方便后来人学习,把这个dll上传上来, 重定位测试DLL.rar (22.6 KB, 下载次数: 44)


免费评分

参与人数 8威望 +1 热心值 +8 收起 理由
whdfog + 1 鼓励转贴优秀软件安全工具和文档!
343424993 + 1 用心讨论,共获提升!
Hmily + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
KaQqi + 1 已答复!
sjclch + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
月华星祈 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
大大怪 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
guan1021 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

caroot1996 发表于 2016-12-6 17:38
谢谢你的教程~~
風走過的路 发表于 2016-12-7 20:27
墨香青瓷 发表于 2016-12-11 07:56
343424993 发表于 2016-12-11 19:27
厉害        膜拜您
头像被屏蔽
sstm 发表于 2016-12-23 12:20
提示: 作者被禁止或删除 内容自动屏蔽
www52pojiecn 发表于 2017-2-6 18:05
赞,谢谢
_默默_ 发表于 2019-4-27 08:50
我咋觉得没头没尾的
ok318 发表于 2019-4-28 17:00
看不懂哦,不过还是感谢分享!
洞见未来 发表于 2019-10-21 14:13
谢谢哈,新人来学习下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 16:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表