支持net8版本的签名检查

This commit is contained in:
ZouJin 2024-03-13 18:57:16 +08:00
parent c6528e1676
commit ead7115ac9
2 changed files with 226 additions and 280 deletions

View File

@ -10,6 +10,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Security.Cryptography.X509Certificates;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Xml.Linq; using System.Xml.Linq;
@ -77,271 +78,278 @@ namespace VPet_Simulator.Windows
} }
public CoreMOD(DirectoryInfo directory, MainWindow mw) public CoreMOD(DirectoryInfo directory, MainWindow mw)
{ {
#if !DEBUG
try try
{ {
Path = directory; #endif
LpsDocument modlps = new LpsDocument(File.ReadAllText(directory.FullName + @"\info.lps")); Path = directory;
Name = modlps.FindLine("vupmod").Info; LpsDocument modlps = new LpsDocument(File.ReadAllText(directory.FullName + @"\info.lps"));
NowLoading = Name; Name = modlps.FindLine("vupmod").Info;
Intro = modlps.FindLine("intro").Info; NowLoading = Name;
GameVer = modlps.FindSub("gamever").InfoToInt; Intro = modlps.FindLine("intro").Info;
Ver = modlps.FindSub("ver").InfoToInt; GameVer = modlps.FindSub("gamever").InfoToInt;
Author = modlps.FindSub("author").Info.Split('[').First(); Ver = modlps.FindSub("ver").InfoToInt;
if (modlps.FindLine("authorid") != null) Author = modlps.FindSub("author").Info.Split('[').First();
AuthorID = modlps.FindLine("authorid").InfoToInt64; if (modlps.FindLine("authorid") != null)
else AuthorID = modlps.FindLine("authorid").InfoToInt64;
AuthorID = 0; else
if (modlps.FindLine("itemid") != null) AuthorID = 0;
ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info); if (modlps.FindLine("itemid") != null)
else ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info);
ItemID = 0; else
CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue); ItemID = 0;
CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue);
//MOD未加载时支持翻译 //MOD未加载时支持翻译
foreach (var line in modlps.FindAllLine("lang")) foreach (var line in modlps.FindAllLine("lang"))
{
List<ILine> ls = new List<ILine>();
foreach (var sub in line)
{ {
List<ILine> ls = new List<ILine>(); ls.Add(new Line(sub.Name, sub.info));
foreach (var sub in line)
{
ls.Add(new Line(sub.Name, sub.info));
}
LocalizeCore.AddCulture(line.info, ls);
} }
LocalizeCore.AddCulture(line.info, ls);
}
if (mw.CoreMODs.FirstOrDefault(x => x.Name == Name) != null) if (mw.CoreMODs.FirstOrDefault(x => x.Name == Name) != null)
{ {
Name += $"({"MOD名称重复".Translate()})"; Name += $"({"MOD名称重复".Translate()})";
ErrorMessage = "MOD名称重复".Translate(); ErrorMessage = "MOD名称重复".Translate();
return; return;
} }
if (!IsOnMOD(mw))
{
Tag.Add("该模组已停用");
foreach (DirectoryInfo di in Path.EnumerateDirectories())
Tag.Add(di.Name.ToLower());
return;
}
if (!IsOnMOD(mw))
{
Tag.Add("该模组已停用");
foreach (DirectoryInfo di in Path.EnumerateDirectories()) foreach (DirectoryInfo di in Path.EnumerateDirectories())
Tag.Add(di.Name.ToLower());
return;
}
foreach (DirectoryInfo di in Path.EnumerateDirectories())
{
switch (di.Name.ToLower())
{ {
switch (di.Name.ToLower()) case "theme":
{ Tag.Add("theme");
case "theme": if (Directory.Exists(di.FullName + @"\fonts"))
Tag.Add("theme"); foreach (var str in Directory.EnumerateFiles(di.FullName + @"\fonts", "*.ttf"))
if (Directory.Exists(di.FullName + @"\fonts"))
foreach (var str in Directory.EnumerateFiles(di.FullName + @"\fonts", "*.ttf"))
{
mw.Fonts.Add(new IFont(new FileInfo(str)));
}
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{ {
var tmp = new Theme(new LpsDocument(File.ReadAllText(fi.FullName))); mw.Fonts.Add(new IFont(new FileInfo(str)));
var oldtheme = mw.Themes.Find(x => x.xName == tmp.xName); }
if (oldtheme != null)
mw.Themes.Remove(oldtheme); foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
mw.Themes.Add(tmp); {
//加载图片包 var tmp = new Theme(new LpsDocument(File.ReadAllText(fi.FullName)));
DirectoryInfo tmpdi = new DirectoryInfo(di.FullName + '\\' + tmp.Image); var oldtheme = mw.Themes.Find(x => x.xName == tmp.xName);
if (tmpdi.Exists) if (oldtheme != null)
mw.Themes.Remove(oldtheme);
mw.Themes.Add(tmp);
//加载图片包
DirectoryInfo tmpdi = new DirectoryInfo(di.FullName + '\\' + tmp.Image);
if (tmpdi.Exists)
{
foreach (FileInfo tmpfi in tmpdi.EnumerateFiles("*.png"))
{ {
foreach (FileInfo tmpfi in tmpdi.EnumerateFiles("*.png")) tmp.Images.AddSource(tmpfi.Name.ToLower().Substring(0, tmpfi.Name.Length - 4), tmpfi.FullName);
}
foreach (DirectoryInfo fordi in tmpdi.EnumerateDirectories())
{
foreach (FileInfo tmpfi in fordi.EnumerateFiles("*.png"))
{ {
tmp.Images.AddSource(tmpfi.Name.ToLower().Substring(0, tmpfi.Name.Length - 4), tmpfi.FullName); tmp.Images.AddSource(fordi.Name + '_' + tmpfi.Name.ToLower().Substring(0, tmpfi.Name.Length - 4), tmpfi.FullName);
}
foreach (DirectoryInfo fordi in tmpdi.EnumerateDirectories())
{
foreach (FileInfo tmpfi in fordi.EnumerateFiles("*.png"))
{
tmp.Images.AddSource(fordi.Name + '_' + tmpfi.Name.ToLower().Substring(0, tmpfi.Name.Length - 4), tmpfi.FullName);
}
} }
} }
} }
break; }
case "pet": break;
//宠物模型 case "pet":
foreach (FileInfo fi in di.EnumerateFiles("*.lps")) //宠物模型
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
LpsDocument lps = new LpsDocument(File.ReadAllText(fi.FullName));
if (lps.First().Name.ToLower() == "pet")
{ {
LpsDocument lps = new LpsDocument(File.ReadAllText(fi.FullName)); var name = lps.First().Info;
if (lps.First().Name.ToLower() == "pet") var p = mw.Pets.FirstOrDefault(x => x.Name == name);
if (p == null)
{ {
var name = lps.First().Info; Tag.Add("pet");
var p = mw.Pets.FirstOrDefault(x => x.Name == name); p = new PetLoader(lps, di);
if (p == null) if (p.Config.Works.Count > 0)
Tag.Add("work");
mw.Pets.Add(p);
}
else
{
if (lps.FindAllLine("work").Length >= 0)
{ {
Tag.Add("work");
}
var dis = new DirectoryInfo(di.FullName + "\\" + lps.First()["path"].Info);
if (dis.Exists && dis.GetDirectories().Length > 0)
Tag.Add("pet"); Tag.Add("pet");
p = new PetLoader(lps, di); p.path.Add(di.FullName + "\\" + lps.First()["path"].Info);
if (p.Config.Works.Count > 0) p.Config.Set(lps);
Tag.Add("work");
mw.Pets.Add(p);
}
else
{
if (lps.FindAllLine("work").Length >= 0)
{
Tag.Add("work");
}
var dis = new DirectoryInfo(di.FullName + "\\" + lps.First()["path"].Info);
if (dis.Exists && dis.GetDirectories().Length > 0)
Tag.Add("pet");
p.path.Add(di.FullName + "\\" + lps.First()["path"].Info);
p.Config.Set(lps);
}
} }
} }
break; }
case "food": break;
Tag.Add("food"); case "food":
foreach (FileInfo fi in di.EnumerateFiles("*.lps")) Tag.Add("food");
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
foreach (ILine li in tmp)
{ {
var tmp = new LpsDocument(File.ReadAllText(fi.FullName)); if (li.Name != "food")
foreach (ILine li in tmp)
{
if (li.Name != "food")
continue;
string tmps = li.Find("name").info;
mw.Foods.RemoveAll(x => x.Name == tmps);
mw.Foods.Add(LPSConvert.DeserializeObject<Food>(li));
}
}
break;
case "image":
Tag.Add("image");
LoadImage(mw, di);
break;
case "text":
Tag.Add("text");
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
foreach (ILine li in tmp)
{
switch (li.Name.ToLower())
{
case "lowfoodtext":
mw.LowFoodText.Add(LPSConvert.DeserializeObject<LowText>(li));
Tag.Add("lowtext");
break;
case "lowdrinktext":
mw.LowDrinkText.Add(LPSConvert.DeserializeObject<LowText>(li));
Tag.Add("lowtext");
break;
case "clicktext":
mw.ClickTexts.Add(LPSConvert.DeserializeObject<ClickText>(li));
Tag.Add("clicktext");
break;
case "selecttext":
mw.SelectTexts.Add(LPSConvert.DeserializeObject<SelectText>(li));
Tag.Add("selecttext");
break;
}
}
}
break;
case "lang":
Tag.Add("lang");
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
LocalizeCore.AddCulture(fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length), new LPS_D(File.ReadAllText(fi.FullName)));
}
foreach (DirectoryInfo dis in di.EnumerateDirectories())
{
foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
{
LocalizeCore.AddCulture(dis.Name, new LPS_D(File.ReadAllText(fi.FullName)));
}
}
if (mw.Set.Language == "null")
{
LocalizeCore.LoadDefaultCulture();
}
else
LocalizeCore.LoadCulture(mw.Set.Language);
break;
case "plugin":
Tag.Add("plugin");
SuccessLoad = true;
string authtype = "";
foreach (FileInfo tmpfi in di.EnumerateFiles("*.dll"))
{
#if X64
if (tmpfi.Name.Contains("x86"))
{
continue; continue;
string tmps = li.Find("name").info;
mw.Foods.RemoveAll(x => x.Name == tmps);
mw.Foods.Add(LPSConvert.DeserializeObject<Food>(li));
}
}
break;
case "image":
Tag.Add("image");
LoadImage(mw, di);
break;
case "text":
Tag.Add("text");
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
foreach (ILine li in tmp)
{
switch (li.Name.ToLower())
{
case "lowfoodtext":
mw.LowFoodText.Add(LPSConvert.DeserializeObject<LowText>(li));
Tag.Add("lowtext");
break;
case "lowdrinktext":
mw.LowDrinkText.Add(LPSConvert.DeserializeObject<LowText>(li));
Tag.Add("lowtext");
break;
case "clicktext":
mw.ClickTexts.Add(LPSConvert.DeserializeObject<ClickText>(li));
Tag.Add("clicktext");
break;
case "selecttext":
mw.SelectTexts.Add(LPSConvert.DeserializeObject<SelectText>(li));
Tag.Add("selecttext");
break;
} }
}
}
break;
case "lang":
Tag.Add("lang");
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
{
LocalizeCore.AddCulture(fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length), new LPS_D(File.ReadAllText(fi.FullName)));
}
foreach (DirectoryInfo dis in di.EnumerateDirectories())
{
foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
{
LocalizeCore.AddCulture(dis.Name, new LPS_D(File.ReadAllText(fi.FullName)));
}
}
if (mw.Set.Language == "null")
{
LocalizeCore.LoadDefaultCulture();
}
else
LocalizeCore.LoadCulture(mw.Set.Language);
break;
case "plugin":
Tag.Add("plugin");
SuccessLoad = true;
string authtype = "";
foreach (FileInfo tmpfi in di.EnumerateFiles("*.dll"))
{
#if X64
if (tmpfi.Name.Contains("x86"))
{
continue;
}
#else #else
if (tmpfi.Name.Contains("x64")) if (tmpfi.Name.Contains("x64"))
{ {
continue; continue;
} }
#endif #endif
try
try
{
var path = tmpfi.Name;
if (LoadedDLL.Contains(path))
continue;
LoadedDLL.Add(path);
X509Certificate2 certificate = new X509Certificate2(tmpfi.FullName);
if (certificate != null)
{ {
var path = tmpfi.Name; if (certificate.Subject == "CN=\"Shenzhen Lingban Computer Technology Co., Ltd.\", O=\"Shenzhen Lingban Computer Technology Co., Ltd.\", L=Shenzhen, S=Guangdong Province, C=CN, SERIALNUMBER=91440300MA5H8REU3K, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.1=Shenzhen, OID.1.3.6.1.4.1.311.60.2.1.2=Guangdong Province, OID.1.3.6.1.4.1.311.60.2.1.3=CN"
if (LoadedDLL.Contains(path)) && certificate.Issuer == "CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1, O=\"DigiCert, Inc.\", C=US")
{//LBGame 信任的证书
if (authtype != "FAIL")
authtype = "[认证]".Translate();
}
else if (certificate.Subject != "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" && !IsPassMOD(mw))
{//不是通过模组,不加载
SuccessLoad = false;
continue; continue;
LoadedDLL.Add(path);
Assembly dll = Assembly.LoadFrom(tmpfi.FullName);
var certificate = Win32.GetCertificateFromSignedFile(path);
if (certificate != null)
{
if (certificate.Subject == "CN=\"Shenzhen Lingban Computer Technology Co., Ltd.\", O=\"Shenzhen Lingban Computer Technology Co., Ltd.\", L=Shenzhen, S=Guangdong Province, C=CN, SERIALNUMBER=91440300MA5H8REU3K, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.1=Shenzhen, OID.1.3.6.1.4.1.311.60.2.1.2=Guangdong Province, OID.1.3.6.1.4.1.311.60.2.1.3=CN"
&& certificate.Issuer == "CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1, O=\"DigiCert, Inc.\", C=US")
{//LBGame 信任的证书
if (authtype != "FAIL")
authtype = "[认证]".Translate();
}
else if (certificate.Subject != "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" && !IsPassMOD(mw))
{//不是通过模组,不加载
SuccessLoad = false;
continue;
}
else if (authtype != "")
{
authtype = "[签名]".Translate();
//Intro += $"\nSubject:{certificate.Subject}\nIssuer:{certificate.Subject}";
}
} }
else else if (authtype != "")
{ {
authtype = "FAIL"; authtype = "[签名]".Translate();
if (!IsPassMOD(mw)) //Intro += $"\nSubject:{certificate.Subject}\nIssuer:{certificate.Subject}";
{//不是通过模组,不加载
SuccessLoad = false;
Author = modlps.FindSub("author").Info.Split('[').First();
continue;
}
}
var v = dll.GetExportedTypes();
foreach (Type exportedType in v)
{
if (exportedType.BaseType == typeof(MainPlugin))
{
mw.Plugins.Add((MainPlugin)Activator.CreateInstance(exportedType, mw));
}
} }
} }
catch (Exception e) else
{ {
ErrorMessage = e.Message; authtype = "FAIL";
SuccessLoad = false; if (!IsPassMOD(mw))
{//不是通过模组,不加载
SuccessLoad = false;
Author = modlps.FindSub("author").Info.Split('[').First();
continue;
}
} }
Assembly dll = Assembly.LoadFrom(tmpfi.FullName);
var v = dll.GetExportedTypes();
foreach (Type exportedType in v)
{
if (exportedType.BaseType == typeof(MainPlugin))
{
mw.Plugins.Add((MainPlugin)Activator.CreateInstance(exportedType, mw));
}
}
} }
if (authtype != "FAIL") catch (Exception e)
Author += authtype; {
break; ErrorMessage = e.Message;
} SuccessLoad = false;
}
}
if (authtype != "FAIL")
Author += authtype;
break;
} }
} }
#if !DEBUG
}
catch (Exception e) catch (Exception e)
{ {
ErrorMessage = e.Message; ErrorMessage = e.Message;
Tag.Add("该模组已损坏"); Tag.Add("该模组已损坏");
SuccessLoad = false; SuccessLoad = false;
} }
#endif
} }
public bool IsOnMOD(MainWindow mw) => mw.Set.IsOnMod(Name); public bool IsOnMOD(MainWindow mw) => mw.Set.IsOnMod(Name);
public bool IsPassMOD(MainWindow mw) => mw.Set.IsPassMOD(Name); public bool IsPassMOD(MainWindow mw) => mw.Set.IsPassMOD(Name);

