Skip to content

Commit 8ebd96a

Browse files
committed
add some improvements
logs are now saved to VMUP_Logs, added function to restore all hooks.
1 parent 1f40be3 commit 8ebd96a

File tree

14 files changed

+107
-93
lines changed

14 files changed

+107
-93
lines changed

README.md

Lines changed: 49 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
```sh
1919
VMUnprotect.exe
2020
-f, --file Required. Path to file.
21-
--usetranspiler (Default: false) Use an older method that makes use of Transpiler (not recommended).
2221
--enableharmonylogs (Default: false) Disable or Enable logs from Harmony.
2322
--bypassantidebug (Default: false) Bypass VMProtect Anti Debug.
2423
--help Display this help screen.
2524
--version Display version information.
2625
```
2726

27+
### Doesn't work? Make sure you dump the file before with:
28+
* [VMUnprotect.Dumper](https://github.com/void-stack/VMUnprotect.Dumper)
29+
2830
# Supported Protections
2931
Note: ***All Supported Protections are working combined***
3032

@@ -38,69 +40,45 @@ Virtualization Tools | ✓
3840
Strip Debug Information | ✓
3941
Pack the Output File | ✓
4042

41-
# Usage can be found in ```MiddleMan```
42-
```csharp
43-
using HarmonyLib;
44-
using System.Diagnostics;
45-
using System.Reflection;
46-
using VMUnprotect.Core.Abstraction;
47-
using VMUnprotect.Core.Helpers;
48-
49-
namespace VMUnprotect.Core.MiddleMan {
50-
/// <summary>
51-
/// Works as Middle Man to make life easier
52-
/// </summary>
53-
public static class UnsafeInvokeMiddleMan {
54-
private static readonly ILogger ConsoleLogger = Engine.Logger;
55-
56-
/// <summary>
57-
/// A prefix is a method that is executed before the original method
58-
/// </summary>
59-
public static void Prefix(ref object __instance, ref object obj, ref object[] parameters, ref object[] arguments) {
60-
var virtualizedMethodName = new StackTrace().GetFrame(7).GetMethod();
61-
var method = (MethodBase) __instance;
62-
63-
ConsoleLogger.Print("VMP MethodName: {0} (MDToken {1:X4})", virtualizedMethodName.FullDescription(), virtualizedMethodName.MetadataToken.ToString());
64-
ConsoleLogger.Print("MethodName: {0}", method.Name);
65-
ConsoleLogger.Print("FullDescription: {0}", method.FullDescription());
66-
ConsoleLogger.Print("MethodType: {0}", method.GetType());
67-
68-
if (obj is not null)
69-
ConsoleLogger.Print("Obj: {0}", obj.GetType());
70-
71-
// Loop through parameters and log them
72-
for (var i = 0; i < parameters.Length; i++) {
73-
var parameter = parameters[i];
74-
ConsoleLogger.Print("Parameter ({1}) [{0}]: ({2})", i, parameter.GetType(), Formatter.FormatObject(parameter));
75-
}
76-
77-
var returnType = method is MethodInfo info ? info.ReturnType.FullName : "System.Object";
78-
ConsoleLogger.Print("MDToken: 0x{0:X4}", method.MetadataToken);
79-
ConsoleLogger.Print("Return Type: {0}", returnType ?? "null");
80-
}
81-
82-
/// <summary>
83-
/// A postfix is a method that is executed after the original method
84-
/// </summary>
85-
public static void Postfix(ref object __instance, ref object __result, ref object obj, ref object[] parameters, ref object[] arguments) {
86-
ConsoleLogger.Print("Returns: {0}", __result);
87-
}
88-
}
89-
}
90-
```
91-
9243
## Current Features
9344
- Tracing invokes in virtualized methods.
9445
- Manipulating parameters and return values.
9546
- Bypass NtQueryInformationProcess, IsLogging, get_IsAttached
9647

48+
## Usage can be found in VMUnprotect.Runtime.MiddleMan
49+
```csharp
50+
/// <summary>
51+
/// A prefix is a method that is executed before the original method
52+
/// </summary>
53+
public bool Prefix(ref object __result, ref object __instance, ref object obj, ref object[] parameters, ref object[] arguments) {
54+
var virtualizedMethodName = new StackTrace().GetFrame(7).GetMethod();
55+
var method = (MethodBase) __instance;
56+
Logger.Print("VMP MethodName: {0} (MDToken 0x{1:X4})", virtualizedMethodName.FullDescription(),
57+
virtualizedMethodName.MetadataToken.ToString());
58+
Logger.Print("MethodName: {0}", method.Name);
59+
Logger.Print("FullDescription: {0}", method.FullDescription());
60+
Logger.Print("MethodType: {0}", method.GetType());
61+
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
62+
if (obj is not null)
63+
Logger.Print("Obj: {0}", Formatter.FormatObject(obj));
64+
// Loop through parameters and log them
65+
for (var i = 0; i < parameters.Length; i++) {
66+
var parameter = parameters[i];
67+
Logger.Print("Parameter ({1}) [{0}]: ({2})", i, parameter.GetType(), Formatter.FormatObject(parameter));
68+
}
69+
var returnType = method is MethodInfo info ? info.ReturnType.FullName : "System.Object";
70+
Logger.Print("MDToken: 0x{0:X4}", method.MetadataToken);
71+
Logger.Print("Return Type: {0}", returnType ?? "null");
72+
return true;
73+
}
9774

98-
## Todo
99-
- Change this to support more VM's
100-
- VMP Stack tracing
101-
- Bypass VMP Debugger Detection ✓
102-
- Bypass VMP CRC Check
103-
- Nice WPF GUI
75+
/// <summary>
76+
/// A postfix is a method that is executed after the original method
77+
/// </summary>
78+
public void Postfix(ref object __instance, ref object __result, ref object obj, ref object[] parameters, ref object[] arguments) {
79+
Logger.Print("Returns: {0}", __result);
80+
}
81+
```
10482

10583
# FAQ
10684
### What is code virtualization?
@@ -109,14 +87,24 @@ As VMProtect describes it on their's website. Code virtualization is the next st
10987
### Can it devirtualize VMP?
11088
No, isn't even meant for devirtualization.
11189

90+
Todo | Done
91+
---------------------------------|---------
92+
Change this to support more VM's | X
93+
VMP Stack tracing | X
94+
Bypass VMP Debugger Detection | ✓
95+
Bypass VMP CRC Check | X
96+
WPF GUI | X
97+
11298
# Credits
11399
* [Washi](https://github.com/Washi1337) Overall credits for the project and inspiration with UnsafeInvokeInternal, thanks <3
114100

115101
This tool uses the following (open source) software:
116102
* [dnlib](https://github.com/0xd4d/dnlib) by [0xd4d](https://github.com/0xd4d), licensed under the MIT license, for reading/writing assemblies.
117103
* [Harmony](https://github.com/pardeike/Harmony) by [Andreas Pardeike](https://github.com/pardeike), licensed under the MIT license
118104
* [Serilog](https://github.com/serilog/serilog) provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API.
105+
* [commandline](https://github.com/commandlineparser/commandline) offers CLR applications a clean and concise API for manipulating command line arguments and related tasks
106+
* [Autofac](https://github.com/autofac/Autofac) Autofac is an IoC container for Microsoft .NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular .NET classes as components.
119107

120-
121-
## Want to support this project?
122-
BTC: bc1q048wrqztka5x2syt9mtj68uuf73vqry60s38vf
108+
## 💵 Want to buy me a Coffee?
109+
- Donate BTC at `bc1q048wrqztka5x2syt9mtj68uuf73vqry60s38vf`
110+
- Donate ETH at `0x86b2C17C94A1E6f35d498d17a37dc1f8A715139b`

VMUP/VMUnprotect.Runtime/General/ContainerConfig.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ public static IContainer Configure(ILogger logger, Project project, CommandLineO
2020
Builder.RegisterType<HooksManager>().As<IHooksManager>().SingleInstance();
2121

2222
Builder.RegisterType<UnsafeInvokeMiddleMan>().As<IUnsafeInvokeMiddleMan>().SingleInstance();
23-
2423
Builder.RegisterType<NtQueryInformationProcessPatch>().As<INtQueryInformationProcessPatch>().SingleInstance();
2524

2625
Builder.RegisterModule(new VmProtectPatchesModule());

VMUP/VMUnprotect.Runtime/General/Engine.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Autofac;
22
using HarmonyLib;
3+
using System;
34
using System.Diagnostics;
45
using System.Runtime.CompilerServices;
56
using VMUnprotect.Runtime.Hooks;
@@ -32,17 +33,19 @@ internal static void Run(Project project) {
3233

3334
using var scope = Container.BeginLifetimeScope();
3435
ctx.Scope = scope;
35-
36+
3637
logger.Debug("Applying VMProtect hooks...");
3738
hooks.Initialize();
3839
hooks.ApplyHooks();
39-
40+
41+
4042
logger.Debug("Invoking Target...");
4143
InvokeTarget(ctx, logger);
4244

4345
stopwatch.Stop();
4446
logger.Info("Finished all tasks in {0}", stopwatch.Elapsed);
45-
ctx.Scope.Dispose();
47+
logger.Info("Restoring Hooks...");
48+
hooks.RestoreAll();
4649
}
4750

4851
private static void InvokeTarget(Context ctx, ILogger logger) {

VMUP/VMUnprotect.Runtime/General/Project.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public void Run(ILogger logger, CommandLineOptions options) {
1515
}
1616

1717
Engine.Initialize(this, logger, options);
18+
19+
1820
Engine.Run(this);
1921
}
2022
}

VMUP/VMUnprotect.Runtime/Hooks/HooksManager.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Autofac;
22
using HarmonyLib;
3+
using System;
34
using System.Collections.Generic;
45
using VMUnprotect.Runtime.General;
56
using VMUnprotect.Runtime.Helpers;
@@ -13,6 +14,21 @@ public class HooksManager : Params, IHooksManager
1314

1415
public HooksManager(Context ctx, ILogger logger) : base(ctx, logger) { }
1516

17+
public void RestoreAll()
18+
{
19+
if (!_isApplied)
20+
{
21+
return;
22+
}
23+
24+
foreach (var patch in Ctx.Scope.Resolve<IEnumerable<IVmupHook>>()) {
25+
Logger.Debug($"Restoring hook {patch.GetType().Name}");
26+
patch.Restore(_harmony);
27+
}
28+
29+
_isApplied = false;
30+
}
31+
1632
public void Initialize() {
1733
if (_isApplied)
1834
return;
@@ -28,7 +44,11 @@ public void ApplyHooks() {
2844

2945
foreach (var patch in Ctx.Scope.Resolve<IEnumerable<IVmupHook>>()) {
3046
Logger.Debug($"Applying hook {patch.GetType().Name}");
31-
patch.Patch(_harmony);
47+
try {
48+
patch.Patch(_harmony);
49+
} catch (Exception e) {
50+
Logger.Error($"Error patching {patch.GetType().Name}. Error: {e.Message}");
51+
}
3252
}
3353

3454
Logger.Info("Completed!");
@@ -39,5 +59,6 @@ public interface IHooksManager
3959
{
4060
void Initialize();
4161
void ApplyHooks();
62+
void RestoreAll();
4263
}
4364
}

VMUP/VMUnprotect.Runtime/Hooks/Methods/AntiDebug/DebugIsAttachedPatch.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,5 @@ public override void Patch(Harmony instance) {
2828
if (Ctx.Options.BypassAntiDebug)
2929
PatchTranspiler(instance, TargetMethod);
3030
}
31-
32-
public override void Restore(Harmony instance) {
33-
//Logger.Debug("Not implemented...");
34-
}
3531
}
3632
}

VMUP/VMUnprotect.Runtime/Hooks/Methods/AntiDebug/DebugIsLoggingPatch.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,5 @@ public override void Patch(Harmony instance) {
2828
if (Ctx.Options.BypassAntiDebug)
2929
PatchTranspiler(instance, TargetMethod);
3030
}
31-
32-
public override void Restore(Harmony instance) {
33-
//Logger.Debug("Not implemented...");
34-
}
3531
}
3632
}

VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetCallingAssemblyPatch.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,5 @@ public static void Postfix(ref Assembly __result) {
2424
public override void Patch(Harmony instance) {
2525
PatchPostfix(instance, TargetMethod);
2626
}
27-
28-
public override void Restore(Harmony instance) {
29-
//Logger.Debug("Not implemented...");
30-
}
3127
}
3228
}

VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetEntryAssemblyPatch.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,5 @@ public override void Patch(Harmony instance) {
2525
PatchPostfix(instance, TargetMethod);
2626
}
2727

28-
public override void Restore(Harmony instance) {
29-
//Logger.Debug("Not implemented...");
30-
}
3128
}
3229
}

VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetExecutingAssemblyPatch.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,5 @@ public static void Postfix(ref Assembly __result) {
2424
public override void Patch(Harmony instance) {
2525
PatchPostfix(instance, TargetMethod);
2626
}
27-
28-
public override void Restore(Harmony instance) {
29-
//Logger.Debug("Not implemented...");
30-
}
3127
}
3228
}

0 commit comments

Comments
 (0)