├── .deepsource.toml ├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── VMUP ├── .editorconfig ├── VMUP.sln ├── VMUnprotect.Runtime │ ├── General │ │ ├── AssemblyLoader.cs │ │ ├── CommandLineOptions.cs │ │ ├── ContainerConfig.cs │ │ ├── Context.cs │ │ ├── Engine.cs │ │ ├── ILogger.cs │ │ └── Project.cs │ ├── Helpers │ │ ├── Formatter.cs │ │ ├── Params.cs │ │ └── StringCounts.cs │ ├── Hooks │ │ ├── HooksManager.cs │ │ ├── IVmupHook.cs │ │ ├── Methods │ │ │ ├── AntiDebug │ │ │ │ ├── DebugIsAttachedPatch.cs │ │ │ │ ├── DebugIsLoggingPatch.cs │ │ │ │ └── NtQueryInformationProcessPatch.cs │ │ │ ├── AssemblyFix │ │ │ │ ├── GetCallingAssemblyPatch.cs │ │ │ │ ├── GetEntryAssemblyPatch.cs │ │ │ │ └── GetExecutingAssemblyPatch.cs │ │ │ ├── VmProtectDumperTranspiler.cs │ │ │ └── VmProtectDumperUnsafeInvoke.cs │ │ └── VmUnprotectPatch.cs │ ├── MiddleMan │ │ ├── TranspilerMiddleMan.cs │ │ └── UnsafeInvokeMiddleMan.cs │ ├── Modules │ │ └── VmProtectPatchesModule.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Structure │ │ ├── VmRuntimeAnalyzer.cs │ │ └── VmRuntimeStructure.cs │ ├── VMUnprotect.Runtime.csproj │ └── packages.config └── VMUnprotect │ ├── FodyWeavers.xml │ ├── FodyWeavers.xsd │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Utils │ └── ConsoleLogger.cs │ ├── VMUnprotect.csproj │ ├── manifest.manifest │ ├── packages.config │ └── vmup.ico └── docs ├── desktop.ini ├── gif.gif ├── screen2.png ├── show.gif └── vmup.png /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "csharp" 5 | enabled = true -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [void-stack] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | VMUP/VMUnprotect/VMUnprotect.csproj.DotSettings 336 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 void 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

VMUnprotect.NET

4 |

5 | VMUnprotect is a project engaged in hunting virtualized VMProtect methods. It makes use of Harmony to dynamically read VMP behavior. Currently only supports method administration. Works on VMProtect 3.6.0 (Latest) and few versions back. 6 |

7 |

8 |

9 | appveyor-ci 10 | appveyor-ci 11 |

12 |

