debugging - 使用WinDbg在运行时修改函数内容

标签 debugging windbg disassembly

我想使用 WinDbg 附加到正在运行的进程,并修改某个函数的代码以简单地在调用时返回(用于教育目的)。

我使用了以下命令:

uf dll!name

这给了我这个函数的反汇编。

我在某个位置选择了一个特定地址并将其修改为ret:

ew addr c3

每次都会崩溃,我做错了什么?

最佳答案

您需要确保进行适当的清理,以使堆栈保持正确的状态。根据调用约定,该方法通常将内容作为 prologue 的一部分推送到堆栈上。 。这必须作为尾声的一部分被撤销。

下面是使用 WinDbg 更改 JIT 编译方法的示例。

代码:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Message();
            Console.ReadLine();
            Message();
            Console.WriteLine("done");
        }

        private static void Message()
        {
            Console.WriteLine("message");
        }
    }
}

我将其编译为“调试”,以防止编译器内联对 Message 的调用。

然后我运行可执行文件并在调用 ReadLine 时附加调试器。

对于托管代码,我需要使用 SOS.dll 来定位 JIT 编译的代码。于是我加载了SOS,找到了代码的地址如下。

0:004> .loadby sos clr
0:004> !name2ee *!ConsoleApplication1.Program
Module:      04a11000
Assembly:    mscorlib.dll
--------------------------------------
Module:      001b2e94
Assembly:    ConsoleApplication1.exe
Token:       02000002
MethodTable: 001b37b4
EEClass:     001b125c
Name:        ConsoleApplication1.Program
0:004> !dumpmt -md 001b37b4
EEClass:         001b125c
Module:          001b2e94
Name:            ConsoleApplication1.Program
mdToken:         02000002
File:            c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
BaseSize:        0xc
ComponentSize:   0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
   Entry MethodDe    JIT Name
04d14960 04a16728 PreJIT System.Object.ToString()
04d08790 04a16730 PreJIT System.Object.Equals(System.Object)
04d08360 04a16750 PreJIT System.Object.GetHashCode()
04d016f0 04a16764 PreJIT System.Object.Finalize()
001bc019 001b37ac   NONE ConsoleApplication1.Program..ctor()
002a0050 001b3794    JIT ConsoleApplication1.Program.Main(System.String[])
002a00a8 001b37a0    JIT ConsoleApplication1.Program.Message()
0:004> !u 001b37a0    
Normal JIT generated code
ConsoleApplication1.Program.Message()
Begin 002a00a8, size 21
*** WARNING: Unable to verify checksum for c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe

c:\temp\ConsoleApplication1\ConsoleApplication1\Program.cs @ 20:
002a00a8 55              push    ebp        <-- prologue
002a00a9 8bec            mov     ebp,esp    
002a00ab 833d60311b0000  cmp     dword ptr ds:[1B3160h],0   <-- start of method
002a00b2 7405            je      ConsoleApplication1!ConsoleApplication1.Program.Message()+0x11 (002a00b9)
002a00b4 e8fb6ff570      call    clr!JIT_DbgIsJustMyCode (711f70b4)
002a00b9 90              nop

c:\temp\ConsoleApplication1\ConsoleApplication1\Program.cs @ 21:
002a00ba 8b0d34217403    mov     ecx,dword ptr ds:[3742134h] ("message")
002a00c0 e82bd3ad04      call    mscorlib_ni!System.Console.WriteLine(System.String) (04d7d3f0)
002a00c5 90              nop

c:\temp\ConsoleApplication1\ConsoleApplication1\Program.cs @ 22:
002a00c6 90              nop
002a00c7 5d              pop     ebp   <-- epilogue
002a00c8 c3              ret

然后我打开“内存”窗口并将其指向 002a00ab,这是 Message 实际方法体的第一部分,并将两个操作码更改为 5dc3 分别代表 pop edbret。如果我跳过 pop edb 部分,堆栈就会困惑,并且会出现异常。

我点击“Go”,应用程序继续,没有再次打印“消息”。

关于debugging - 使用WinDbg在运行时修改函数内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12082782/

相关文章:

.net - 免费 ~90% Gen2 .NET 堆

visual-studio-2010 - VS2010 中的 ReSharper 8.0 调试插件第一次工作,随后尝试出错

c# - 计算托管堆大小及其中的所有对象

.net - .Net应用程序中极端私有(private)字节使用分析, native 内存泄漏?

assembly - x86 中变量的大小

c++ - 除了内存中的长度之外,数据类型之间有什么区别?

c# - 我尝试使用 .NET 反射器查看 .NET BCL 库,但它没有显示任何符号

debugging - 如何调试恶意软件注入(inject)的代码?

c# - Visual Studio 2010 Professional 播放按钮已禁用

python - pygtk 2.22和python 2.6严重不稳定