我正在开发一个解决方案,我需要能够检查文件是否属于特定类型,我不能信任该文件的扩展名。
我已经能够识别EXE和DLL文件,只需要识别最后一个。
目前我不知道如何识别MSI MSI中的哪些与EXE和DLL不同?我应该在哪里看?
例如找到我正在执行以下操作的DLL:
if ((ntHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) != 0)
{
//If DLL then this returns True Else Return False
return (ntHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) == 8192;
}
是否有类似的解决方案来确定文件是否为MSI类型?
编辑1 这就是我现在根据dlatikay的想法做的事情
private static ulong FIRST_8_BYTES_OF_MSI_FILE =0xD0CF11E0A1B11AE1;
private bool MSICheck(FileStream fileData)
{
byte[] first8bytes = new byte[8];
using (BinaryReader reader = new BinaryReader(fileData))
{
reader.BaseStream.Seek(0, SeekOrigin.Begin);
reader.Read(first8bytes, 0, 7);
}
ulong sum = BitConverter.ToUInt64(first8bytes, 0);
//string hexString = BitConverter.ToString(first8bytes);
bool returnval = sum == FIRST_8_BYTES_OF_MSI_FILE;
return returnval;
//D0 CF 11 E0 A1 B1 1A E1 First 8 hexadecimal of a MSI package
//return false;
}
但是这种方法无法将我的测试msi文件称为msi文件,因此我猜测我做错了什么?
我的解决方案:
在 dlatikay
的指导下private static string FIRST_8_BYTES_OF_MSI_FILE = "D0CF11E0A1B11AE1";
private bool MSICheck(FileStream fileData)
{
byte[] first8bytes = new byte[8];
using (BinaryReader reader = new BinaryReader(fileData))
{
reader.BaseStream.Seek(0, SeekOrigin.Begin);
reader.Read(first8bytes, 0, first8bytes.Length);
}
string sum = BitConverter.ToString(first8bytes).Replace("-",""); ;
bool returnval = sum.Equals(FIRST_8_BYTES_OF_MSI_FILE);
return returnval;
//D0 CF 11 E0 A1 B1 1A E1 First 8 hexadecimal of a MSI package
//return false;
}
答案 0 :(得分:3)
MSI文件格式是Microsoft的私有指定格式。这真是一个奇怪的野兽,我的意思是谁会采用SQL数据库,强制它成为COM存储格式并调用该MSI?但就是这样。
相关: Windows installer MSI format
干净的方法是引用Windows Installer SDK并尝试在您怀疑是MSI的文件上调用MsiVerifyPackage
(documentation),如果调用返回{{1你认为这是真的。
有一个适用于.NET的托管版本:
ERROR_SUCCESS
更实用,轻量且更快的方法是检查序列
using Microsoft.Deployment.WindowsInstaller;
...
if(Installer.VerifyPackage(fullpath))
{
/* positive. it may still be corrupt,
* but the API says it is a Microsoft Installer package */
}
将其与具有相同扩展名的Cerius2文件区分开来。
(Source)