13 | 14 | ## Showcase 15 | 16 | 17 | # Usage 18 | ```sh 19 | VMUnprotect.exe 20 | -f, --file Required. Path to file. 21 | --enableharmonylogs (Default: false) Disable or Enable logs from Harmony. 22 | --bypassantidebug (Default: false) Bypass VMProtect Anti Debug. 23 | --help Display this help screen. 24 | --version Display version information. 25 | ``` 26 | 27 | ### Doesn't work? Make sure you dump the file before with: 28 | * [VMUnprotect.Dumper](https://github.com/void-stack/VMUnprotect.Dumper) 29 | 30 | # Supported Protections 31 | Note: ***All Supported Protections are working combined*** 32 | 33 | Protection Name | Is supported 34 | ------------------------|-------------- 35 | Memory Protection | ✓ 36 | Import Protection | ✓ 37 | Resource Protection | ✓ 38 | Debugger Detection | ✓ 39 | Virtualization Tools | ✓ 40 | Strip Debug Information | ✓ 41 | Pack the Output File | ✓ 42 | 43 | ## Current Features 44 | - Tracing invokes in virtualized methods. 45 | - Manipulating parameters and return values. 46 | - Bypass NtQueryInformationProcess, IsLogging, get_IsAttached 47 | 48 | ## Usage can be found in VMUnprotect.Runtime.MiddleMan 49 | ```csharp 50 | /// 51 | /// A prefix is a method that is executed before the original method 52 | /// 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 | } 74 | 75 | /// 76 | /// A postfix is a method that is executed after the original method 77 | /// 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 | ``` 82 | 83 | # FAQ 84 | ### What is code virtualization? 85 | As VMProtect describes it on their's website. Code virtualization is the next step in software protection. Most protection systems encrypt the code and then decrypt it at the application’s startup. VMProtect doesn’t decrypt the code at all! Instead, the encrypted code runs on a virtual CPU that is markedly different from generic x86 and x64 CPUs as the command set is different for each protected file. 86 | 87 | ### Can it devirtualize VMP? 88 | No, isn't even meant for devirtualization. 89 | 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 | 98 | 99 | # Credits, checkout my blog about [VMUnprotect](https://void-stack.github.io) 100 | * [Washi](https://github.com/Washi1337) Overall credits for the project and inspiration with UnsafeInvokeInternal, thanks <3 101 | 102 | This tool uses the following (open source) software: 103 | * [dnlib](https://github.com/0xd4d/dnlib) by [0xd4d](https://github.com/0xd4d), licensed under the MIT license, for reading/writing assemblies. 104 | * [Harmony](https://github.com/pardeike/Harmony) by [Andreas Pardeike](https://github.com/pardeike), licensed under the MIT license 105 | * [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. 106 | * [commandline](https://github.com/commandlineparser/commandline) offers CLR applications a clean and concise API for manipulating command line arguments and related tasks 107 | * [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. 108 | 109 | ## 💵 Want to buy me a Coffee? 110 | - Donate BTC at `bc1q048wrqztka5x2syt9mtj68uuf73vqry60s38vf` 111 | - Donate ETH at `0x86b2C17C94A1E6f35d498d17a37dc1f8A715139b` 112 | -------------------------------------------------------------------------------- /VMUP/.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*] 3 | charset = utf-8 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | 10 | # Microsoft .NET properties 11 | csharp_new_line_before_members_in_object_initializers = false 12 | csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion 13 | csharp_style_var_elsewhere = true:suggestion 14 | csharp_style_var_for_built_in_types = false:suggestion 15 | csharp_style_var_when_type_is_apparent = true:suggestion 16 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none 17 | dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none 18 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none 19 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 20 | dotnet_style_predefined_type_for_member_access = true:suggestion 21 | dotnet_style_qualification_for_event = false:suggestion 22 | dotnet_style_qualification_for_field = false:suggestion 23 | dotnet_style_qualification_for_method = false:suggestion 24 | dotnet_style_qualification_for_property = false:suggestion 25 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion 26 | 27 | # ReSharper properties 28 | resharper_autodetect_indent_settings = true 29 | resharper_csharp_wrap_before_binary_opsign = true 30 | resharper_csharp_wrap_before_first_type_parameter_constraint = true 31 | resharper_keep_existing_embedded_arrangement = false 32 | resharper_keep_existing_switch_expression_arrangement = false 33 | resharper_max_array_initializer_elements_on_line = 20 34 | resharper_max_enum_members_on_line = 1 35 | resharper_max_initializer_elements_on_line = 1 36 | resharper_place_abstract_accessorholder_on_single_line = false 37 | resharper_place_attribute_on_same_line = false 38 | resharper_place_constructor_initializer_on_same_line = false 39 | resharper_place_simple_embedded_statement_on_same_line = false 40 | resharper_place_simple_initializer_on_single_line = false 41 | resharper_show_autodetect_configure_formatting_tip = false 42 | resharper_use_indent_from_vs = false 43 | resharper_wrap_array_initializer_style = chop_if_long 44 | 45 | # ReSharper inspection severities 46 | resharper_arrange_redundant_parentheses_highlighting = hint 47 | resharper_arrange_this_qualifier_highlighting = hint 48 | resharper_arrange_type_member_modifiers_highlighting = hint 49 | resharper_arrange_type_modifiers_highlighting = hint 50 | resharper_built_in_type_reference_style_for_member_access_highlighting = hint 51 | resharper_built_in_type_reference_style_highlighting = hint 52 | resharper_inconsistent_naming_highlighting = hint 53 | resharper_introduce_optional_parameters_global_highlighting = none 54 | resharper_loop_can_be_converted_to_query_highlighting = none 55 | resharper_redundant_base_qualifier_highlighting = warning 56 | resharper_shift_expression_real_shift_count_is_zero_highlighting = hint 57 | resharper_shift_expression_result_equals_zero_highlighting = hint 58 | resharper_shift_expression_zero_left_operand_highlighting = hint 59 | resharper_suggest_var_or_type_built_in_types_highlighting = hint 60 | resharper_suggest_var_or_type_elsewhere_highlighting = hint 61 | resharper_suggest_var_or_type_simple_types_highlighting = hint 62 | resharper_unused_member_global_highlighting = hint 63 | resharper_web_config_module_not_resolved_highlighting = warning 64 | resharper_web_config_type_not_resolved_highlighting = warning 65 | resharper_web_config_wrong_module_highlighting = warning 66 | 67 | [{*.bash,*.sh,*.zsh}] 68 | indent_style = space 69 | indent_size = 2 70 | 71 | [{*.yaml,*.yml}] 72 | indent_style = space 73 | indent_size = 2 74 | 75 | [*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}] 76 | indent_style = space 77 | indent_size = 4 78 | tab_width = 4 -------------------------------------------------------------------------------- /VMUP/VMUP.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMUnprotect", "VMUnprotect\VMUnprotect.csproj", "{42C88429-9A67-4087-91BD-7D76383BC86D}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMUnprotect.Runtime", "VMUnprotect.Runtime\VMUnprotect.Runtime.csproj", "{3EE03C52-C17B-4771-BF5A-32D04A2D435E}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {42C88429-9A67-4087-91BD-7D76383BC86D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {42C88429-9A67-4087-91BD-7D76383BC86D}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {42C88429-9A67-4087-91BD-7D76383BC86D}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {42C88429-9A67-4087-91BD-7D76383BC86D}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {3EE03C52-C17B-4771-BF5A-32D04A2D435E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {3EE03C52-C17B-4771-BF5A-32D04A2D435E}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {3EE03C52-C17B-4771-BF5A-32D04A2D435E}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {3EE03C52-C17B-4771-BF5A-32D04A2D435E}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/AssemblyLoader.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using System; 3 | using System.Reflection; 4 | using VMUnprotect.Runtime.Helpers; 5 | 6 | namespace VMUnprotect.Runtime.General 7 | { 8 | internal class AssemblyLoader : Params, IAssemblyLoader 9 | { 10 | public AssemblyLoader(Context ctx, ILogger logger) : base(ctx, logger) { } 11 | 12 | public void LoadAssembly() { 13 | var assembly = Ctx.Project.TargetFilePath; 14 | 15 | try { 16 | Ctx.Module = ModuleDefMD.Load(assembly); 17 | Ctx.Assembly = Assembly.LoadFile(assembly); 18 | Logger.Info("Loaded assembly '{0}'", Ctx.Module.Name); 19 | } catch (Exception exception) { 20 | Logger.Info("Failed to load assembly '{0}'", assembly); 21 | Logger.Error($"Stacktrace: {exception}"); 22 | Environment.Exit(0); 23 | } 24 | } 25 | } 26 | 27 | public interface IAssemblyLoader 28 | { 29 | void LoadAssembly(); 30 | } 31 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/CommandLineOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace VMUnprotect.Runtime.General 4 | { 5 | public class CommandLineOptions 6 | { 7 | [Option('f', "file", HelpText = "Path to file.", Required = true)] 8 | public string FilePath { get; set; } = null!; 9 | 10 | /*[Option(Default = false, HelpText = "Use an older method that makes use of Transpiler (not recommended).", 11 | Required = false)] 12 | public bool UseTranspiler { get; set; }*/ 13 | 14 | [Option(Default = false, HelpText = "Disable or Enable logs from Harmony.", Required = false)] 15 | public bool EnableHarmonyLogs { get; set; } 16 | 17 | [Option(Default = false, HelpText = "Bypass VMProtect Anti Debug.", Required = false)] 18 | public bool BypassAntiDebug { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/ContainerConfig.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using VMUnprotect.Runtime.Hooks; 3 | using VMUnprotect.Runtime.Hooks.Methods.AntiDebug; 4 | using VMUnprotect.Runtime.MiddleMan; 5 | using VMUnprotect.Runtime.Modules; 6 | using VMUnprotect.Runtime.Structure; 7 | 8 | namespace VMUnprotect.Runtime.General 9 | { 10 | internal static class ContainerConfig 11 | { 12 | private static ContainerBuilder Builder { get; set; } 13 | 14 | public static IContainer Configure(ILogger logger, Project project, CommandLineOptions options) { 15 | Builder = new ContainerBuilder(); 16 | 17 | Builder.RegisterInstance(logger).As().SingleInstance(); 18 | Builder.RegisterType().As().SingleInstance(); 19 | Builder.RegisterType().As().SingleInstance(); 20 | Builder.RegisterType().As().SingleInstance(); 21 | 22 | Builder.RegisterType().As().SingleInstance(); 23 | Builder.RegisterType().As().SingleInstance(); 24 | 25 | Builder.RegisterModule(new VmProtectPatchesModule()); 26 | 27 | logger.Debug("Creating context..."); 28 | Builder.RegisterInstance(new Context(project, logger, options)).As().SingleInstance(); 29 | 30 | return Builder.Build(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/Context.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using dnlib.DotNet; 3 | using HarmonyLib; 4 | using System.Reflection; 5 | using VMUnprotect.Runtime.Structure; 6 | 7 | namespace VMUnprotect.Runtime.General 8 | { 9 | public class Context 10 | { 11 | public Context(Project project, ILogger logger, CommandLineOptions options) { 12 | Logger = logger; 13 | Project = project; 14 | Options = options; 15 | } 16 | 17 | public Project Project { get; } 18 | public Assembly Assembly { get; internal set; } 19 | public ModuleDef Module { get; internal set; } 20 | public Harmony Harmony { get; internal set; } 21 | public CommandLineOptions Options { get; } 22 | public VmRuntimeStructure VmRuntimeStructure { get; internal set; } 23 | 24 | public ILogger Logger { get; } 25 | public ILifetimeScope Scope { get; internal set; } 26 | } 27 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/Engine.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using HarmonyLib; 3 | using System.Diagnostics; 4 | using System.Runtime.CompilerServices; 5 | using VMUnprotect.Runtime.Hooks; 6 | using VMUnprotect.Runtime.Structure; 7 | 8 | namespace VMUnprotect.Runtime.General 9 | { 10 | internal static class Engine 11 | { 12 | private static IContainer Container { get; set; } 13 | 14 | internal static void Initialize(Project project, ILogger logger, CommandLineOptions options) { 15 | logger.Info("initializing Engine..."); 16 | Container = ContainerConfig.Configure(logger, project, options); 17 | } 18 | 19 | internal static void Run(Project project) { 20 | var logger = Container.Resolve(); 21 | var ctx = Container.Resolve(); 22 | var hooks = Container.Resolve(); 23 | 24 | logger.Info("Starting..."); 25 | var stopwatch = Stopwatch.StartNew(); 26 | 27 | logger.Debug("Loading sample..."); 28 | Container.Resolve().LoadAssembly(); 29 | 30 | logger.Debug("Discovering VMProtect Runtime..."); 31 | Container.Resolve().Discover(); 32 | 33 | using var scope = Container.BeginLifetimeScope(); 34 | ctx.Scope = scope; 35 | 36 | logger.Debug("Applying VMProtect hooks..."); 37 | hooks.Initialize(); 38 | hooks.ApplyHooks(); 39 | 40 | 41 | logger.Debug("Invoking Target..."); 42 | InvokeTarget(ctx, logger); 43 | 44 | stopwatch.Stop(); 45 | logger.Info("Finished all tasks in {0}", stopwatch.Elapsed); 46 | logger.Info("Restoring Hooks..."); 47 | hooks.RestoreAll(); 48 | } 49 | 50 | private static void InvokeTarget(Context ctx, ILogger logger) { 51 | 52 | var fileEntryPoint = ctx.Assembly.EntryPoint; 53 | var moduleHandle = ctx.Assembly.ManifestModule.ModuleHandle; 54 | var parameters = fileEntryPoint.GetParameters(); 55 | 56 | logger.Debug("Entrypoint method: {0}", fileEntryPoint.FullDescription()); 57 | logger.Debug("ModuleHandle: {0:X4}", moduleHandle); 58 | 59 | logger.Info("--- Invoking Constructor."); 60 | RuntimeHelpers.RunModuleConstructor(moduleHandle); 61 | 62 | logger.Info("--- Invoking assembly.\n"); 63 | fileEntryPoint.Invoke( 64 | null, 65 | parameters.Length == 0 ? null : new object[] {new[] {string.Empty}}); // parse arguments from commandlineoptions 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace VMUnprotect.Runtime.General 2 | { 3 | public interface ILogger 4 | { 5 | public void Debug(string m, params object[] f); 6 | public void Error(string m, params object[] f); 7 | public void Info(string m, params object[] f); 8 | public void Warn(string m, params object[] f); 9 | public void Print(string m, params object[] f); 10 | } 11 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/General/Project.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace VMUnprotect.Runtime.General 5 | { 6 | public class Project 7 | { 8 | public string TargetFilePath { get; set; } 9 | 10 | public void Run(ILogger logger, CommandLineOptions options) { 11 | if (!File.Exists(TargetFilePath)) { 12 | logger.Error($"{TargetFilePath} is not a file or it does not exist"); 13 | Console.ReadLine(); 14 | return; 15 | } 16 | 17 | Engine.Initialize(this, logger, options); 18 | 19 | 20 | Engine.Run(this); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Helpers/Formatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Linq; 4 | 5 | namespace VMUnprotect.Runtime.Helpers 6 | { 7 | public static class Formatter 8 | { 9 | /// 10 | /// Formats code to more reliable format 11 | /// 12 | public static string FormatObject(object obj) { 13 | try { 14 | return obj switch { 15 | null => "null", 16 | string x => $"\"{x}\"", 17 | IEnumerable enumerable => 18 | $"{obj.GetType().Name} {{{string.Join(", ", enumerable.Cast().Select(FormatObject))}}}", 19 | var _ => obj.ToString() 20 | }; 21 | } catch (Exception) { 22 | return "???"; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Helpers/Params.cs: -------------------------------------------------------------------------------- 1 | using VMUnprotect.Runtime.General; 2 | 3 | namespace VMUnprotect.Runtime.Helpers 4 | { 5 | public abstract class Params 6 | { 7 | internal static Context Ctx; 8 | internal static ILogger Logger; 9 | 10 | protected Params(Context ctx, ILogger logger) { 11 | Ctx = ctx; 12 | Logger = logger; 13 | 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Helpers/StringCounts.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace VMUnprotect.Runtime.Helpers 8 | { 9 | public class StringCounts 10 | { 11 | private readonly Dictionary _strings = new(StringComparer.Ordinal); 12 | 13 | public IEnumerable Strings => _strings.Keys; 14 | public int NumStrings => _strings.Count; 15 | 16 | protected void Add(string s) { 17 | _strings.TryGetValue(s, out var count); 18 | _strings[s] = count + 1; 19 | } 20 | 21 | private bool Exists(string s) { 22 | return _strings.ContainsKey(s); 23 | } 24 | 25 | public bool All(IEnumerable list) { 26 | return list.All(Exists); 27 | } 28 | 29 | public bool Exactly(ICollection list) { 30 | return list.Count == _strings.Count && All(list); 31 | } 32 | 33 | public int Count(string s) { 34 | _strings.TryGetValue(s, out var count); 35 | return count; 36 | } 37 | } 38 | 39 | 40 | public class LocalTypes : StringCounts 41 | { 42 | public LocalTypes(MethodDef method) { 43 | if (method is {Body: { }}) Initialize(method.Body.Variables); 44 | } 45 | 46 | public LocalTypes(IEnumerable locals) { 47 | Initialize(locals); 48 | } 49 | 50 | private void Initialize(IEnumerable locals) { 51 | foreach (var local in locals) Add(local.Type.FullName); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/HooksManager.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using HarmonyLib; 3 | using System; 4 | using System.Collections.Generic; 5 | using VMUnprotect.Runtime.General; 6 | using VMUnprotect.Runtime.Helpers; 7 | 8 | namespace VMUnprotect.Runtime.Hooks 9 | { 10 | public class HooksManager : Params, IHooksManager 11 | { 12 | private readonly Harmony _harmony = new("com.hussaryyn.vmup"); 13 | private bool _isApplied; 14 | 15 | public HooksManager(Context ctx, ILogger logger) : base(ctx, logger) { } 16 | 17 | public void RestoreAll() { 18 | if (!_isApplied) 19 | return; 20 | 21 | foreach (var patch in Ctx.Scope.Resolve>()) { 22 | Logger.Debug($"Restoring hook {patch.GetType().Name}"); 23 | patch.Restore(_harmony); 24 | } 25 | 26 | _isApplied = false; 27 | } 28 | 29 | public void Initialize() { 30 | if (_isApplied) 31 | return; 32 | 33 | Logger.Info("Starting"); 34 | Harmony.DEBUG = Ctx.Options.EnableHarmonyLogs; 35 | 36 | _isApplied = true; 37 | } 38 | 39 | public void ApplyHooks() { 40 | Logger.Info("Patching..."); 41 | 42 | foreach (var patch in Ctx.Scope.Resolve>()) { 43 | Logger.Debug($"Applying hook {patch.GetType().Name}"); 44 | try { 45 | patch.Patch(_harmony); 46 | } catch (Exception e) { 47 | Logger.Error($"Error patching {patch.GetType().Name}. Error: {e.Message}"); 48 | } 49 | } 50 | 51 | Logger.Info("Completed!"); 52 | } 53 | } 54 | 55 | public interface IHooksManager 56 | { 57 | void Initialize(); 58 | void ApplyHooks(); 59 | void RestoreAll(); 60 | } 61 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/IVmupHook.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | 3 | namespace VMUnprotect.Runtime.Hooks 4 | { 5 | public interface IVmupHook 6 | { 7 | void Patch(Harmony instance); 8 | void Restore(Harmony instance); 9 | } 10 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AntiDebug/DebugIsAttachedPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using VMUnprotect.Runtime.General; 8 | 9 | namespace VMUnprotect.Runtime.Hooks.Methods.AntiDebug 10 | { 11 | public class DebugIsAttachedPatch : VmUnprotectPatch 12 | { 13 | private static readonly MethodInfo TargetMethod = AccessTools.Method(typeof(Debugger), "get_IsAttached"); 14 | 15 | public DebugIsAttachedPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 16 | 17 | public static IEnumerable Transpiler(IEnumerable instructions) { 18 | var codes = new List(instructions) { 19 | new(OpCodes.Ldc_I4_0), 20 | new(OpCodes.Ret) 21 | }; 22 | 23 | Logger.Debug($"Recompiled {nameof(TargetMethod)} body to IL and forced to return: false"); 24 | return codes.AsEnumerable(); 25 | } 26 | 27 | public override void Patch(Harmony instance) { 28 | if (Ctx.Options.BypassAntiDebug) 29 | PatchTranspiler(instance, TargetMethod); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AntiDebug/DebugIsLoggingPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using VMUnprotect.Runtime.General; 8 | 9 | namespace VMUnprotect.Runtime.Hooks.Methods.AntiDebug 10 | { 11 | public class DebugIsLoggingPatch : VmUnprotectPatch 12 | { 13 | private static readonly MethodInfo TargetMethod = AccessTools.Method(typeof(Debugger), nameof(Debugger.IsLogging)); 14 | 15 | public DebugIsLoggingPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 16 | 17 | public static IEnumerable Transpiler(IEnumerable instructions) { 18 | var codes = new List(instructions) { 19 | new(OpCodes.Ldc_I4_0), 20 | new(OpCodes.Ret) 21 | }; 22 | 23 | Logger.Debug($"Recompiled {nameof(Debugger.IsLogging)} body to IL and forced to return: false"); 24 | return codes.AsEnumerable(); 25 | } 26 | 27 | public override void Patch(Harmony instance) { 28 | if (Ctx.Options.BypassAntiDebug) 29 | PatchTranspiler(instance, TargetMethod); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AntiDebug/NtQueryInformationProcessPatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using VMUnprotect.Runtime.General; 4 | using VMUnprotect.Runtime.Helpers; 5 | 6 | namespace VMUnprotect.Runtime.Hooks.Methods.AntiDebug 7 | { 8 | public class NtQueryInformationProcessPatch : Params, INtQueryInformationProcessPatch 9 | { 10 | private IntPtr _ntQueryInformationProcessPtr = new(0x0); 11 | public NtQueryInformationProcessPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 12 | private Delegate NtQueryInformationProcessDelegate { get; set; } 13 | 14 | //__kernel_entry NTSTATUS NtQueryInformationProcess( 15 | // [in] HANDLE ProcessHandle, 16 | // [in] PROCESSINFOCLASS ProcessInformationClass, 17 | // [out] PVOID ProcessInformation, 18 | // [in] ULONG ProcessInformationLength, 19 | // [out, optional] PULONG ReturnLength 20 | //); 21 | public void OverwriteProcessInformation(object obj, ref object[] arguments) { 22 | if (obj is not null && obj.Equals(NtQueryInformationProcessDelegate)) 23 | arguments[2] = (IntPtr) 0x0; // [out] PVOID ProcessInformation = 0x0 // We don't care about this structure 24 | } 25 | 26 | public void GetDelegateForFunctionPointer(object __result, object[] parameters) { 27 | if (parameters == null) 28 | return; 29 | 30 | if (parameters.Any(x => x.Equals("NtQueryInformationProcess"))) 31 | _ntQueryInformationProcessPtr = (IntPtr) __result; 32 | 33 | if (parameters.Any(x => x.Equals(_ntQueryInformationProcessPtr) && 34 | _ntQueryInformationProcessPtr != new IntPtr(0x0))) 35 | NtQueryInformationProcessDelegate = (Delegate) __result; 36 | } 37 | } 38 | 39 | public interface INtQueryInformationProcessPatch 40 | { 41 | public void OverwriteProcessInformation(object obj, ref object[] arguments); 42 | public void GetDelegateForFunctionPointer(object __result, object[] parameters); 43 | } 44 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetCallingAssemblyPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Reflection; 3 | using VMUnprotect.Runtime.General; 4 | 5 | // ReSharper disable InconsistentNaming 6 | 7 | namespace VMUnprotect.Runtime.Hooks.Methods.AssemblyFix 8 | { 9 | public class GetCallingAssemblyPatch : VmUnprotectPatch 10 | { 11 | private static readonly MethodInfo TargetMethod = 12 | AccessTools.Method(typeof(Assembly), nameof(Assembly.GetCallingAssembly)); 13 | 14 | public GetCallingAssemblyPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 15 | 16 | public static void Postfix(ref Assembly __result) { 17 | if (__result != typeof(string).Assembly) 18 | return; 19 | 20 | //MessageBox.Show($"Swapped {__result.FullName} | GetCallingAssembly", "GetCallingAssembly"); 21 | __result = Ctx.Assembly; 22 | } 23 | 24 | public override void Patch(Harmony instance) { 25 | PatchPostfix(instance, TargetMethod); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetEntryAssemblyPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Reflection; 3 | using VMUnprotect.Runtime.General; 4 | 5 | // ReSharper disable InconsistentNaming 6 | 7 | namespace VMUnprotect.Runtime.Hooks.Methods.AssemblyFix 8 | { 9 | public class GetEntryAssemblyPatch : VmUnprotectPatch 10 | { 11 | private static readonly MethodInfo TargetMethod = 12 | AccessTools.Method(typeof(Assembly), nameof(Assembly.GetEntryAssembly)); 13 | 14 | public GetEntryAssemblyPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 15 | 16 | public static void Postfix(ref Assembly __result) { 17 | if (__result != typeof(string).Assembly) 18 | return; 19 | 20 | //MessageBox.Show($"Swapped {__result.FullName} | GetCallingAssembly", "GetCallingAssembly"); 21 | __result = Ctx.Assembly; 22 | } 23 | 24 | public override void Patch(Harmony instance) { 25 | PatchPostfix(instance, TargetMethod); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/AssemblyFix/GetExecutingAssemblyPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Reflection; 3 | using VMUnprotect.Runtime.General; 4 | 5 | // ReSharper disable InconsistentNaming 6 | 7 | namespace VMUnprotect.Runtime.Hooks.Methods.AssemblyFix 8 | { 9 | public class GetExecutingAssemblyPatch : VmUnprotectPatch 10 | { 11 | private static readonly MethodInfo TargetMethod = 12 | AccessTools.Method(typeof(Assembly), nameof(Assembly.GetExecutingAssembly)); 13 | 14 | public GetExecutingAssemblyPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 15 | 16 | public static void Postfix(ref Assembly __result) { 17 | if (__result != typeof(string).Assembly) 18 | return; 19 | 20 | //MessageBox.Show($"Swapped {__result.FullName} | GetExecutingAssembly", "GetExecutingAssembly"); 21 | __result = Ctx.Assembly; 22 | } 23 | 24 | public override void Patch(Harmony instance) { 25 | PatchPostfix(instance, TargetMethod); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/VmProtectDumperTranspiler.cs: -------------------------------------------------------------------------------- 1 | /*using Autofac; 2 | using HarmonyLib; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Globalization; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Reflection.Emit; 9 | using VMUnprotect.Runtime.General; 10 | using VMUnprotect.Runtime.MiddleMan; 11 | 12 | namespace VMUnprotect.Runtime.Hooks.Methods 13 | { 14 | public class VmProtectDumperTranspiler : VmUnprotectPatch 15 | { 16 | public VmProtectDumperTranspiler(Context ctx, ILogger logger) : base(ctx, logger) { } 17 | 18 | public static object HookedInvoke( 19 | object obj, 20 | BindingFlags bindingFlags, 21 | Binder binder, 22 | object[] parameters, 23 | CultureInfo culture, 24 | MethodBase methodBase) { 25 | try { 26 | // Indicate this method was called by newer version of VMP. 27 | Logger.Warn( 28 | "============================================= HookedInvoke =============================================\n"); 29 | 30 | // Route the arguments and return value to our middleman function where they can be manipulated or logged. 31 | return Ctx.Scope.Resolve().Log(obj, null, null, ref parameters, null, methodBase); 32 | } catch (Exception ex) { 33 | // Log the exception. 34 | Logger.Error(ex.ToString()); 35 | return null; 36 | } 37 | } 38 | 39 | public static object HookedInvokeOld(object obj, object[] parameters, MethodBase methodBase) { 40 | try { 41 | // Indicate this method was called by older version of VMP. 42 | Logger.Warn( 43 | "============================================= HookedInvokeOld =============================================\n"); 44 | 45 | // Route the arguments and return value to our middleman function where they can be manipulated or logged. 46 | return Ctx.Scope.Resolve().Log(obj, null, null, ref parameters, null, methodBase); 47 | } catch (Exception ex) { 48 | // Log the exception. 49 | Logger.Error(ex.ToString()); 50 | return null; 51 | } 52 | } 53 | 54 | /// A transpiler that replaces all occurrences of a given method with another with additional Ldarg_1 instruction 55 | /// The enumeration of to act on 56 | /// Method to search for 57 | /// Method to replace with 58 | /// Modified enumeration of 59 | private static void ReplaceVmpInvoke(ref IEnumerable instructions, MethodBase @from, MethodBase to) { 60 | if ((object) from == null) throw new ArgumentException("Unexpected null argument", nameof(from)); 61 | if ((object) to == null) throw new ArgumentException("Unexpected null argument", nameof(to)); 62 | 63 | var code = new List(instructions); 64 | 65 | for (var x = 0; x < code.Count; x++) { 66 | var ins = code[x]; 67 | if (ins.operand as MethodBase != from) continue; 68 | 69 | // replace callvirt Invoke with our debug invoke. 70 | ins.opcode = OpCodes.Callvirt; 71 | ins.operand = to; 72 | 73 | // insert additional Ldarg_1 which corresponds to MethodBase of invoked function. 74 | // TODO: Improve this, can be easily broken by obfuscation or future VMP updates 75 | code.Insert(x, new CodeInstruction(OpCodes.Ldarg_1)); 76 | Logger.Info("Replaced with custom Invoke and injected MethodBase argument at {0}.", x); 77 | } 78 | 79 | } 80 | 81 | /// A transpiler that alters instructions that calls specific method 82 | /// The enumeration of to act on 83 | /// Modified enumeration of 84 | public static IEnumerable Transpiler(IEnumerable instructions) { 85 | Logger.Debug("VMP Function Handler Transpiler"); 86 | 87 | // Newer version 88 | ReplaceVmpInvoke(ref instructions, AccessTools.Method(typeof(MethodBase), "Invoke", new[] { 89 | typeof(object), typeof(BindingFlags), typeof(Binder), typeof(object[]), 90 | typeof(CultureInfo) 91 | }), AccessTools.Method(typeof(VmProtectDumperTranspiler), nameof(HookedInvoke))); 92 | 93 | // Older version 94 | /*ReplaceVmpInvoke(ref instructions, 95 | AccessTools.Method(typeof(MethodBase), "Invoke", new[] {typeof(object), typeof(object[])}), 96 | AccessTools.Method(typeof(VmProtectDumperTranspiler), nameof(HookedInvokeOld)));#1# 97 | 98 | // Replace all occurrences of MethodBase.Invoke with our debug version. 99 | return instructions; 100 | } 101 | 102 | public override void Patch(Harmony harmony) { 103 | if (!Ctx.Options.UseTranspiler) 104 | return; 105 | 106 | var resolvedMethod = 107 | Ctx.Assembly.ManifestModule.ResolveMethod(Ctx.VmRuntimeStructure.FunctionHandler.MDToken.ToInt32()); 108 | 109 | if (resolvedMethod is not null) 110 | PatchTranspiler(harmony, resolvedMethod); 111 | else 112 | Logger.Error("Failed to resolve FunctionHandler!"); 113 | } 114 | 115 | public override void Restore(Harmony harmony) { 116 | throw new NotImplementedException(); 117 | } 118 | } 119 | }*/ 120 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/Methods/VmProtectDumperUnsafeInvoke.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using HarmonyLib; 3 | using System.Diagnostics; 4 | using System.Reflection; 5 | using VMUnprotect.Runtime.General; 6 | using VMUnprotect.Runtime.Hooks.Methods.AntiDebug; 7 | using VMUnprotect.Runtime.MiddleMan; 8 | 9 | // ReSharper disable InconsistentNaming 10 | 11 | namespace VMUnprotect.Runtime.Hooks.Methods 12 | { 13 | public class VmProtectDumperUnsafeInvoke : VmUnprotectPatch 14 | { 15 | public VmProtectDumperUnsafeInvoke(Context ctx, ILogger logger) : base(ctx, logger) { } 16 | 17 | private static MethodInfo TargetMethod() { 18 | var runtimeMethodInfoType = AccessTools.TypeByName("System.Reflection.RuntimeMethodInfo"); 19 | var invokeMethod = AccessTools.DeclaredMethod(runtimeMethodInfoType, "UnsafeInvokeInternal"); 20 | return invokeMethod; 21 | } 22 | 23 | public static bool Prefix( 24 | ref object __result, 25 | ref object __instance, 26 | ref object obj, 27 | ref object[] parameters, 28 | ref object[] arguments) { 29 | var structure = Ctx.VmRuntimeStructure; 30 | 31 | // Check if this invoke is coming from VMP Handler 32 | var isVmpFunction = structure is { } && new StackTrace().GetFrame(3).GetMethod().MetadataToken == 33 | structure.FunctionHandler.MDToken.ToInt32(); 34 | 35 | if (!isVmpFunction) 36 | return true; 37 | 38 | if (Ctx.Options.BypassAntiDebug) 39 | Ctx.Scope.Resolve().OverwriteProcessInformation(obj, ref arguments); 40 | 41 | 42 | Logger.Info("VmProtectDumperUnsafeInvoke Prefix:"); 43 | Logger.Warn("{"); 44 | return Ctx.Scope.Resolve() 45 | .Prefix(ref __result, ref __instance, ref obj, ref parameters, ref arguments); 46 | } 47 | 48 | 49 | public static void Postfix( 50 | ref object __instance, 51 | ref object __result, 52 | ref object obj, 53 | ref object[] parameters, 54 | ref object[] arguments) { 55 | var structure = Ctx.VmRuntimeStructure; 56 | 57 | // Check if this invoke is coming from VMP Handler 58 | var isVmpFunction = structure is { } && new StackTrace().GetFrame(3).GetMethod().MetadataToken == 59 | structure.FunctionHandler.MDToken.ToInt32(); 60 | 61 | if (!isVmpFunction) 62 | return; 63 | 64 | if (Ctx.Options.BypassAntiDebug) 65 | Ctx.Scope.Resolve().GetDelegateForFunctionPointer(__result, arguments); 66 | 67 | Logger.Info("VmProtectDumperUnsafeInvoke Result:"); 68 | Ctx.Scope.Resolve() 69 | .Postfix(ref __instance, ref __result, ref obj, ref parameters, ref arguments); 70 | Logger.Warn("}\n"); 71 | } 72 | 73 | public override void Patch(Harmony harmony) { 74 | PatchPrefix(harmony, TargetMethod()); 75 | PatchPostfix(harmony, TargetMethod()); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Hooks/VmUnprotectPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | using VMUnprotect.Runtime.General; 6 | using VMUnprotect.Runtime.Helpers; 7 | 8 | namespace VMUnprotect.Runtime.Hooks 9 | { 10 | // NitroxPatcher 11 | public abstract class VmUnprotectPatch : Params, IVmupHook 12 | { 13 | private readonly List _activePatches = new(); 14 | 15 | protected VmUnprotectPatch(Context ctx, ILogger logger) : base(ctx, logger) { } 16 | 17 | public abstract void Patch(Harmony harmony); 18 | 19 | public void Restore(Harmony harmony) { 20 | foreach (var targetMethod in _activePatches) 21 | harmony.Unpatch(targetMethod, HarmonyPatchType.All, harmony.Id); 22 | } 23 | 24 | private HarmonyMethod GetHarmonyMethod(string methodName) { 25 | 26 | var method = AccessTools.DeclaredMethod(GetType(), methodName); 27 | 28 | if (method is null) 29 | throw new Exception($"Couldn't find {methodName}"); 30 | 31 | return new HarmonyMethod(method); 32 | } 33 | 34 | protected void PatchTranspiler(Harmony harmony, MethodBase targetMethod, string transpilerMethod = "Transpiler") { 35 | PatchMultiple(harmony, targetMethod, null, null, transpilerMethod); 36 | } 37 | 38 | protected void PatchPrefix(Harmony harmony, MethodBase targetMethod, string prefixMethod = "Prefix") { 39 | PatchMultiple(harmony, targetMethod, prefixMethod); 40 | } 41 | 42 | protected void PatchPostfix(Harmony harmony, MethodBase targetMethod, string postfixMethod = "Postfix") { 43 | PatchMultiple(harmony, targetMethod, null, postfixMethod); 44 | } 45 | 46 | protected void PatchMultiple( 47 | Harmony harmony, 48 | MethodBase targetMethod, 49 | bool prefix = false, 50 | bool postfix = false, 51 | bool transpiler = false, 52 | bool finalizer = false, 53 | bool iLManipulator = false) { 54 | var prefixMethod = prefix ? "Prefix" : null; 55 | var postfixMethod = postfix ? "Postfix" : null; 56 | var transpilerMethod = transpiler ? "Transpiler" : null; 57 | var finalizerMethod = finalizer ? "Finalizer" : null; 58 | 59 | PatchMultiple(harmony, targetMethod, prefixMethod, postfixMethod, transpilerMethod, finalizerMethod); 60 | } 61 | 62 | private void PatchMultiple( 63 | Harmony harmony, 64 | MethodBase targetMethod, 65 | string prefixMethod = null, 66 | string postfixMethod = null, 67 | string transpilerMethod = null, 68 | string finalizerMethod = null) { 69 | if (targetMethod is null) 70 | throw new Exception("Target method cannot be null"); 71 | 72 | var harmonyPrefixMethod = prefixMethod != null ? GetHarmonyMethod(prefixMethod) : null; 73 | var harmonyPostfixMethod = postfixMethod != null ? GetHarmonyMethod(postfixMethod) : null; 74 | var harmonyTranspilerMethod = transpilerMethod != null ? GetHarmonyMethod(transpilerMethod) : null; 75 | var harmonyFinalizerMethod = finalizerMethod != null ? GetHarmonyMethod(finalizerMethod) : null; 76 | 77 | harmony.Patch(targetMethod, harmonyPrefixMethod, harmonyPostfixMethod, harmonyTranspilerMethod, 78 | harmonyFinalizerMethod); 79 | 80 | _activePatches.Add(targetMethod); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/MiddleMan/TranspilerMiddleMan.cs: -------------------------------------------------------------------------------- 1 | /*using HarmonyLib; 2 | using System.Diagnostics; 3 | using System.Globalization; 4 | using System.Reflection; 5 | using VMUnprotect.Runtime.General; 6 | using VMUnprotect.Runtime.Helpers; 7 | 8 | namespace VMUnprotect.Runtime.MiddleMan 9 | { 10 | public class TranspilerMiddleMan : Params, ITranspilerMiddleMan 11 | { 12 | public TranspilerMiddleMan(Context ctx, ILogger logger) : base(ctx, logger) { } 13 | 14 | /// 15 | /// This function manipulate can manipulate, log actual invokes from virtualized VMP functions. 16 | /// 17 | public object Log( 18 | object obj, 19 | BindingFlags? bindingFlags, 20 | Binder binder, 21 | ref object[] parameters, 22 | CultureInfo culture, 23 | MethodBase methodBase) { 24 | // THIS IS OLD METHOD!!! Check Methods/MiddleMan.cs 25 | // Invoke the method and get return value. 26 | var returnValue = methodBase.Invoke(obj, parameters); 27 | 28 | // TODO: Add option to disable this because can cause bugs and can be broken easily 29 | var trace = new StackTrace(); 30 | var frame = trace.GetFrame(5); // <-- 31 | var method = frame.GetMethod(); 32 | 33 | Logger.Warn($"VMP Method: {method.FullDescription()}"); 34 | 35 | Logger.Warn("MethodName: {0}", methodBase.Name); 36 | Logger.Warn("FullDescription: {0}", methodBase.FullDescription()); 37 | Logger.Warn("MethodType: {0}", methodBase.GetType()); 38 | 39 | if (obj is not null) 40 | Logger.Warn("obj: {0}", obj.GetType()); 41 | 42 | // Loop through parameters and log them 43 | for (var i = 0; i < parameters.Length; i++) { 44 | var parameter = parameters[i]; 45 | Logger.Warn("Parameter ({1}) [{0}]: ({2})", i, parameter.GetType(), parameter); 46 | } 47 | 48 | Logger.Warn("MDToken: {0}", methodBase.MetadataToken); 49 | Logger.Warn("Returns: {0}", returnValue ?? "null"); 50 | 51 | return returnValue ?? null; 52 | } 53 | } 54 | 55 | public interface ITranspilerMiddleMan 56 | { 57 | public object Log( 58 | object obj, 59 | BindingFlags? bindingFlags, 60 | Binder binder, 61 | ref object[] parameters, 62 | CultureInfo culture, 63 | MethodBase methodBase); 64 | } 65 | }*/ 66 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/MiddleMan/UnsafeInvokeMiddleMan.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Diagnostics; 3 | using System.Reflection; 4 | using VMUnprotect.Runtime.General; 5 | using VMUnprotect.Runtime.Helpers; 6 | 7 | // ReSharper disable InconsistentNaming 8 | 9 | namespace VMUnprotect.Runtime.MiddleMan 10 | { 11 | public class UnsafeInvokeMiddleMan : Params, IUnsafeInvokeMiddleMan 12 | { 13 | public UnsafeInvokeMiddleMan(Context ctx, ILogger logger) : base(ctx, logger) { } 14 | 15 | /// 16 | /// A prefix is a method that is executed before the original method 17 | /// 18 | public bool Prefix( 19 | ref object __result, 20 | ref object __instance, 21 | ref object obj, 22 | ref object[] parameters, 23 | ref object[] arguments) { 24 | var virtualizedMethodName = new StackTrace().GetFrame(7).GetMethod(); 25 | var method = (MethodBase) __instance; 26 | 27 | Logger.Print("VMP MethodName: {0} (MDToken 0x{1:X4})", virtualizedMethodName.FullDescription(), 28 | virtualizedMethodName.MetadataToken.ToString()); 29 | Logger.Print("MethodName: {0}", method.Name); 30 | Logger.Print("FullDescription: {0}", method.FullDescription()); 31 | Logger.Print("MethodType: {0}", method.GetType()); 32 | 33 | // ReSharper disable once ConditionIsAlwaysTrueOrFalse 34 | if (obj is not null) 35 | Logger.Print("Obj: {0}", Formatter.FormatObject(obj)); 36 | 37 | // Loop through parameters and log them 38 | for (var i = 0; i < parameters.Length; i++) { 39 | var parameter = parameters[i]; 40 | Logger.Print("Parameter ({1}) [{0}]: ({2})", i, parameter.GetType(), Formatter.FormatObject(parameter)); 41 | } 42 | 43 | var returnType = method is MethodInfo info ? info.ReturnType.FullName : "System.Object"; 44 | Logger.Print("MDToken: 0x{0:X4}", method.MetadataToken); 45 | Logger.Print("Return Type: {0}", returnType ?? "null"); 46 | return true; 47 | } 48 | 49 | /// 50 | /// A postfix is a method that is executed after the original method 51 | /// 52 | public void Postfix( 53 | ref object __instance, 54 | ref object __result, 55 | ref object obj, 56 | ref object[] parameters, 57 | ref object[] arguments) { 58 | Logger.Print("Returns: {0}", __result); 59 | } 60 | } 61 | 62 | public interface IUnsafeInvokeMiddleMan 63 | { 64 | public void Postfix( 65 | ref object __result, 66 | ref object __instance, 67 | ref object obj, 68 | ref object[] parameters, 69 | ref object[] arguments); 70 | 71 | public bool Prefix( 72 | ref object __result, 73 | ref object __instance, 74 | ref object obj, 75 | ref object[] parameters, 76 | ref object[] arguments); 77 | } 78 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Modules/VmProtectPatchesModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using System.Reflection; 3 | using VMUnprotect.Runtime.Hooks; 4 | using Module = Autofac.Module; 5 | 6 | namespace VMUnprotect.Runtime.Modules 7 | { 8 | public class VmProtectPatchesModule : Module 9 | { 10 | protected override void Load(ContainerBuilder builder) { 11 | builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AssignableTo().AsImplementedInterfaces(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("VMUnprotect.Runtime")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("VMUnprotect.Runtime")] 12 | [assembly: AssemblyCopyright("Copyright © 2022")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("3EE03C52-C17B-4771-BF5A-32D04A2D435E")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Structure/VmRuntimeAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using System; 3 | using System.Linq; 4 | using VMUnprotect.Runtime.General; 5 | using VMUnprotect.Runtime.Helpers; 6 | using ILogger = VMUnprotect.Runtime.General.ILogger; 7 | 8 | namespace VMUnprotect.Runtime.Structure 9 | { 10 | internal class VmRuntimeAnalyzer : Params, IVmRuntimeAnalyzer 11 | { 12 | public VmRuntimeAnalyzer(Context ctx, ILogger logger) : base(ctx, logger) { } 13 | 14 | public void Discover() { 15 | var (functionHandler, vmTypeDef) = LocateVmHandlerAndTypDef(Ctx.Module); 16 | 17 | if (functionHandler is null || vmTypeDef is null) 18 | throw new ApplicationException("Could not locate VmProtectFunctionHandler."); 19 | 20 | Ctx.VmRuntimeStructure = new VmRuntimeStructure { 21 | FunctionHandler = functionHandler, 22 | VmTypeDef = vmTypeDef 23 | }; 24 | } 25 | 26 | #region VMP_FUNCTION_HANDLER 27 | 28 | /// 29 | /// These locals can be found in VMP Function Handler 30 | /// 31 | private static readonly string[] VmpFunctionHandlerLocals = { 32 | "System.Object", "System.Int32", "System.Reflection.MethodInfo", "System.Reflection.ParameterInfo[]", 33 | "System.Type[]", "System.Reflection.Emit.DynamicMethod", "System.Reflection.Emit.ILGenerator" 34 | }; 35 | 36 | /// 37 | /// Tries to search and match VMProtect MethodHandler 38 | /// 39 | /// Target Module 40 | /// MethodDef and TypeDef of Handler, if not returns NULL 41 | private static (MethodDef vmpHandler, TypeDef vmTypeDef) LocateVmHandlerAndTypDef(ModuleDef module) { 42 | MethodDef vmpHandler = null; 43 | TypeDef vmTypeDef = null; 44 | 45 | foreach (var type in module.GetTypes()) { 46 | // search pattern for 3.5.1 and older 47 | vmpHandler = type.Methods.Where(IsVmpFunctionHandler) 48 | .FirstOrDefault(method => new LocalTypes(method).All(VmpFunctionHandlerLocals)) ?? type.Methods 49 | // Search for pattern in 3.6.0 50 | .Where(IsVmpFunctionHandlerNew) 51 | .FirstOrDefault(method => new LocalTypes(method).All(VmpFunctionHandlerLocals)); 52 | 53 | if (vmpHandler == null) 54 | continue; 55 | 56 | vmTypeDef = type; 57 | 58 | Logger.Info("Found VmTypeDef, MDToken 0x{0:X4}", vmTypeDef.MDToken); 59 | Logger.Info("Found VMPFunctionHandler, MDToken 0x{0:X4}", vmpHandler.MDToken); 60 | break; 61 | } 62 | 63 | if (vmpHandler is null) { 64 | Logger.Error("Could not find VMP Method handler? Are you using supported version of VMP?"); 65 | Console.ReadKey(); 66 | } 67 | 68 | return (vmpHandler, vmTypeDef); 69 | } 70 | 71 | /// 72 | /// Checks RetType and Params, etc of MethodDef 73 | /// 74 | /// 75 | /// Does method match the requirements 76 | private static bool IsVmpFunctionHandlerNew(MethodDef method) { 77 | return method is {IsStatic: false} && method.MethodSig.GetParamCount() == 0; 78 | } 79 | 80 | 81 | /// 82 | /// Checks RetType and Params, etc of MethodDef 83 | /// 84 | /// 85 | /// Does method match the requirements 86 | private static bool IsVmpFunctionHandler(MethodDef method) { 87 | return method is {IsStatic: false} && method.MethodSig.GetParamCount() == 2 && 88 | method.MethodSig.RetType.GetElementType() == ElementType.Class && 89 | method.MethodSig.Params[0].GetElementType() == ElementType.Class && 90 | method.MethodSig.Params[1].GetElementType() == ElementType.Boolean; 91 | } 92 | #endregion 93 | } 94 | 95 | internal interface IVmRuntimeAnalyzer 96 | { 97 | void Discover(); 98 | } 99 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/Structure/VmRuntimeStructure.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | 3 | namespace VMUnprotect.Runtime.Structure 4 | { 5 | /// 6 | /// Structure of VMP Virtual Machine 7 | /// 8 | public class VmRuntimeStructure 9 | { 10 | /// 11 | /// TypeDefinition of Virtual Machine 12 | /// 13 | public TypeDef VmTypeDef { get; set; } 14 | 15 | /// 16 | /// Call handler of VMP Function Handler 17 | /// 18 | public MethodDef FunctionHandler { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/VMUnprotect.Runtime.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3EE03C52-C17B-4771-BF5A-32D04A2D435E} 8 | Library 9 | Properties 10 | VMUnprotect.Runtime 11 | VMUnprotect.Runtime 12 | v4.8 13 | 512 14 | default 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Lib.Harmony.2.1.1\lib\net48\0Harmony.dll 38 | True 39 | 40 | 41 | ..\packages\Autofac.6.3.0\lib\netstandard2.0\Autofac.dll 42 | True 43 | 44 | 45 | ..\packages\Autofac.Extensions.DependencyInjection.7.2.0\lib\netstandard2.0\Autofac.Extensions.DependencyInjection.dll 46 | True 47 | 48 | 49 | ..\packages\CommandLineParser.2.8.0\lib\net461\CommandLine.dll 50 | True 51 | 52 | 53 | ..\packages\dnlib.3.3.5\lib\net45\dnlib.dll 54 | True 55 | 56 | 57 | ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll 58 | True 59 | 60 | 61 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll 62 | True 63 | 64 | 65 | 66 | 67 | ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll 68 | True 69 | 70 | 71 | 72 | 73 | ..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll 74 | True 75 | 76 | 77 | ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll 78 | True 79 | 80 | 81 | 82 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll 83 | True 84 | 85 | 86 | ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll 87 | True 88 | 89 | 90 | ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect.Runtime/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 23 | 24 | 25 | 26 | 27 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 28 | 29 | 30 | 31 | 32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 38 | 39 | 40 | 41 | 42 | The order of preloaded assemblies, delimited with line breaks. 43 | 44 | 45 | 46 | 47 | 48 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 49 | 50 | 51 | 52 | 53 | Controls if .pdbs for reference assemblies are also embedded. 54 | 55 | 56 | 57 | 58 | Controls if runtime assemblies are also embedded. 59 | 60 | 61 | 62 | 63 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. 64 | 65 | 66 | 67 | 68 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 69 | 70 | 71 | 72 | 73 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 74 | 75 | 76 | 77 | 78 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 79 | 80 | 81 | 82 | 83 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 84 | 85 | 86 | 87 | 88 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 89 | 90 | 91 | 92 | 93 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 94 | 95 | 96 | 97 | 98 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 99 | 100 | 101 | 102 | 103 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. 104 | 105 | 106 | 107 | 108 | A list of unmanaged 32 bit assembly names to include, delimited with |. 109 | 110 | 111 | 112 | 113 | A list of unmanaged 64 bit assembly names to include, delimited with |. 114 | 115 | 116 | 117 | 118 | The order of preloaded assemblies, delimited with |. 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 127 | 128 | 129 | 130 | 131 | A comma-separated list of error codes that can be safely ignored in assembly verification. 132 | 133 | 134 | 135 | 136 | 'false' to turn off automatic generation of the XML Schema file. 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/Program.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using System; 3 | using System.IO; 4 | using System.Linq; 5 | using VMUnprotect.Runtime.General; 6 | using VMUnprotect.Utils; 7 | 8 | // https://open.spotify.com/playlist/4IeI5PQYePhXaezV9HRDIr 9 | // ^ Thanks for this banger soundtrack, without it the whole project wouldn't exist 10 | 11 | namespace VMUnprotect 12 | { 13 | internal static class Program 14 | { 15 | private const string AsciiArt = @" 16 | ____ ____ ____ ____ _____ _____ _______ 17 | |_ _| |_ _||_ \ / _||_ _||_ _||_ __ \ 18 | \ \ / / | \/ | | | | | | |__) | 19 | \ \ / / | |\ /| | | ' ' | | ___/ 20 | \ ' / _| |_\/_| |_ \ \__/ / _| |_ 21 | \_/ |_____||_____| `.__.' |_____| 22 | https://github.com/void-stack/VMUnprotect 23 | VMUnprotect Ultimate v 3.6.0 24 | "; 25 | 26 | public static void Main(string[] args) { 27 | Console.Title = "VMUnprotect Ultimate"; 28 | ConsoleLogger.Banner(AsciiArt); 29 | 30 | if (args.Length > 0 && File.Exists(args[0])) 31 | args[0] = $"-f {args[0]}"; 32 | 33 | Parser.Default.ParseArguments(args) 34 | .WithParsed(options => { 35 | var fileName = Path.GetFileNameWithoutExtension(options.FilePath); 36 | var fullPath = Path.GetFullPath(options.FilePath!); 37 | 38 | var logger = new ConsoleLogger(fileName); 39 | logger.Info( 40 | "Doesn't work? Make sure you dump the file before with: https://github.com/void-stack/VMUnprotect.Dumper"); 41 | 42 | var project = new Project { 43 | TargetFilePath = fullPath 44 | }; 45 | 46 | try { 47 | project.Run(logger, options); 48 | } catch (Exception ex) { 49 | // ignored 50 | } 51 | 52 | Console.ReadKey(); 53 | }) 54 | .WithNotParsed(errors => { 55 | Console.WriteLine("Errors: {0}", string.Join(", ", errors.Select(ex => ex.Tag))); 56 | Console.ReadKey(); 57 | }); 58 | 59 | Environment.Exit(0); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("VMUnprotect")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("VMUnprotect")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("42C88429-9A67-4087-91BD-7D76383BC86D")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /VMUP/VMUnprotect/Utils/ConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | using Serilog.Core; 3 | using Serilog.Sinks.SystemConsole.Themes; 4 | using System; 5 | using System.IO; 6 | using ILogger = VMUnprotect.Runtime.General.ILogger; 7 | 8 | namespace VMUnprotect.Utils 9 | { 10 | public class ConsoleLogger : ILogger 11 | { 12 | private readonly Logger _logger; 13 | 14 | public ConsoleLogger(string filename) { 15 | if (Directory.Exists("VMUP_Logs")) 16 | Directory.CreateDirectory("VMUP_Logs"); 17 | 18 | _logger = new LoggerConfiguration().WriteTo.File($"VMUP_Logs\\{filename}_{DateTime.Now:HH-mm-ss}.vmuplog") 19 | .WriteTo.Console(theme: AnsiConsoleTheme.Grayscale) 20 | .MinimumLevel.Verbose() 21 | .CreateLogger(); 22 | } 23 | 24 | public void Debug(string m, params object[] f) { 25 | _logger.Debug(m, f); 26 | } 27 | 28 | public void Error(string m, params object[] f) { 29 | _logger.Error(m, f); 30 | } 31 | 32 | public void Info(string m, params object[] f) { 33 | _logger.Information(m, f); 34 | } 35 | 36 | public void Warn(string m, params object[] f) { 37 | _logger.Warning(m, f); 38 | } 39 | 40 | public void Print(string m, params object[] f) { 41 | _logger.Verbose('\t' + m, f); 42 | } 43 | 44 | public static void Banner(string asciiArt) { 45 | Console.Title = "VMUnprotect for Ultimate v3.5.1"; 46 | Console.WriteLine(asciiArt); 47 | Console.WriteLine("Made with love by void-stack <3"); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /VMUP/VMUnprotect/VMUnprotect.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {42C88429-9A67-4087-91BD-7D76383BC86D} 8 | Exe 9 | Properties 10 | VMUnprotect 11 | VMUnprotect 12 | v4.8 13 | 512 14 | 9 15 | vmup.ico 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | manifest.manifest 39 | 40 | 41 | 42 | ..\..\..\..\..\.nuget\packages\lib.harmony\2.1.1\lib\net45\0Harmony.dll 43 | 44 | 45 | ..\packages\CommandLineParser.2.9.0-preview1\lib\net461\CommandLine.dll 46 | True 47 | 48 | 49 | ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll 50 | True 51 | 52 | 53 | 54 | ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll 55 | True 56 | 57 | 58 | 59 | ..\packages\Serilog.2.10.0\lib\net46\Serilog.dll 60 | True 61 | 62 | 63 | ..\packages\Serilog.Sinks.Console.4.0.0\lib\net45\Serilog.Sinks.Console.dll 64 | True 65 | 66 | 67 | ..\packages\Serilog.Sinks.File.5.0.0\lib\net45\Serilog.Sinks.File.dll 68 | True 69 | 70 | 71 | 72 | ..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll 73 | True 74 | 75 | 76 | ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll 77 | True 78 | 79 | 80 | 81 | ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll 82 | True 83 | 84 | 85 | 86 | 87 | ..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll 88 | True 89 | 90 | 91 | ..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll 92 | True 93 | 94 | 95 | ..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll 96 | True 97 | 98 | 99 | ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll 100 | True 101 | 102 | 103 | ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll 104 | True 105 | 106 | 107 | 108 | ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll 109 | True 110 | 111 | 112 | ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll 113 | True 114 | 115 | 116 | ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll 117 | True 118 | 119 | 120 | ..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll 121 | True 122 | 123 | 124 | ..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll 125 | True 126 | 127 | 128 | ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll 129 | True 130 | 131 | 132 | ..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll 133 | True 134 | 135 | 136 | ..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll 137 | True 138 | 139 | 140 | 141 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll 142 | True 143 | 144 | 145 | ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll 146 | True 147 | 148 | 149 | ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll 150 | True 151 | 152 | 153 | ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll 154 | True 155 | 156 | 157 | ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll 158 | True 159 | 160 | 161 | ..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll 162 | True 163 | 164 | 165 | ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll 166 | True 167 | 168 | 169 | ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll 170 | True 171 | 172 | 173 | ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll 174 | True 175 | 176 | 177 | ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll 178 | True 179 | 180 | 181 | ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll 182 | True 183 | 184 | 185 | ..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll 186 | True 187 | 188 | 189 | ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll 190 | True 191 | 192 | 193 | 194 | 195 | 196 | ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll 197 | True 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | {3ee03c52-c17b-4771-bf5a-32d04a2d435e} 212 | VMUnprotect.Runtime 213 | 214 | 215 | 216 | 223 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/manifest.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 62 | 63 | 64 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /VMUP/VMUnprotect/vmup.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/void-stack/VMUnprotect/c20ba5d4baf6845c22481d996369b1992dd3f6cb/VMUP/VMUnprotect/vmup.ico -------------------------------------------------------------------------------- /docs/desktop.ini: -------------------------------------------------------------------------------- 1 | [LocalizedFileNames] 2 | rider64_GMFmpBmXIx.png=@rider64_GMFmpBmXIx.png,0 3 | -------------------------------------------------------------------------------- /docs/gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/void-stack/VMUnprotect/c20ba5d4baf6845c22481d996369b1992dd3f6cb/docs/gif.gif -------------------------------------------------------------------------------- /docs/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/void-stack/VMUnprotect/c20ba5d4baf6845c22481d996369b1992dd3f6cb/docs/screen2.png -------------------------------------------------------------------------------- /docs/show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/void-stack/VMUnprotect/c20ba5d4baf6845c22481d996369b1992dd3f6cb/docs/show.gif -------------------------------------------------------------------------------- /docs/vmup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/void-stack/VMUnprotect/c20ba5d4baf6845c22481d996369b1992dd3f6cb/docs/vmup.png --------------------------------------------------------------------------------