Delete current instruction macro

I must admit I am not as die hard fan of ProDG debugger as some other coders out there, perhaps I’ve not been using it long enough. One tiny thing I miss though was the possibility of replacing an assembly instruction under the cursor with NOP with a single keystroke. Sure, with Visual Studio you can achieve same result with memory/immediate window, but it’s much more cumbersome. Today I decided to finally bite the bullet and recreate this little feature with VB macro:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Windows.Forms

Public Module Module1

    Sub NopInstruction()
        Dim debugger As EnvDTE.Debugger
        debugger = DTE.Debugger

        Dim projs As System.Array
        Dim proj As Project
        projs = DTE.ActiveSolutionProjects()
        Dim is64 As Boolean
        is64 = False
        If projs.Length > 0 Then
            proj = CType(projs.GetValue(0), EnvDTE.Project)
            is64 = proj.ConfigurationManager.ActiveConfiguration.PlatformName.IndexOf("64") >= 0
        End If

        Dim expr As Expression
        If is64 Then
            expr = debugger.GetExpression("@rip")
            expr = debugger.GetExpression("@eip")
        End If

        If expr.IsValidValue Then
            Dim deleteExpression As String
            deleteExpression = "*(unsigned char*)" + expr.Value + " = 0x90"
        End If

    End Sub

End Module

All you need to do is to add this macro and bind it to a key of your choice. Unfortunately, life is never easy and my solution doesn’t come without a few drawbacks:

  • you probably don’t want to bind it to Delete. Visual Studio doesn’t support different binding for different modes… Well, it kinda does, but I don’t think you can distinguish between an editor and debugger. I have it under Ctrl+Del.

  • it’s rather dumb. IIRC ProDG was smart enough to know the instruction size and insert a proper number of NOPs. My macro will always insert one per keystroke. I think it’s possible to fix this one by writing a “proper” add-in and using information provided by IDebugDisassemblyStream2, but this was supposed to be a quick evening coding fueled by Ardbeg & Genesis. Took me long enough to figure out how to get current code location (CurrentThread.Location returns function name, not address, if symbols are provided :/)

  • posted version will only work with 64-bit code. 32-bit would require changing rip->eip. This sucks, as now we have to have 2 macros. It’s not a deal breaker for me, I work with 64-bit code 90% of the time, but still, a little bit annoying. [EDIT] It was a problem with the first version I posted. After some hacking I’ve been able to add 64/32-bit detection (it’s based on the platform name for the first active solution project).

More Reading
Older// Go pathtracer