none
如何用C++读取程序集的CLR文件头 RRS feed

  • 问题

  • 我想读取PE文件头,找到那个CLR文件头,不过我没有成功。我看到了链接:http://geekswithblogs.net/rupreet/archive/2005/11/02/58873.aspx,我觉得他的意思是偏移0x3C+0x32+0x60+0x70个字节,读取这个地方的4个字节,我试试c:\windows\system32\ntdll.dll,结果不为0,再试一试c:\Windows\Microsoft.NET\Framework64\v4.0.30319\system.dll,结果是0,这与它的代码逻辑的意思刚好相反。请问问题在哪里呢?我还试了这个方法:

    void CsfclrDlg::OnClickedButton2()
    {
    	UpdateData();
    	CFile f(m_DllPath,CFile::modeRead);
    	PBYTE data=(PBYTE)calloc((ULONG)f.GetLength(),sizeof(BYTE));
    	f.Read(data,(UINT)f.GetLength());
    	f.Close();
    	PIMAGE_DOS_HEADER pdosHeader=(PIMAGE_DOS_HEADER)data;
    	PIMAGE_NT_HEADERS32 pntHeader=(PIMAGE_NT_HEADERS)(pdosHeader+pdosHeader->e_lfanew);
    	PIMAGE_COR20_HEADER pclrHeader=(PIMAGE_COR20_HEADER)(pntHeader+sizeof(IMAGE_NT_HEADERS32));
    	
    }

    不过我无法从PIMAGE_COR20_HEADER找到确切证明模块是.NET模块的信息。您能告诉我从哪里检查数据的合法性以确定该模块是.NET模块吗?

    除上述方法外,我想加一个辅助条件来判断,即找到PE文件入口点,读取入口点的6个字节,确定是否FF 25 00 20 40 00(jmp dword ptr [00402000])或者FF 25 00 20 00 10,您觉得呢?

    我看到Windows Platform SDK里面许多头文件以cor开头,比如CorHdr.h文件,我粗略看了里面的内容,好像SDK里面提供了C++与.NET 托管代码交互操作的方法,我想知道哪里有这些方面的资料。比如,如何检测到.NET程序有未经处理的异常,在.NET弹框提示用户之前我能否捕捉得到并自行处理(比如导出DMP文件)?



    妆台秋思



    2014年9月27日 18:35

答案

  • ImageNtHeader函数可以在加载文件到内存映射之后找到文件头。可以根据OptionalHeader.Magic判断文件是PE32还是PE32+。

    IMAGE_OPTIONAL_HEADER的最后一个成员DataDirectory是个数组,根据文件格式不同,可能是IMAGE_NT_HEADERS32或者是IMAGE_NT_HEADERS64。要是里面第IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR个元素有数据的话,可以用ImageRvaToVa找到IMAGE_COR20_HEADER。

    至于要抓未处理的异常,需要自己写一个调试器。



    Visual C++ MVP


    2014年9月27日 22:08
    版主

全部回复

  • ImageNtHeader函数可以在加载文件到内存映射之后找到文件头。可以根据OptionalHeader.Magic判断文件是PE32还是PE32+。

    IMAGE_OPTIONAL_HEADER的最后一个成员DataDirectory是个数组,根据文件格式不同,可能是IMAGE_NT_HEADERS32或者是IMAGE_NT_HEADERS64。要是里面第IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR个元素有数据的话,可以用ImageRvaToVa找到IMAGE_COR20_HEADER。

    至于要抓未处理的异常,需要自己写一个调试器。



    Visual C++ MVP


    2014年9月27日 22:08
    版主
  • 谢谢,我已经发现我的代码有问题,按照你的方法,我成功了。

    妆台秋思

    2014年9月28日 1:12