又好久没有发帖子了!今天我也来凑个热闹!
其实起这么一个标题真的让我感到很惭愧,因为读取导入表这里我学的真是一塌糊涂!
外加上最近不知道怎么了,个人头脑智商低下,看了挺多读取导入表的程序,还是没有弄明白怎么用一个指针把导入表中的所有信息都读出来!
无奈之下,想了一个最笨的方法:按照《加密与解密》(第二版)中导入表的实例的步骤,把各个指针的地址转换成文件偏移,然后在用CFile类从文件里面读出数据来!
虽然这个方法效率确实低下,在程序中实在不可取!但是无论怎么说,这也是我学习PE文件结构的一个见证!也是我经过近四天努力的结果,几经考虑,终于还是决定帖出来,让新手朋友参考,请高手指教!
好了,废话不说了,进入主题!
要读取导入表的信息需要知道:区段表、目录表还有地址偏移转换相关的东西!
怎么转换地址可以看我的另一个帖子:
http://bbs.pediy.com/showthread.php?t=67955怎么读取区段和目录表不是这个帖子的主题,朋友们可以看其它相关的帖子文章或者看我附件中的源程序!
获取导入表的代码如下:
1
void CImportViewsDlg::GetImports(DWORD _Addr)
2

{
3
CFileException ex;
4
5
CFile pFile;
6
if (!pFile.Open(m_FilePathName,CFile::shareDenyNone|CFile::typeBinary,&ex))
7
{
8
TCHAR szError[1024];
9
ex.GetErrorMessage(szError,1024);
10
MessageBox(szError);
11
}
12
13
pFile.Seek(_Addr,CFile::begin);
14
15
CString szTemp = "";
16
m_DllList.DeleteAllItems();
17
int i = 0;
18
while ( 1 )
19
{
20
pFile.Read(&_Imports,sizeof(IMAGE_IMPORT_DESCRIPTOR));
21
22
if((_Imports.TimeDateStamp==0 ) && (_Imports.Name==0) )
23
break;
24
szTemp = GetNames(RVAtoFileOffSet(_Imports.Name));
25
m_DllList.InsertItem(i,szTemp);
26
27
szTemp.Format("%p",_Imports.OriginalFirstThunk);
28
m_DllList.SetItemText(i,1,szTemp);
29
szTemp.Format("%p",_Imports.TimeDateStamp);
30
m_DllList.SetItemText(i,2,szTemp);
31
szTemp.Format("%p",_Imports.ForwarderChain);
32
m_DllList.SetItemText(i,3,szTemp);
33
szTemp.Format("%p",_Imports.FirstThunk);
34
m_DllList.SetItemText(i,4,szTemp);
35
i++;
36
37
}
38
pFile.Close();
39
}
40
由于DLL的名称没有指明具体的大小只知道以0x00结尾,所以我就写了一个GetNames()函数,大家别笑话我哦~~~:
1
CString CImportViewsDlg::GetNames(DWORD _Addr)
2

{
3
CString Name = "";
4
CString sTemp = "";
5
CFileException ex;
6
CFile pFile;
7
8
if (!pFile.Open(m_FilePathName,CFile::shareDenyNone|CFile::typeBinary,&ex))
9
{
10
TCHAR szError[1024];
11
ex.GetErrorMessage(szError,1024);
12
MessageBox(szError);
13
return "";
14
}
15
BYTE fileBur;
16
pFile.Seek(_Addr,CFile::begin);
17
pFile.Read(&fileBur,0x1);
18
sTemp.Format("%c",fileBur);
19
Name += sTemp;
20
for(int i=0;fileBur!=0;i++)
21
{
22
pFile.Read(&fileBur,0x1);
23
sTemp.Format("%c",fileBur);
24
Name += sTemp;
25
}
26
pFile.Close();
27
return Name;
28
}
29
获取相应DLL中API函数信息的代码如下
1
void CImportViewsDlg::GetFunctions(IMAGE_IMPORT_DESCRIPTOR _Imports)
2

