Skip to content

Commit 83174a9

Browse files
committed
Fix .NET 4.8 compatibility
1 parent c3c74c5 commit 83174a9

9 files changed

Lines changed: 391 additions & 388 deletions

File tree

de4dot.code/deobfuscators/dotNET_Reactor/v4/vm/IPattern.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,32 @@ You should have received a copy of the GNU General Public License
2525

2626
namespace de4dot.code.deobfuscators.dotNET_Reactor.v4.vm;
2727

28-
public interface IPattern {
28+
// Note: These should be interfaces in newer .NET versions, but they aren't
29+
// because .NET 4.8 doesn't support default implementations.
30+
31+
public abstract record IPattern {
2932
/// <summary>
3033
/// Contiguous list of opcodes that should match. Nops are wildcards.
3134
/// The pattern does not need to overlap the input completely, i.e., it can be a prefix of the input.
3235
/// </summary>
33-
IList<OpCode> Pattern { get; }
36+
public virtual IList<OpCode> Pattern { get; }
3437

3538
/// <summary>
3639
/// If true, the pattern doesn't need to match from the start.
3740
/// </summary>
38-
bool MatchAnywhere => false;
41+
public virtual bool MatchAnywhere => false;
3942

4043
/// <summary>
4144
/// Does (optional) additional verification on the input if the pattern would not be unique otherwise.
4245
/// </summary>
4346
/// <param name="instructions">Matched instructions from the input.</param>
4447
/// <returns>True if this should indeed be a match.</returns>
45-
bool Verify(IList<Instruction> instructions) => true;
48+
public virtual bool Verify(IList<Instruction> instructions) => true;
4649
}
4750

48-
public interface IOpcodePattern : IPattern {
51+
public abstract record IOpcodePattern : IPattern {
4952
/// <summary>
5053
/// Resulting opcode assigned to the match.
5154
/// </summary>
52-
OpCode Opcode { get; }
55+
public virtual OpCode Opcode { get; }
5356
}

de4dot.code/deobfuscators/dotNET_Reactor/v4/vm/PatternHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ public static bool FindPatternInOverridesCall(this MethodDef? virtualMethod, IPa
5858
var firstOverride = t.Methods.FirstOrDefault(m => m.IsVirtual && m.HasBody
5959
&& m.Name == virtualMethod.Name
6060
&& m.Body.Instructions.Count >= 3
61-
&& m.Body.Instructions[^2].OpCode == OpCodes.Callvirt);
61+
&& m.Body.Instructions[m.Body.Instructions.Count - 2].OpCode == OpCodes.Callvirt); // net48 compat
6262
if (firstOverride == null)
6363
continue;
6464

65-
var calledInOverride = ((MethodDef)firstOverride.Body.Instructions[^2].Operand).Name;
65+
var calledInOverride = ((MethodDef)firstOverride.Body.Instructions[firstOverride.Body.Instructions.Count - 2].Operand).Name; // net48 compat
6666
foreach (var t2 in virtualMethod.Module.GetTypes()) {
6767
foreach (var callee in t2.Methods.Where(m => m.IsVirtual && m.HasBody && m.Name == calledInOverride)) {
6868
if (PatternMatcher.Match(pattern, callee.Body.Instructions))

de4dot.code/deobfuscators/dotNET_Reactor/v4/vm/PatternMatcher.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ public PatternMatcher()
3939
_opcodes = new Dictionary<int, IOpcodePattern>();
4040
_opcodePatterns = new List<IOpcodePattern>();
4141
foreach (var type in typeof(PatternMatcher).Assembly.GetTypes())
42-
if (type.GetInterface(nameof(IOpcodePattern)) != null)
42+
if (!type.IsAbstract && typeof(IOpcodePattern).IsAssignableFrom(type))
4343
if (Activator.CreateInstance(type) is IOpcodePattern instance)
4444
_opcodePatterns.Add(instance);
4545
}
4646

47-
public IOpcodePattern? GetOpcode(int vmOpcode) => _opcodes.GetValueOrDefault(vmOpcode);
47+
public IOpcodePattern? GetOpcode(int vmOpcode) => _opcodes.TryGetValue(vmOpcode, out var res) ? res : null; // net48 compat
4848

4949
public void MatchAll(HandlerMapper mapper) {
5050
int numMatched = 0;

0 commit comments

Comments
 (0)