View File

@ -11,68 +11,6 @@ namespace VPet_Simulator.Windows
{ {
static partial class Win32 static partial class Win32
{ {
[DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CryptQueryObject(
int dwObjectType,
string pvObject,
int dwExpectedContentTypeFlags,
int dwExpectedFormatTypeFlags,
int dwFlags,
IntPtr pdwMsgAndCertEncodingType,
IntPtr pdwContentType,
IntPtr pdwFormatType,
IntPtr phStore,
IntPtr phMsg,
ref IntPtr ppvContext
);
private const int CERT_QUERY_OBJECT_FILE = 0x00000001;
private const int CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = 0x00004000;
private const int CERT_QUERY_FORMAT_FLAG_BINARY = 0x00000002;
public static X509Certificate2? GetCertificateFromSignedFile(string filePath)
{
IntPtr certificateContext = IntPtr.Zero;
if (!CryptQueryObject(
CERT_QUERY_OBJECT_FILE,
filePath,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
ref certificateContext))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
return new X509Certificate2(certificateContext);
}
catch
{
return null;
}
//finally
//{
// if (certificateContext != IntPtr.Zero)
// {
// X509Certificate2Collection certificates = new X509Certificate2Collection();
// certificates.ImportFromPemFile(filePath);
// foreach (var certificate in certificates)
// {
// Console.WriteLine($"Subject: {certificate.Subject}");
// Console.WriteLine($"Issuer: {certificate.Issuer}");
// }
// }
//}
}
[ComImport] [ComImport]
[Guid("00021401-0000-0000-C000-000000000046")] [Guid("00021401-0000-0000-C000-000000000046")]
internal class ShellLink internal class ShellLink