Skip to content

Commit 8f2fa59

Browse files
committed
Fix #207
1 parent 4e6d293 commit 8f2fa59

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

src/BitMono.Protections/DotNetHook.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public override Task ExecuteAsync()
2020
var listener = new ModifyInjectTypeClonerListener(ModifyFlags.All, _renamer, module);
2121
var memberCloneResult = new MemberCloner(module, listener)
2222
.Include(runtimeHookingType)
23-
.Clone();
23+
.CloneSafely(module, runtimeModule);
2424
var redirectStubMethod = memberCloneResult.GetClonedMember(runtimeRedirectStubMethod);
2525

2626
var factory = module.CorLibTypeFactory;

src/BitMono.Protections/StringsEncryption.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,21 @@ public StringsEncryption(Renamer renamer, IServiceProvider serviceProvider) : ba
1010
_renamer = renamer;
1111
}
1212

13-
[SuppressMessage("ReSharper", "InvertIf")]
1413
public override Task ExecuteAsync()
1514
{
16-
var globalModuleType = Context.Module.GetOrCreateModuleType();
17-
MscorlibInjector.InjectCompilerGeneratedValueType(Context.Module, globalModuleType, _renamer.RenameUnsafely());
18-
var cryptKeyField = MscorlibInjector.InjectCompilerGeneratedArray(Context.Module, globalModuleType, Data.CryptKeyBytes, _renamer.RenameUnsafely());
19-
var saltBytesField = MscorlibInjector.InjectCompilerGeneratedArray(Context.Module, globalModuleType, Data.SaltBytes, _renamer.RenameUnsafely());
15+
var module = Context.Module;
16+
var globalModuleType = module.GetOrCreateModuleType();
17+
MscorlibInjector.InjectCompilerGeneratedValueType(module, globalModuleType, _renamer.RenameUnsafely());
18+
var cryptKeyField = MscorlibInjector.InjectCompilerGeneratedArray(module, globalModuleType, Data.CryptKeyBytes, _renamer.RenameUnsafely());
19+
var saltBytesField = MscorlibInjector.InjectCompilerGeneratedArray(module, globalModuleType, Data.SaltBytes, _renamer.RenameUnsafely());
2020

21-
var runtimeDecryptorType = Context.RuntimeModule.ResolveOrThrow<TypeDefinition>(typeof(Decryptor));
21+
var runtimeModule = Context.RuntimeModule;
22+
var runtimeDecryptorType = runtimeModule.ResolveOrThrow<TypeDefinition>(typeof(Decryptor));
2223
var runtimeDecryptMethod = runtimeDecryptorType.Methods.Single(x => x.Name!.Equals(nameof(Decryptor.Decrypt)));
23-
var listener = new ModifyInjectTypeClonerListener(ModifyFlags.All, _renamer, Context.Module);
24-
var memberCloneResult = new MemberCloner(Context.Module, listener)
24+
var listener = new ModifyInjectTypeClonerListener(ModifyFlags.All, _renamer, module);
25+
var memberCloneResult = new MemberCloner(module, listener)
2526
.Include(runtimeDecryptorType)
26-
.Clone();
27+
.CloneSafely(module, runtimeModule);
2728

2829
var decryptMethod = memberCloneResult.GetClonedMember(runtimeDecryptMethod);
2930

@@ -49,7 +50,7 @@ public override Task ExecuteAsync()
4950

5051
var data = Encryptor.EncryptContent(content, Data.SaltBytes, Data.CryptKeyBytes);
5152
var arrayName = _renamer.RenameUnsafely();
52-
var encryptedDataFieldDef = MscorlibInjector.InjectCompilerGeneratedArray(Context.Module, globalModuleType, data, arrayName);
53+
var encryptedDataFieldDef = MscorlibInjector.InjectCompilerGeneratedArray(module, globalModuleType, data, arrayName);
5354

5455
instruction.ReplaceWith(CilOpCodes.Ldsfld, encryptedDataFieldDef);
5556
instructions.InsertRange(i + 1,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace BitMono.Utilities.AsmResolver;
2+
3+
public static class CloneHelper
4+
{
5+
/// <summary>
6+
/// Clones via AsmResolver's API,
7+
/// but removes the <see cref="cloningModule"/> assembly reference from <see cref="sourceModule"/>.
8+
/// This is needed as a workaround, because sometimes AsmResolver adds
9+
/// a reference of the included item to a <see cref="sourceModule"/>.
10+
/// See here more details about that problem: https://github.com/sunnamed434/BitMono/issues/207
11+
/// </summary>
12+
/// <param name="cloner">The cloner.</param>
13+
/// <param name="sourceModule">The source module.</param>
14+
/// <param name="cloningModule">The cloning module.</param>
15+
/// <returns>The clone result.</returns>
16+
public static MemberCloneResult CloneSafely(this MemberCloner cloner,
17+
ModuleDefinition sourceModule, ModuleDefinition cloningModule)
18+
{
19+
var cloningModuleAssembly = cloningModule.Assembly
20+
?? throw new InvalidOperationException($"{nameof(cloningModule)} assembly was null");
21+
22+
var result = cloner.Clone();
23+
24+
var fullName = cloningModuleAssembly.FullName;
25+
if (sourceModule.AssemblyReferences.FirstOrDefault(
26+
x => x.FullName == fullName) is { } assembly)
27+
{
28+
sourceModule.AssemblyReferences.Remove(assembly);
29+
}
30+
31+
return result;
32+
}
33+
}

src/BitMono.Utilities/GlobalUsings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
global using System.Runtime.InteropServices;
1717
global using System.Runtime.Versioning;
1818
global using System.Text;
19+
global using AsmResolver.DotNet.Cloning;
1920
global using AsmResolver.DotNet.Signatures;
2021
global using AsmResolver.DotNet.Signatures.Parsing;
2122
global using TypeAttributes = AsmResolver.PE.DotNet.Metadata.Tables.TypeAttributes;

0 commit comments

Comments
 (0)