聚星亭

吾笨笨且懒散兮 急须改之而奋进

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  2 随笔 :: 3 文章 :: 3 评论 :: 0 Trackbacks
又好久没有发帖子了!今天我也来凑个热闹! 
其实起这么一个标题真的让我感到很惭愧,因为读取导入表这里我学的真是一塌糊涂!
外加上最近不知道怎么了,个人头脑智商低下,看了挺多读取导入表的程序,还是没有弄明白怎么用一个指针把导入表中的所有信息都读出来! 
无奈之下,想了一个最笨的方法:按照《加密与解密》(第二版)中导入表的实例的步骤,把各个指针的地址转换成文件偏移,然后在用CFile类从文件里面读出数据来!  
虽然这个方法效率确实低下,在程序中实在不可取!但是无论怎么说,这也是我学习PE文件结构的一个见证!也是我经过近四天努力的结果,几经考虑,终于还是决定帖出来,让新手朋友参考,请高手指教! 

好了,废话不说了,进入主题!
要读取导入表的信息需要知道:区段表、目录表还有地址偏移转换相关的东西!
怎么转换地址可以看我的另一个帖子:
http://bbs.pediy.com/showthread.php?t=67955

怎么读取区段和目录表不是这个帖子的主题,朋友们可以看其它相关的帖子文章或者看我附件中的源程序!

获取导入表的代码如下:
 1void 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()函数,大家别笑话我哦~~~:
 1CString 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函数信息的代码如下 
 1void 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

好了,主要的代码都帖完了,效果还不错的,如下图:


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

点击这里下载附件导入表查看器[SRC]
导入表查看器[EXE]

posted on 2008-11-01 12:02 美丽の破船 阅读(201) 评论(0)  编辑 收藏 引用 所属分类: C/C++/VC/MFC
只有注册用户登录后才能发表评论。