天天看點

PE導入表(輸入表)學習筆記導入表結構注意點:輸入表列印中的部分核心代碼(API形式)

導入表結構

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 ;
}