mirror of
https://github.com/Wack0/IFPSTools.NET.git
synced 2025-06-18 10:45:36 -04:00
lib: dll delayload/loadwithalteredsearchpath flags were added in v23, add version check for this
tests: add test for v22 script with dll imports. please note bytecode used here came from a malware sample!
This commit is contained in:
parent
8108a88464
commit
a9e627314a
BIN
IFPSLib.Tests/CompiledCode_v22.bin
Normal file
BIN
IFPSLib.Tests/CompiledCode_v22.bin
Normal file
Binary file not shown.
3175
IFPSLib.Tests/CompiledCode_v22.txt
Normal file
3175
IFPSLib.Tests/CompiledCode_v22.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -59,6 +59,7 @@
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="CompiledCode.bin" />
|
||||
<None Include="CompiledCode_v22.bin" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -81,6 +82,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="CompiledCode.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CompiledCode_v22.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
38
IFPSLib.Tests/Properties/Resources.Designer.cs
generated
38
IFPSLib.Tests/Properties/Resources.Designer.cs
generated
@ -70,6 +70,16 @@ namespace IFPSLib.Tests.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] CompiledCode_v22 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("CompiledCode_v22", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to .version 23
|
||||
///
|
||||
@ -97,5 +107,33 @@ namespace IFPSLib.Tests.Properties {
|
||||
return ResourceManager.GetString("CompiledCodeDisasm", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to .version 23
|
||||
///
|
||||
///.entry !MAIN
|
||||
///
|
||||
///.type primitive(Pointer) Pointer
|
||||
///.type primitive(U32) U32
|
||||
///.type primitive(Variant) Variant
|
||||
///.type primitive(PChar) PChar
|
||||
///.type primitive(Currency) Currency
|
||||
///.type primitive(Extended) Extended
|
||||
///.type primitive(Double) Double
|
||||
///.type primitive(Single) Single
|
||||
///.type primitive(S64) S64
|
||||
///.type primitive(String) String
|
||||
///.type primitive(U32) U32_2
|
||||
///.type primitive(S32) S32
|
||||
///.type primitive(S16) S16
|
||||
///.type primitive(U16) U16
|
||||
///.type primitive(S8) S8
|
||||
///.type(export) funcptr(void()) ANY [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string CompiledCodeDisasm_v22 {
|
||||
get {
|
||||
return ResourceManager.GetString("CompiledCodeDisasm_v22", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,4 +124,10 @@
|
||||
<data name="CompiledCodeDisasm" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\CompiledCode.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="CompiledCodeDisasm_v22" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\CompiledCode_v22.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="CompiledCode_v22" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\CompiledCode_v22.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
@ -11,6 +11,7 @@ namespace IFPSLib.Tests
|
||||
public class ScriptTest
|
||||
{
|
||||
private static readonly string origB64 = Convert.ToBase64String(Resources.CompiledCode);
|
||||
private static readonly string origB64_22 = Convert.ToBase64String(Resources.CompiledCode_v22);
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSave()
|
||||
@ -44,5 +45,38 @@ namespace IFPSLib.Tests
|
||||
var savedB64 = Convert.ToBase64String(script.Save());
|
||||
Assert.AreEqual(savedB64, origB64);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSaveV22()
|
||||
{
|
||||
// Load the script.
|
||||
var script = Script.Load(Resources.CompiledCode_v22);
|
||||
// Ensure it's not null.
|
||||
Assert.IsNotNull(script);
|
||||
// For an official script (compiled by inno setup), the entrypoint is the first function.
|
||||
Assert.AreEqual(script.EntryPoint, script.Functions[0]);
|
||||
// Save the script.
|
||||
var savedBytes = script.Save();
|
||||
// Convert to base64 for later.
|
||||
var saved = Convert.ToBase64String(savedBytes);
|
||||
// Load the saved script.
|
||||
var scriptSaved = Script.Load(savedBytes);
|
||||
// Save again.
|
||||
var savedTwice = Convert.ToBase64String(scriptSaved.Save());
|
||||
// Ensure both saved scripts equal each other.
|
||||
Assert.AreEqual(saved, savedTwice);
|
||||
// Ensure the saved script equals the original.
|
||||
Assert.AreEqual(saved, origB64_22);
|
||||
// Ensure the disassemblies are equal.
|
||||
Assert.AreEqual(script.Disassemble(), scriptSaved.Disassemble());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAsmV22()
|
||||
{
|
||||
var script = Assembler.Assemble(Resources.CompiledCodeDisasm_v22);
|
||||
var savedB64 = Convert.ToBase64String(script.Save());
|
||||
Assert.AreEqual(savedB64, origB64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace IFPSLib.Emit
|
||||
protected const string ClassString = "class:";
|
||||
protected const string ComString = "intf:.";
|
||||
|
||||
internal static Base Load(BinaryReader br)
|
||||
internal static Base Load(BinaryReader br, Script script)
|
||||
{
|
||||
var fdeclLen = br.Read<uint>();
|
||||
using (var fdeclMem = new NativeMemoryArray<byte>(fdeclLen, true))
|
||||
@ -39,21 +39,21 @@ namespace IFPSLib.Emit
|
||||
if (fdeclSpan.EqualsAsciiString(0, DllString))
|
||||
{
|
||||
brDecl.BaseStream.Position = DllString.Length;
|
||||
return DLL.Load(brDecl);
|
||||
return DLL.Load(brDecl, script);
|
||||
}
|
||||
else if (fdeclSpan.EqualsAsciiString(0, ClassString))
|
||||
{
|
||||
brDecl.BaseStream.Position = ClassString.Length;
|
||||
return Class.Load(brDecl);
|
||||
return Class.Load(brDecl, script);
|
||||
}
|
||||
else if (fdeclSpan.EqualsAsciiString(0, ComString))
|
||||
{
|
||||
brDecl.BaseStream.Position = ComString.Length;
|
||||
return COM.Load(brDecl);
|
||||
return COM.Load(brDecl, script);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Internal.Load(brDecl);
|
||||
return Internal.Load(brDecl, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,14 +124,17 @@ namespace IFPSLib.Emit
|
||||
|
||||
internal override string Name => string.Format("{0}!{1}", DllName, ProcedureName);
|
||||
|
||||
internal static new DLL Load(BinaryReader br)
|
||||
internal static new DLL Load(BinaryReader br, Script script)
|
||||
{
|
||||
var ret = new DLL();
|
||||
ret.DllName = br.ReadAsciiStringTerminated();
|
||||
ret.ProcedureName = br.ReadAsciiStringTerminated();
|
||||
ret.CallingConvention = (NativeCallingConvention)br.ReadByte();
|
||||
ret.DelayLoad = br.ReadByte() != 0;
|
||||
ret.LoadWithAlteredSearchPath = br.ReadByte() != 0;
|
||||
if (script.FileVersion >= Script.VERSION_MIN_DLL_LOAD_FLAGS)
|
||||
{
|
||||
ret.DelayLoad = br.ReadByte() != 0;
|
||||
ret.LoadWithAlteredSearchPath = br.ReadByte() != 0;
|
||||
}
|
||||
|
||||
ret.LoadArguments(br);
|
||||
|
||||
@ -164,8 +167,11 @@ namespace IFPSLib.Emit
|
||||
bw.WriteAsciiStringTerminated(DllName);
|
||||
bw.WriteAsciiStringTerminated(ProcedureName);
|
||||
bw.Write(CallingConvention);
|
||||
bw.Write<byte>((byte)(DelayLoad ? 1 : 0));
|
||||
bw.Write<byte>((byte)(LoadWithAlteredSearchPath ? 1 : 0));
|
||||
if (ctx.FileVersion >= Script.VERSION_MIN_DLL_LOAD_FLAGS)
|
||||
{
|
||||
bw.Write<byte>((byte)(DelayLoad ? 1 : 0));
|
||||
bw.Write<byte>((byte)(LoadWithAlteredSearchPath ? 1 : 0));
|
||||
}
|
||||
SaveArguments(bw);
|
||||
}
|
||||
}
|
||||
@ -181,7 +187,7 @@ namespace IFPSLib.Emit
|
||||
|
||||
private const byte TERMINATOR = (byte)'|';
|
||||
|
||||
internal static new Class Load(BinaryReader br)
|
||||
internal static new Class Load(BinaryReader br, Script script)
|
||||
{
|
||||
var ret = new Class();
|
||||
|
||||
@ -297,7 +303,7 @@ namespace IFPSLib.Emit
|
||||
|
||||
internal override string Name => string.Format("CoInterface->vtbl[{0}]", VTableIndex);
|
||||
|
||||
internal static new COM Load(BinaryReader br)
|
||||
internal static new COM Load(BinaryReader br, Script script)
|
||||
{
|
||||
var ret = new COM();
|
||||
ret.VTableIndex = br.Read<uint>();
|
||||
@ -325,7 +331,7 @@ namespace IFPSLib.Emit
|
||||
|
||||
public sealed class Internal : Base
|
||||
{
|
||||
internal static new Internal Load(BinaryReader br)
|
||||
internal static new Internal Load(BinaryReader br, Script script)
|
||||
{
|
||||
var ret = new Internal();
|
||||
ret.LoadArguments(br);
|
||||
@ -378,7 +384,7 @@ namespace IFPSLib.Emit
|
||||
ret.Name = br.ReadAsciiString(namelen);
|
||||
if (exported)
|
||||
{
|
||||
ret.Declaration = FDecl.Base.Load(br);
|
||||
ret.Declaration = FDecl.Base.Load(br, script);
|
||||
if (ret.Declaration.HasReturnArgument) ret.ReturnArgument = UnknownType.Instance;
|
||||
if (string.IsNullOrEmpty(ret.Name)) ret.Name = ret.Declaration.Name;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ namespace IFPSLib
|
||||
|
||||
internal const int VERSION_MIN_ATTRIBUTES = 21;
|
||||
internal const int VERSION_MAX_SETSTACKTYPE = 22; // Is this correct?
|
||||
internal const int VERSION_MIN_DLL_LOAD_FLAGS = 23;
|
||||
internal const int VERSION_MIN_STATICARRAYSTART = 23;
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user