PE重定位表学习笔记

重定位表结构

typedef struct _IMAGE_BASE_RELOCATION {
DWORD   VirtualAddress;
DWORD   SizeOfBlock;
} IMAGE_BASE_RELOCATION;

typedef struct _IMAGE_BASE_RELOCATION {  
    DWORD   VirtualAddress;  
    DWORD   SizeOfBlock;  
    WORD    TypeOffset[];  
} IMAGE_BASE_RELOCATION;  
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;  

注意点

  • VirtualAddress是这一组重定位数据的开始的RVA地址。各重定位项的地址加上这个值才是该重定位项完整的RAV地址。

  • SizeOfBlock是当前重定位表结构的大小。因为DWORD VirtualAddress和DWORD SizeOfBlock,可以看出它们的大小固定的4个字节,因此减去8,则是TypeOffset大小。再观察WORD TypeOffset发现是每个是2字节。所以用TypeOffset/2就可以得到TypeOffset在当前重定位表结构的数量。

  • TypeOffset是一个数组,大小两个字节(16位)。它又分为高4位和低12位。高4位是重定位表的类型(值0说明不要修改、值3说明重定位指向的地址需要修改、值10说明重定位指向的地址需要修改<出现在64位的PE中>),低12位是重定位的地址。

重定位表的结构和理解见流程图
这里写图片描述

重定位表打印的部分核心代码(API)

BOOL Add_list_Relocation_View_Items(HWND hListDescriport,HWND hDlg)
{
    LVITEM lvI;
    DWORD index=0;
    char string[32];
    ZeroMemory(string,32);
    ZeroMemory(&lvI,sizeof(lvI));
    lvI.mask=LVIF_TEXT;//|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE

    //定位到重定位表结构
    PIMAGE_BASE_RELOCATION pIMAGE_BASE_RELOCATION=NULL;
    pIMAGE_BASE_RELOCATION = (PIMAGE_BASE_RELOCATION)
        ((DWORD)lpMemory + RVAToFOA(lpMemory, pOptionHeader->DataDirectory[5].VirtualAddress)); 



    if(!pIMAGE_BASE_RELOCATION)
    {
        MessageBox(hDlg,"can't get IMAGE_BASE_RELOCATION ","IMPORTD",MB_OK);
        return FALSE;
    }

    int i;
    int j=1;
    while (pIMAGE_BASE_RELOCATION->SizeOfBlock&&pIMAGE_BASE_RELOCATION->VirtualAddress)
    {
        //计算需要修改的地址的个数
        int uRelocTableSize=(pIMAGE_BASE_RELOCATION->SizeOfBlock-8)/2;
    //找出TypeOffset的首地址指针
        PWORD pTypeOffset=(PWORD)((char*)pIMAGE_BASE_RELOCATION+8);
        int n1=1;
        //循环遍历
        for (i=0;i<uRelocTableSize;i++)
        {//判断高4位是否等于3
            int Type=(*(pTypeOffset+i))>>12;
            if (Type==3)
            {
                ZeroMemory(&lvI,sizeof(lvI));
                lvI.iItem=index;
                lvI.mask=LVIF_TEXT;

                lvI.iSubItem=0;
                ZeroMemory(string,32);
                wsprintf(string, "%08d", j); 
                lvI.pszText=TEXT(string);
                ListView_InsertItem(hListDescriport,&lvI);

                lvI.iSubItem=1;
                ZeroMemory(string,32);
                wsprintf(string, "%03d",n1); 
                lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=2;
                ZeroMemory(string,32);
                wsprintf(string, "%08X",(DWORD)(pTypeOffset+i)-(DWORD)lpMemory); //
                lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=3;
                lvI.pszText=TEXT("要");
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=4;
                ZeroMemory(string,32);
            //  wsprintf(string, "%08X", 
            //      (DWORD)(*(pTypeOffset+i)&0x0fff+pIMAGE_BASE_RELOCATION->VirtualAddress)); 
                //上面备注代码错误原因*(pTypeOffset+i)&0x0fff和pIMAGE_BASE_RELOCATION->VirtualAddress占的字节大小不一致
                wsprintf(string, "%08X", 
                    (DWORD)(*(pTypeOffset+i)&0x0fff)+pIMAGE_BASE_RELOCATION->VirtualAddress); 
                    lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=5;
                ZeroMemory(string,32);
                wsprintf(string, "%08X",RVAToFOA(lpMemory, 
                    (DWORD)(*(pTypeOffset+i)&0x0fff)+pIMAGE_BASE_RELOCATION->VirtualAddress)); 
                lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=6;
                ZeroMemory(string,32);
                wsprintf(string, "%08X",*(PDWORD)((DWORD)lpMemory + 
                    RVAToFOA(lpMemory,(DWORD)(*(pTypeOffset+i)&0x0fff)+pIMAGE_BASE_RELOCATION->VirtualAddress))); 
                lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

            }
            else
            {
                ZeroMemory(&lvI,sizeof(lvI));
                lvI.iItem=index;
                lvI.mask=LVIF_TEXT;

                lvI.iSubItem=0;
                ZeroMemory(string,32);
                wsprintf(string, "%08d", j); 
                lvI.pszText=TEXT(string);
                ListView_InsertItem(hListDescriport,&lvI);

                lvI.iSubItem=1;
                ZeroMemory(string,32);
                wsprintf(string, "%03d",n1); 
                lvI.pszText=TEXT(string);
                ListView_InsertItem(hListDescriport,&lvI);

                lvI.iSubItem=2;
                ZeroMemory(string,32);
                wsprintf(string, "%08X", (DWORD)(pTypeOffset+i)-(DWORD)lpMemory); 
                lvI.pszText=TEXT(string);
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=3;
                lvI.pszText=TEXT("不要");
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=4;
                ZeroMemory(string,32);
                lvI.pszText=TEXT("-");
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=5;
                ZeroMemory(string,32);
                lvI.pszText=TEXT("-");
                ListView_SetItem(hListDescriport,&lvI);

                lvI.iSubItem=6;
                ZeroMemory(string,32);
            lvI.pszText=TEXT("-");
                ListView_SetItem(hListDescriport,&lvI);
            }
            n1++;
            index++;
        }
        //进行下一个重定位表的修改
        pIMAGE_BASE_RELOCATION=(IMAGE_BASE_RELOCATION *)((DWORD)pIMAGE_BASE_RELOCATION+pIMAGE_BASE_RELOCATION->SizeOfBlock);
    j++;
    }

    return 0;
}