{
3
DWORD RvaINT = _Imports.OriginalFirstThunk;
4
DWORD RvaIAT = _Imports.FirstThunk;
5
IMAGE_THUNK_DATA tdINT;
6
CString strFlag;
7
int FunNum = 0;
8
9
if ( RvaINT == 0 )
10
{
11
RvaINT = RvaIAT;
12
if ( RvaINT == 0 )
13
return;
14
}
15
16
if(((CButton*)GetDlgItem(IDC_FIRSTTHUNK))->GetCheck()&1)
17
{
18
m_KindThunk = _Imports.FirstThunk;
19
strFlag = "( FirstThunk chain )";
20
}
21
else
22
{
23
m_KindThunk = _Imports.OriginalFirstThunk;
24
strFlag = "( OriginalFirstThunk chain )";
25
}
26
m_ListInfo.DeleteAllItems();
27
28
CFileException ex;
29
CFile pFile;
30
if (!pFile.Open(m_FilePathName,CFile::shareDenyNone|CFile::typeBinary,&ex))
31
{
32
TCHAR szError[1024];
33
ex.GetErrorMessage(szError,1024);
34
MessageBox(szError);
35
}
36
37
pFile.Seek(RVAtoFileOffSet(RvaINT),CFile::begin);
38
CString szTemp = "";
39
while ( 1 )
40
{
41
pFile.Read(&tdINT,sizeof(IMAGE_THUNK_DATA));
42
if(!tdINT.u1.AddressOfData)
43
break;
44
ULONG ordinal=-1;
45
if(IMAGE_SNAP_BY_ORDINAL32(tdINT.u1.Ordinal))
46
ordinal = IMAGE_ORDINAL32(tdINT.u1.Ordinal);
47
CString strTemp;
48
CString RVApINT;
49
CString Hint;
50
CString Name;
51
CString OffsetOrdinalName;
52
CString ThunkZhi;
53
CString dHint;
54
CString FinalHint;
55
56
if(ordinal==-1)
57
{
58
RVApINT.Format("%p",(PBYTE)m_KindThunk);
59
OffsetOrdinalName.Format("%p",RVAtoFileOffSet((DWORD)m_KindThunk));
60
ThunkZhi.Format("%p",RVAtoFileOffSet((DWORD)(tdINT.u1.AddressOfData)));
61
dHint.Format("%u",GetOrdinalName(RVAtoFileOffSet((DWORD)(tdINT.u1.AddressOfData))));
62
Hint.Format("%.4X",GetOrdinalName(RVAtoFileOffSet((DWORD)(tdINT.u1.AddressOfData))));
63
FinalHint=Hint+"("+dHint+")";
64
Name.Format("%s",GetOrdinalName(RVAtoFileOffSet((DWORD)(tdINT.u1.AddressOfData)),TRUE));
65
}
66
else
67
{
68
RVApINT.Format("%p",(PBYTE)m_KindThunk);
69
OffsetOrdinalName.Format("%p",RVAtoFileOffSet((DWORD)m_KindThunk));
70
ThunkZhi.Format("%p",RVAtoFileOffSet((DWORD)(tdINT.u1.AddressOfData)));
71
//OffsetOrdinalName="N/A";
72
FinalHint="N/A";
73
Name="N/A";
74
}
75
76
m_ListInfo.InsertItem(FunNum,RVApINT);
77
m_ListInfo.SetItemText(FunNum,1,OffsetOrdinalName);
78
m_ListInfo.SetItemText(FunNum,2,ThunkZhi);
79
m_ListInfo.SetItemText(FunNum,3,FinalHint);
80
m_ListInfo.SetItemText(FunNum,4,Name);
81
82
FunNum++;
83
m_KindThunk += 4;
84
}
85
pFile.Close();
86
CString strTishi;
87
szTemp.Format("%X",FunNum);
88
strTishi += "Thunk数:" + szTemp + "h / ";
89
szTemp.Format("%d",FunNum);
90
strTishi += szTemp + "d" + strFlag;
91
SetDlgItemText(IDC_IMPORT_TISHI,strTishi);
92
}
93
好了,主要的代码都帖完了,效果还不错的,如下图:

具体代码大家可以看附件中的程序!
如果您有更好的方法,请一定要教一下我哦~~
我最近智商太低了,让大家笑话了~~~