導入表結構
typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
union
{
DWORD Characteristics;
DWORD OriginalFirstThunk; //指向輸入名稱表(簡稱INT)的RVA,INI是一個IMAGE_THUNK_DATA32結構
};
DWORD TimeDateStamp; //一個32位時間标志
DWORD ForwarderChain; //第一個被轉向的API索引,一般為0。
DWORD Name;//指向DLL名稱的RVA位址(是個以00結尾的ASCII字元的位址)
DWORD FirstThunk;//包含指向輸入位址表(IAI)的RVA,IAI是一個IMAGE_THUNK_DATA32結構
} IMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_THUNK_DATA32
{
union {
PBYTE ForwarderString;//指向一個轉向者字元串的RVA
PDWORD Function;//被輸入的函數記憶體位址
DWORD Ordinal;//被輸入的API的序數值
PIMAGE_IMPORT_BY_NAME AddressOfData;//指向IMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA32;
typedef struct _IMAGE_IMPORT_BY_NAME
{
WORD Hint;//訓示本函數在其所駐留DLL輸出表中的序号,該域被PE裝載器用來在DLL的輸出表裡快速查詢函數
BYTE Name[];//含有輸入函數的函數名,函數名是一個ASCII碼字元串,以NULL結尾。
} IMAGE_IMPORT_BY_NAME;
PE導入表(輸入表)學習筆記導入表結構注意點:輸入表列印中的部分核心代碼(API形式) 注意點:
- 輸入表是以一個IMAGE_IMPORT_DESCRIPTOR(簡稱LLD)數組開始,一個接一個。每個被PE檔案隐式地連結進來的DLL都有一個IID。結束判斷是該數組的最後一個單元為NULL。
- 對于IMAGE_THUNK_DATA的了解不要考慮複雜,整體判斷它就是一個以DWORD數組開始,一個接一個,結束判斷是出現0,是以在定義時可以直接用PDWORD。個體判斷分2種情況,一是DWORD的第32位為1時,表示函數是以序号方式輸入,這是低31位被看作一個函數序号(跟第32位的1沒關系)。當最高位為0時,表示函數以字元串類型的函數方式輸入,這時DWORD是一個RVA(才會用到IMAGE_IMPORT_BY_NAME結構),指向一個IMAGE_IMPORT_BY_NAME結構。
- IMAGE_IMPORT_BY_NAME結構注意WORD Hint開始占2個位元組,列印輸入函數的函數名時一定要把IMAGE_THUNK_DATA中的值轉化為FOA時移動2個位元組,才能正确指向輸入函數的函數名的首位址。
輸入表列印中的部分核心代碼(API形式)
//主要是對IMAGE_IMPORT_DESCRIPTOR(簡稱LLD)數組中其中任意一個有輸入的函數的列印
VOID Enum_IMPORT_THUNK_DATA_listView(HWND hListDescriport,HWND hListThunkData,
WPARAM wParam,LPARAM lParam ,HWND hDlg)
{
SendMessage(hListThunkData,LVM_DELETEALLITEMS ,,);//清除ListControl控件裡面的所有條目
DWORD dwRowId,dwOriginalFirstThunk;
DWORD index=;
TCHAR szOriginalFirstThunk[];
LV_ITEM lvI;
//初始化
memset(&lvI,,sizeof(LV_ITEM));
memset(szOriginalFirstThunk,,);
//擷取選擇行
dwRowId=SendMessage(hListDescriport,LVM_GETNEXTITEM,-,LVNI_SELECTED);
if (dwRowId==-)
{
MessageBox(NULL,TEXT("請選擇DLL"),TEXT("出錯了"),MB_OK);
}
//擷取OriginalFirstThunk
lvI.iSubItem=;//要擷取的列
lvI.pszText=szOriginalFirstThunk;//指定存儲查詢結果的緩沖區
lvI.cchTextMax=;//指定緩沖區大小
SendMessage(hListDescriport,LVM_GETITEMTEXT,dwRowId,(DWORD)&lvI);
sscanf(szOriginalFirstThunk,"%x",&dwOriginalFirstThunk);
PDWORD pThunkData=(PDWORD)((DWORD)lpMemory +
RVAToFOA(lpMemory, dwOriginalFirstThunk));
char string[];
char string1[];
ZeroMemory(string,);
ZeroMemory(string1,);
while(*pThunkData)
{
ZeroMemory(&lvI,sizeof(lvI));
lvI.iItem=index;
lvI.mask=LVIF_TEXT;
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X",*pThunkData);
lvI.pszText=TEXT(string);
ListView_InsertItem(hListThunkData,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X",FOAToRVA(lpMemory,(DWORD)pThunkData-(DWORD)lpMemory));
lvI.pszText=TEXT(string);
ListView_SetItem(hListThunkData,&lvI);
if (*pThunkData>>!=)
{
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", (DWORD)((DWORD)pThunkData-(DWORD)lpMemory));
lvI.pszText=TEXT(string);
ListView_SetItem(hListThunkData,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X",*((PWORD)((DWORD)lpMemory +RVAToFOA(lpMemory, *pThunkData))));
lvI.pszText=TEXT(string);
ListView_SetItem(hListThunkData,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
lvI.pszText=TEXT((char*)((DWORD)lpMemory +RVAToFOA(lpMemory, *pThunkData))+);
ListView_SetItem(hListThunkData,&lvI);
}
else
{
lvI.iSubItem=;
lvI.pszText=TEXT("-");
ListView_SetItem(hListThunkData,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
ZeroMemory(string1,);
wsprintf(string, "%03d", *pThunkData&);
strcpy(string1,"函數序号:");
strcat(string1, string);
lvI.pszText=TEXT(string1);
ListView_SetItem(hListThunkData,&lvI);
}
index++;
pThunkData++;
}
}
//對于PIMAGE_IMPORT_DESCRIPTOR結構中資料的列印
BOOL Add_list_IMPORT_View_Items(HWND hListDescriport,HWND hDlg)
{
LVITEM lvI;
DWORD index=;
char string[];
ZeroMemory(string,);
ZeroMemory(&lvI,sizeof(lvI));
lvI.mask=LVIF_TEXT;//
PIMAGE_IMPORT_DESCRIPTOR pIMPORTDESCRIPTOR=NULL;
pIMPORTDESCRIPTOR=(PIMAGE_IMPORT_DESCRIPTOR)
((DWORD)lpMemory + RVAToFOA(lpMemory, pOptionHeader->DataDirectory[].VirtualAddress));
if(!pIMPORTDESCRIPTOR)
{
MessageBox(hDlg,"can't get IMPORTDESCRIPTOR ","IMPORTD",MB_OK);
return FALSE;
}
while (pIMPORTDESCRIPTOR->FirstThunk)
{
ZeroMemory(&lvI,sizeof(lvI));
lvI.iItem=index;
lvI.mask=LVIF_TEXT;
lvI.iSubItem=;
lvI.pszText=TEXT((char*)((DWORD)lpMemory + RVAToFOA(lpMemory,pIMPORTDESCRIPTOR->Name)) );
ListView_InsertItem(hListDescriport,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", pIMPORTDESCRIPTOR->OriginalFirstThunk);
lvI.pszText=TEXT(string);
ListView_SetItem(hListDescriport,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", pIMPORTDESCRIPTOR->TimeDateStamp);
lvI.pszText=TEXT(string);
ListView_SetItem(hListDescriport,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", pIMPORTDESCRIPTOR->ForwarderChain);
lvI.pszText=TEXT(string);
ListView_SetItem(hListDescriport,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", pIMPORTDESCRIPTOR->Name);
lvI.pszText=TEXT(string);
ListView_SetItem(hListDescriport,&lvI);
lvI.iSubItem=;
ZeroMemory(string,);
wsprintf(string, "%08X", pIMPORTDESCRIPTOR->FirstThunk);
lvI.pszText=TEXT(string);
ListView_SetItem(hListDescriport,&lvI);
index++;
pIMPORTDESCRIPTOR++;
}
return ;
}