VOID Init_Relocation_listView(HWND hDlg)
{
    LV_COLUMN lv;
    HWND hListDescriport;

    //初始化
    memset(&lv,0,sizeof(LV_COLUMN));
    //获取IDC_LIST_DESCRIPTOR句柄
    hListDescriport=GetDlgItem(hDlg,IDC_LIST_Relocation);
    //设置整行选中
    SendMessage(hListDescriport,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);

    //第一列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("条目块");            //列标题
    lv.cx=100;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,0,(DWORD)&lv);


    //第二列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("编号");            //列标题
    lv.cx=50;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,1,(DWORD)&lv);

    //第三列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("TypeOffset(FOA)");            //列标题
    lv.cx=120;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,2,(DWORD)&lv);

    //第四列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("是否要修改");            //列标题
    lv.cx=100;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,3,(DWORD)&lv);

    //第五列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("修改地址(RVA))");            //列标题
    lv.cx=120;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,4,(DWORD)&lv);

    //第五列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("修改地址(FOA))");            //列标题
    lv.cx=120;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,5,(DWORD)&lv);

    //第六列

    lv.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
    lv.pszText=TEXT("修改地址的具体值");            //列标题
    lv.cx=120;                          //列宽
    lv.iSubItem=0;

    SendMessage(hListDescriport,LVM_INSERTCOLUMN,6,(DWORD)&lv);



    Add_list_Relocation_View_Items(hListDescriport,hDlg);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值