重定位表结构
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);
}