├── DotNetPlugin.Impl
├── Resources
│ ├── mcp.png
│ └── abouticon.png
├── NativeBindings
│ ├── Win32
│ │ ├── Constants.cs
│ │ ├── Types.cs
│ │ ├── Functions.Psapi.cs
│ │ └── Functions.Kernel32.cs
│ ├── SDK
│ │ ├── Bridge.cs
│ │ ├── Bridge.Gui.cs
│ │ ├── TitanEngine.cs
│ │ └── Bridge.Dbg.cs
│ └── Script
│ │ ├── Pattern.cs
│ │ ├── Register.cs
│ │ ├── Disassembly.cs
│ │ ├── Gui.cs
│ │ ├── Argument.cs
│ │ └── Module.cs
├── Plugin.ExpressionFunctions.cs
├── ILRepack.targets
├── Plugin.cs
├── Plugin.Menus.cs
├── DotNetPlugin.Impl.csproj
├── Plugin.EventCallbacks.cs
└── Properties
│ └── Resources.Designer.cs
├── .editorconfig
├── .gitattributes
├── DotNetPlugin.Stub
├── NativeBindings
│ ├── Win32
│ │ ├── Win32Window.cs
│ │ ├── Types.WinGdi.cs
│ │ ├── Types.cs
│ │ └── Types.DebugEvents.cs
│ ├── Utf8StringRef.cs
│ ├── BlittableBoolean.cs
│ ├── StructRef.cs
│ ├── SDK
│ │ ├── PLog.cs
│ │ └── Bridge.cs
│ └── Extensions.cs
├── IPluginSession.cs
├── IPlugin.cs
├── Attributes.DllExport.cs
├── DotNetPlugin.Stub.csproj
├── PluginSession.cs
├── PluginBase.cs
├── Commands.cs
├── ExpressionFunctions.cs
├── PluginSessionProxy.cs
├── Menus.cs
├── EventCallbacks.cs
└── PluginMain.cs
├── Directory.Build.props
├── DotNetPlugin.RemotingHelper
├── DotNetPlugin.RemotingHelper.csproj
└── AppDomainInitializer.cs
├── .github
└── workflows
│ ├── build-x86.yml
│ └── build-x64.yml
├── x64DbgMCPServer.sln
├── .gitignore
└── README.md
/DotNetPlugin.Impl/Resources/mcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentSmithers/x64DbgMCPServer/HEAD/DotNetPlugin.Impl/Resources/mcp.png
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/Resources/abouticon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentSmithers/x64DbgMCPServer/HEAD/DotNetPlugin.Impl/Resources/abouticon.png
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Win32/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetPlugin.NativeBindings.Win32
2 | {
3 | public static class Win32Constants
4 | {
5 | public const int MAX_PATH = 260;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; Top-most EditorConfig file
2 | root = true
3 |
4 | ; Windows-style newlines
5 | [*]
6 | end_of_line = CRLF
7 |
8 | ; Tab indentation
9 | [*.cs]
10 | indent_style = space
11 | tab_width = 4
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/SDK/Bridge.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetPlugin.NativeBindings.SDK
2 | {
3 | // https://github.com/x64dbg/x64dbg/blob/development/src/bridge/bridgemain.h
4 | public sealed partial class Bridge : BridgeBase
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | DotNetPlugin.Impl/DotNetPlugin.Impl.csproj merge=ours
2 | DotNetPlugin.Stub/PluginMain.cs merge=ours
3 | DotNetPlugin.Stub/Attributes.DllExport.cs merge=ours
4 | .github/workflows/build-x86.yml merge=ours
5 | .github/workflows/build-x64.yml merge=ours
6 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/Plugin.ExpressionFunctions.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetPlugin
2 | {
3 | partial class Plugin
4 | {
5 | [ExpressionFunction]
6 | public static nuint DotNetAdd(nuint a, nuint b)
7 | {
8 | return a + b;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Win32/Types.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetPlugin.NativeBindings.Win32
2 | {
3 | #pragma warning disable 0649
4 |
5 | public enum ContinueStatus : uint
6 | {
7 | DBG_CONTINUE = 0x00010002,
8 | DBG_EXCEPTION_NOT_HANDLED = 0x80010001,
9 | DBG_REPLY_LATER = 0x40010001
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/NativeBindings/Win32/Win32Window.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace DotNetPlugin.NativeBindings.Win32
5 | {
6 | public sealed class Win32Window : IWin32Window
7 | {
8 | public Win32Window(IntPtr handle)
9 | {
10 | Handle = handle;
11 | }
12 |
13 | public IntPtr Handle { get; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/IPluginSession.cs:
--------------------------------------------------------------------------------
1 | #if ALLOW_UNLOADING
2 |
3 | using System;
4 |
5 | namespace DotNetPlugin
6 | {
7 | ///
8 | /// Represents the lifecycle of a plugin instance. (Supports Impl assembly unloading.)
9 | ///
10 | internal interface IPluginSession : IPlugin, IDisposable
11 | {
12 | new int PluginHandle { set; }
13 | }
14 | }
15 |
16 | #endif
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Win32/Functions.Psapi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 |
5 | namespace DotNetPlugin.NativeBindings.Win32
6 | {
7 | public static class Psapi
8 | {
9 | [DllImport("psapi.dll", CharSet = CharSet.Auto)]
10 | public static extern uint GetModuleBaseName(IntPtr hProcess, IntPtr hModule, StringBuilder lpBaseName, uint nSize);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/IPlugin.cs:
--------------------------------------------------------------------------------
1 | using DotNetPlugin.NativeBindings.SDK;
2 |
3 | namespace DotNetPlugin
4 | {
5 | ///
6 | /// Defines an API to interact with x64dbg.
7 | ///
8 | internal interface IPlugin
9 | {
10 | int PluginHandle { get; }
11 |
12 | bool Init();
13 | void Setup(ref Plugins.PLUG_SETUPSTRUCT setupStruct);
14 | bool Stop();
15 |
16 | void OnMenuEntry(ref Plugins.PLUG_CB_MENUENTRY info);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | MCP - Agent Smithers
4 | x64DbgMCPServer
5 |
6 | DotNetPlugin
7 | ..\bin\$(Platform)\$(Configuration)\
8 |
9 | 9
10 |
11 |
12 |
13 | true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/NativeBindings/Utf8StringRef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DotNetPlugin.NativeBindings
4 | {
5 | [Serializable]
6 | public readonly struct Utf8StringRef
7 | {
8 | private readonly IntPtr _intPtr;
9 |
10 | public Utf8StringRef(IntPtr intPtr)
11 | {
12 | _intPtr = intPtr;
13 | }
14 |
15 | public string GetValue() => _intPtr.MarshalToStringUTF8();
16 |
17 | public static implicit operator string(Utf8StringRef value) => value.GetValue();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Win32/Functions.Kernel32.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace DotNetPlugin.NativeBindings.Win32
5 | {
6 | public static class Kernel32
7 | {
8 | [DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory", ExactSpelling = true)]
9 | public static extern void ZeroMemory(IntPtr dst, nuint length);
10 |
11 | [DllImport("kernel32.dll", SetLastError = true)]
12 | public static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, ContinueStatus dwContinueStatus);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/NativeBindings/BlittableBoolean.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DotNetPlugin.NativeBindings
4 | {
5 | // Based on: https://aakinshin.net/posts/blittable/#boolean
6 | [Serializable]
7 | public struct BlittableBoolean
8 | {
9 | private byte _byteValue;
10 |
11 | public bool Value
12 | {
13 | get => Convert.ToBoolean(_byteValue);
14 | set => _byteValue = Convert.ToByte(value);
15 | }
16 |
17 | public static explicit operator BlittableBoolean(bool value) => new BlittableBoolean { Value = value };
18 |
19 | public static implicit operator bool(BlittableBoolean value) => value.Value;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/ILRepack.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/Attributes.DllExport.cs:
--------------------------------------------------------------------------------
1 | namespace RGiesecke.DllExport
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
7 | public sealed class DllExportAttribute : Attribute
8 | {
9 | public DllExportAttribute() { }
10 | public DllExportAttribute(string entryPoint) { EntryPoint = entryPoint; }
11 | public DllExportAttribute(string entryPoint, CallingConvention callingConvention)
12 | {
13 | EntryPoint = entryPoint;
14 | CallingConvention = callingConvention;
15 | }
16 |
17 | public string EntryPoint { get; }
18 | public CallingConvention CallingConvention { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/NativeBindings/StructRef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace DotNetPlugin.NativeBindings
5 | {
6 | ///
7 | /// Safe to use with blittable types only!
8 | ///
9 | [Serializable]
10 | public readonly struct StructRef where T : unmanaged
11 | {
12 | private readonly IntPtr _intPtr;
13 |
14 | public StructRef(IntPtr intPtr)
15 | {
16 | _intPtr = intPtr;
17 | }
18 |
19 | public bool HasValue => _intPtr != IntPtr.Zero;
20 |
21 | public ref T Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => ref _intPtr.ToStructUnsafe(); }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/DotNetPlugin.RemotingHelper/DotNetPlugin.RemotingHelper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(PluginAssemblyName).RemotingHelper
4 | DotNetPlugin
5 | net472
6 | x86;x64
7 | false
8 | full
9 | true
10 | $(PluginName)
11 |
12 |
13 |
14 | X86;$(DefineConstants)
15 |
16 |
17 | AMD64;$(DefineConstants)
18 |
19 |
20 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Script/Pattern.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace DotNetPlugin.NativeBindings.Script
4 | {
5 | public static class Pattern
6 | {
7 | #if AMD64
8 | private const string dll = "x64dbg.dll";
9 |
10 | private const string Script_Pattern_FindMemEP = "?FindMem@Pattern@Script@@YA_K_K0PEBD@Z";
11 | #else
12 | private const string dll = "x32dbg.dll";
13 |
14 | private const string Script_Pattern_FindMemEP = "?FindMem@Pattern@Script@@YAKKKPBD@Z";
15 | #endif
16 | private const CallingConvention cdecl = CallingConvention.Cdecl;
17 |
18 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Pattern_FindMemEP, ExactSpelling = true)]
19 | private static extern nuint Script_Pattern_FindMem(nuint start, nuint size, [MarshalAs(UnmanagedType.LPUTF8Str)] string pattern);
20 |
21 | public static nuint FindMem(nuint start, nuint size, string pattern) => Script_Pattern_FindMem(start, size, pattern);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Script/Register.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace DotNetPlugin.NativeBindings.Script
5 | {
6 | public static class Register
7 | {
8 | #if AMD64
9 | private const string dll = "x64dbg.dll";
10 |
11 | private const string ScriptRegisterGetCIP = "?GetCIP@Register@Script@@YA_KXZ";
12 | private const string ScriptRegisterGetCSP = "?GetCSP@Register@Script@@YA_KXZ";
13 | #else
14 | private const string dll = "x32dbg.dll";
15 |
16 | private const string ScriptRegisterGetCIP = "?GetCIP@Register@Script@@YAKXZ";
17 | private const string ScriptRegisterGetCSP = "?GetCSP@Register@Script@@YAKXZ";
18 | #endif
19 | private const CallingConvention cdecl = CallingConvention.Cdecl;
20 |
21 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = ScriptRegisterGetCIP, ExactSpelling = true)]
22 | public static extern UIntPtr GetCIP();
23 |
24 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = ScriptRegisterGetCSP, ExactSpelling = true)]
25 | public static extern UIntPtr GetCSP();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Script/Disassembly.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace DotNetPlugin.NativeBindings.Script
4 | {
5 | public static partial class Gui
6 | {
7 | public static class Disassembly
8 | {
9 | #if AMD64
10 | private const string dll = "x64dbg.dll";
11 |
12 | private const string Script_Gui_Disassembly_SelectionGetStartEP = "?SelectionGetStart@Disassembly@Gui@Script@@YA_KXZ";
13 | private const string Script_Gui_Disassembly_SelectionGetEndEP = "?SelectionGetEnd@Disassembly@Gui@Script@@YA_KXZ";
14 | #else
15 | private const string dll = "x32dbg.dll";
16 |
17 | private const string Script_Gui_Disassembly_SelectionGetStartEP = "?SelectionGetStart@Disassembly@Gui@Script@@YAKXZ";
18 | private const string Script_Gui_Disassembly_SelectionGetEndEP = "?SelectionGetEnd@Disassembly@Gui@Script@@YAKXZ";
19 | #endif
20 | private const CallingConvention cdecl = CallingConvention.Cdecl;
21 |
22 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Gui_Disassembly_SelectionGetStartEP, ExactSpelling = true)]
23 | private static extern nuint Script_Gui_Disassembly_SelectionGetStart();
24 |
25 | public static nuint SelectionGetStart() => Script_Gui_Disassembly_SelectionGetStart();
26 |
27 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Gui_Disassembly_SelectionGetEndEP, ExactSpelling = true)]
28 | private static extern nuint Script_Gui_Disassembly_SelectionGetEnd();
29 |
30 | public static nuint SelectionGetEnd() => Script_Gui_Disassembly_SelectionGetEnd();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.github/workflows/build-x86.yml:
--------------------------------------------------------------------------------
1 | name: Build x86 Plugin
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | paths:
7 | - '**/*.cs'
8 | - '**/*.csproj'
9 | - 'Directory.Build.props'
10 | - '.github/workflows/build-x86.yml'
11 |
12 | jobs:
13 | build:
14 | runs-on: windows-latest
15 | env:
16 | NUGET_PACKAGES: ${{ github.workspace }}\\packages
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Setup MSBuild
22 | uses: microsoft/setup-msbuild@v2
23 |
24 | - name: Setup .NET SDK
25 | uses: actions/setup-dotnet@v4
26 | with:
27 | dotnet-version: '8.0.x'
28 |
29 | - name: Restore
30 | run: msbuild x64DbgMCPServer.sln /t:Restore /p:Platform=x86 /p:Configuration=Debug /p:RestorePackagesPath="${{ env.NUGET_PACKAGES }}" /p:BaseIntermediateOutputPath=.cache\\obj\\
31 |
32 | - name: Build x86 Debug
33 | run: msbuild x64DbgMCPServer.sln /t:Rebuild /p:Platform=x86 /p:Configuration=Debug /p:RestorePackagesPath="${{ env.NUGET_PACKAGES }}" /p:BaseIntermediateOutputPath=.cache\\obj\\ /p:BaseOutputPath=.cache\\bin\\
34 |
35 | - name: Upload artifact (dp32)
36 | uses: actions/upload-artifact@v4
37 | with:
38 | name: AgentSmithers_x64DbgMCP_x32Plugin
39 | path: |
40 | bin\\x86\\Debug\\**\\*.dp32
41 | bin\\x86\\Debug\\**\\*.dll
42 | bin\\x86\\Debug\\**\\*.pdb
43 | if-no-files-found: error
44 |
45 | - name: Cleanup caches
46 | if: always()
47 | run: |
48 | Remove-Item -Recurse -Force .cache -ErrorAction SilentlyContinue
49 | Remove-Item -Recurse -Force packages -ErrorAction SilentlyContinue
50 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Script/Gui.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace DotNetPlugin.NativeBindings.Script
4 | {
5 | public static partial class Gui
6 | {
7 | public enum Window
8 | {
9 | DisassemblyWindow,
10 | DumpWindow,
11 | StackWindow,
12 | GraphWindow,
13 | MemMapWindow,
14 | SymModWindow
15 | };
16 |
17 | #if AMD64
18 | private const string dll = "x64dbg.dll";
19 |
20 | private const string Script_Gui_SelectionGetStartEP = "?SelectionGetStart@Gui@Script@@YA_KW4Window@12@@Z";
21 | private const string Script_Gui_SelectionGetEndEP = "?SelectionGetEnd@Gui@Script@@YA_KW4Window@12@@Z";
22 | #else
23 | private const string dll = "x32dbg.dll";
24 |
25 | private const string Script_Gui_SelectionGetStartEP = "?SelectionGetStart@Gui@Script@@YAKW4Window@12@@Z";
26 | private const string Script_Gui_SelectionGetEndEP = "?SelectionGetEnd@Gui@Script@@YAKW4Window@12@@Z";
27 | #endif
28 | private const CallingConvention cdecl = CallingConvention.Cdecl;
29 |
30 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Gui_SelectionGetStartEP, ExactSpelling = true)]
31 | private static extern nuint Script_Gui_SelectionGetStart(Window window);
32 |
33 | public static nuint SelectionGetStart(Window window) => Script_Gui_SelectionGetStart(window);
34 |
35 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Gui_SelectionGetEndEP, ExactSpelling = true)]
36 | private static extern nuint Script_Gui_SelectionGetEnd(Window window);
37 |
38 | public static nuint SelectionGetEnd(Window window) => Script_Gui_SelectionGetEnd(window);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/.github/workflows/build-x64.yml:
--------------------------------------------------------------------------------
1 | name: Build x64 Plugin
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | paths:
7 | - '**/*.cs'
8 | - '**/*.csproj'
9 | - 'Directory.Build.props'
10 | - '.github/workflows/build-x64.yml'
11 |
12 | jobs:
13 | build:
14 | runs-on: windows-latest
15 | env:
16 | NUGET_PACKAGES: ${{ github.workspace }}\\packages
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Setup MSBuild
22 | uses: microsoft/setup-msbuild@v2
23 |
24 | - name: Setup .NET SDK
25 | uses: actions/setup-dotnet@v4
26 | with:
27 | dotnet-version: '8.0.x'
28 |
29 | - name: Restore
30 | run: msbuild x64DbgMCPServer.sln /t:Restore /p:Platform=x64 /p:Configuration=Debug /p:RestorePackagesPath="${{ env.NUGET_PACKAGES }}" /p:BaseIntermediateOutputPath=.cache\\obj\\
31 |
32 | - name: Build x64 Debug
33 | run: msbuild x64DbgMCPServer.sln /t:Rebuild /p:Platform=x64 /p:Configuration=Debug /p:RestorePackagesPath="${{ env.NUGET_PACKAGES }}" /p:BaseIntermediateOutputPath=.cache\\obj\\ /p:BaseOutputPath=.cache\\bin\\
34 |
35 | - name: Upload artifact (dp64)
36 | uses: actions/upload-artifact@v4
37 | with:
38 | name: AgentSmithers_x64DbgMCP_x64Plugin
39 | path: |
40 | bin\\x64\\Debug\\**\\*.dp64
41 | bin\\x64\\Debug\\**\\*.dll
42 | bin\\x64\\Debug\\**\\*.pdb
43 | if-no-files-found: error
44 |
45 | - name: Cleanup caches
46 | if: always()
47 | run: |
48 | Remove-Item -Recurse -Force .cache -ErrorAction SilentlyContinue
49 | Remove-Item -Recurse -Force packages -ErrorAction SilentlyContinue
50 |
51 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/NativeBindings/Script/Argument.cs:
--------------------------------------------------------------------------------
1 | using DotNetPlugin.NativeBindings.SDK;
2 | using System;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace DotNetPlugin.NativeBindings.Script
6 | {
7 | public static class Argument
8 | {
9 | [Serializable]
10 | public unsafe struct ArgumentInfo
11 | {
12 | private fixed byte _mod[BridgeBase.MAX_MODULE_SIZE];
13 | public string mod
14 | {
15 | get
16 | {
17 | fixed (byte* ptr = _mod)
18 | return new IntPtr(ptr).MarshalToStringUTF8(Bridge.MAX_MODULE_SIZE);
19 | }
20 | set
21 | {
22 | fixed (byte* ptr = _mod)
23 | value.MarshalToPtrUTF8(new IntPtr(ptr), Bridge.MAX_MODULE_SIZE * 4);
24 | }
25 | }
26 |
27 | nuint rvaStart;
28 | nuint rvaEnd;
29 | bool manual;
30 | nuint instructioncount;
31 | };
32 |
33 | #if AMD64
34 | private const string dll = "x64dbg.dll";
35 |
36 | private const string Script_Argument_DeleteRangeEP = "?DeleteRange@Argument@Script@@YAX_K0_N@Z";
37 | #else
38 | private const string dll = "x32dbg.dll";
39 |
40 | private const string Script_Argument_DeleteRangeEP = "?DeleteRange@Argument@Script@@YAXKK_N@Z";
41 | #endif
42 | private const CallingConvention cdecl = CallingConvention.Cdecl;
43 |
44 | [DllImport(dll, CallingConvention = cdecl, EntryPoint = Script_Argument_DeleteRangeEP, ExactSpelling = true)]
45 | private static extern void Script_Argument_DeleteRange(nuint start, nuint end, bool deleteManual = false);
46 |
47 | public static void DeleteRange(nuint start, nuint end, bool deleteManual = false) =>
48 | Script_Argument_DeleteRange(start, end, deleteManual);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/DotNetPlugin.RemotingHelper/AppDomainInitializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 |
5 | namespace DotNetPlugin
6 | {
7 | ///
8 | /// A helper class which enables the Stub assembly to be resolved in a separate app domain.
9 | ///
10 | ///
11 | /// It's inevitable to place this class into a separate assembly because of an issue of the remoting activator:
12 | /// if this type resided in the Stub assembly, the activator would want to load that assembly in the app domain upon initialization,
13 | /// which would fail because the activator looks for a dll but x64dbg plugins must have a custom extension (dp32/dp64)...
14 | ///
15 | public static class AppDomainInitializer
16 | {
17 | private const string DllExtension =
18 | #if AMD64
19 | ".dp64";
20 | #else
21 | ".dp32";
22 | #endif
23 |
24 | public static void Initialize(string[] args)
25 | {
26 | AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
27 | {
28 | var assemblyName = new AssemblyName(e.Name);
29 | var pluginAssemblyName = typeof(AppDomainInitializer).Assembly.GetName().Name;
30 |
31 | if (pluginAssemblyName.StartsWith(assemblyName.Name, StringComparison.OrdinalIgnoreCase) &&
32 | pluginAssemblyName.Substring(assemblyName.Name.Length).Equals(".RemotingHelper", StringComparison.OrdinalIgnoreCase))
33 | {
34 | var location = typeof(AppDomainInitializer).Assembly.Location;
35 | var pluginBasePath = Path.GetDirectoryName(location);
36 | var dllPath = Path.Combine(pluginBasePath, assemblyName.Name + DllExtension);
37 |
38 | return Assembly.LoadFile(dllPath);
39 | }
40 |
41 | return null;
42 | };
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/DotNetPlugin.Impl/Plugin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using DotNetPlugin.NativeBindings;
4 | using DotNetPlugin.NativeBindings.SDK;
5 |
6 | namespace DotNetPlugin
7 | {
8 | ///
9 | /// Implementation of your x64dbg plugin.
10 | ///
11 | ///
12 | /// If you change the namespace or name of this class, don't forget to reflect the change in too!
13 | ///
14 | public partial class Plugin : PluginBase
15 | {
16 | public override bool Init()
17 | {
18 | Console.SetOut(PLogTextWriter.Default);
19 | Console.SetError(PLogTextWriter.Default);
20 |
21 | LogInfo($"PluginHandle: {PluginHandle}");
22 |
23 |
24 | // You can listen to debugger events in two ways:
25 | // 1. by declaring dll exports in the Stub project (see PluginMain), then adding the corresponding methods to the IPlugin interface,
26 | // finally implementing them as required to propagate the call to the Plugin class or
27 | // 2. by registering callbacks using the EventCallback attribute (see Plugin.EventCallbacks.cs).
28 |
29 | // Please note that Option 1 goes through remoting in Debug builds (where Impl assembly unloading is enabled),
30 | // so it may be somewhat slower than Option 2. Release builds don't use remoting, just direct calls, so in that case there should be no significant difference.
31 |
32 | // Commands and function expressions are discovered and registered automatically. See Plugin.Commands.cs and Plugin.ExpressionFunctions.cs.
33 |
34 | // Menus can be registered by overriding the SetupMenu method. See Plugin.Menus.cs.
35 |
36 | return true;
37 | }
38 |
39 | public override void Setup(ref Plugins.PLUG_SETUPSTRUCT setupStruct)
40 | {
41 | // Do additional UI setup (apart from menus) here.
42 | Plugin.cbStartMCPServer(null);
43 | }
44 |
45 | public override Task StopAsync()
46 | {
47 | // Do additional cleanup here.
48 |
49 | return Task.FromResult(true);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/DotNetPlugin.Stub/NativeBindings/SDK/PLog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using DotNetPlugin.NativeBindings.SDK;
5 |
6 | namespace DotNetPlugin.NativeBindings
7 | {
8 | public sealed class PLogTextWriter : TextWriter
9 | {
10 | public static readonly PLogTextWriter Default = new PLogTextWriter();
11 |
12 | private PLogTextWriter()
13 | {
14 | NewLine = "\n";
15 | }
16 |
17 | public override Encoding Encoding => Encoding.UTF8;
18 |
19 | public override void Write(char value) =>
20 | Write(value.ToString());
21 |
22 | public override void Write(char[] buffer, int index, int count) =>
23 | Write(new string(buffer, index, count));
24 |
25 | public override void Write(string value) =>
26 | Write(value, Array.Empty