Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# (interactive) scripting example #315

Open
waruiji opened this issue Apr 20, 2024 · 2 comments
Open

C# (interactive) scripting example #315

waruiji opened this issue Apr 20, 2024 · 2 comments

Comments

@waruiji
Copy link

waruiji commented Apr 20, 2024

Description

Hi. Thanks for the great work.
Could you please provide an example snippet to use for scripting dnSpyEx through C# interactive window?
I'm interested in trying to script a patching process, but couldn't find the "entry-point" to the exposed functionality.

@ElektroKill
Copy link
Member

Hi,

There is very little documentation on this, if any.
Here are a few things that might help you:

All methods defined in the ScriptGlobals class are directly accessible from the C# code you enter in C# interactive.
https://github.com/dnSpyEx/dnSpy/blob/master/Extensions/dnSpy.Scripting.Roslyn/Common/ScriptGlobals.cs

The key method here is Resolve<T> which is responsible for resolving a given dnSpy service. There are lots of these services scattered throughout the codebase all responsible for different things whether that would be debugging, managing the treeview, ui components, etc. The best way to find useful services is to search the code for all public classes marked with Export attribute since these will all be accessible through this method.

You will also need to use the #r directive to add references to certain components which arent referenced by default if you need them. One such example is the debugger. You use these like so #r "dnSpy.Contracts.Debugger.dll", you can, of course, use a different assembly name which is either from dnSpy or exists in .NET by default.

Here is a snippet combining some of that knowledge to start debugging of a file on the disk.

#r "dnSpy.Contracts.Debugger.dll"
#r "dnSpy.Contracts.Debugger.DotNet.dll"
#r "dnSpy.Contracts.Debugger.DotNet.CorDebug.dll"

using dnSpy.Contracts.Debugger;
using dnSpy.Contracts.Debugger.DotNet.CorDebug;

string assemblyPath = @"C:\Users\admin\desktop\KeyGenMe.exe";

var dbgManager = Resolve<DbgManager>();

var startOptions = new DotNetFrameworkStartDebuggingOptions();
startOptions.Filename = assemblyPath;
startOptions.WorkingDirectory = Path.GetDirectoryName(assemblyPath);
startOptions.BreakKind = PredefinedBreakKinds.EntryPoint;

dbgManager.Start(startOptions);

You can of course access currently selected nodes or files by utilizing the appropriate service, aka the IDocumentTabService using code like so:
var module = UI(() => documentTabService.ActiveTab?.Content.Nodes.FirstOrDefault().GetModule());
The UI call here demonstrates executing code on the UI thread. By default code in C# interactive is executed on a separate thread to not freeze the UI. Using UI() will execute the given code on the UI thread meaning it will prevent usage of the UI during the execution.

Hope this rather basic example is helpful. If you have any questions feel free to ask them in the form of a discussion on github! https://github.com/dnSpyEx/dnSpy/discussions

@waruiji
Copy link
Author

waruiji commented Apr 29, 2024

Thank you for the detailed reply! I'll give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants