以下代码用于从文件头读取第一个字节。
在Windows 8 64bit上运行,此代码在标记为“AnyCPU - 首选32位”的项目下运行时有效。 (.NET 4.5.1)
如果它在'AnyCPU'下运行(未选中'Prefer 32 bit') - 它会抛出
“AccessViolationException:附加信息:尝试阅读 或写保护的内存。这通常表明其他 记忆已腐败。“
在以前的.NET版本中,它可以作为“AnyCPU”使用。
为什么“Prefer 32 bit”选中与否之间的行为不同?
为什么.net版本之间的行为有所不同?
public class FileParser
{
private static uint _hLib;
public static void Parse(string fileName)
{
_hLib = LoadLibraryEx(fileName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_IGNORE_CODE_AUTHZ_LEVEL);
if (_hLib == 0)
{
Console.WriteLine("********* Failed to load {0}.\r\nSpecified file was either not found, or is not a valid PE file.********", fileName);
return;
}
ScanHeaders();
}
private static unsafe void ScanHeaders()
{
byte* pDosHeader = (byte*) _hLib;
Console.WriteLine("pDosHeader[0] = {0}", pDosHeader[0]); // <<---- this is where it throws 'AccessViolationException'
}
// From winbase.h in the Win32 platform SDK.
//
const uint DONT_RESOLVE_DLL_REFERENCES = 0x00000001;
const uint LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010;
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
static extern uint LoadLibraryEx(string fileName, uint notUsedMustBeZero, uint flags);
}
答案 0 :(得分:3)
可能还有其他问题,但最重要的问题是:
private static uint _hLib;
HMODULE
是指针大小的。你的演员byte*
应该清楚这一点。但uint
是32位宽,可能会发生。您需要将_hLib
声明为指针大小。例如:
private static IntPtr _hLib;
或者
private static UIntPtr _hLib;
这可以解释为什么代码在64位进程内运行时会失败。
也就是说,如果要扫描DLL的标头,则不必使用LoadLibraryEx
。简单地打开文件并阅读其内容。