Windbg / cdb-用内存中的补丁程序(32位)替换缓慢的条件断点

问题描述 投票:1回答:2

使用cdb,我有以下条件断点

bp 004bf9f8 ".if (@eax = 0) {.echotime;.echo Breakpoint 004bf9f8;r};gc"

因为这是调查一个间歇性问题,它必须保持连接一段时间,但条件断点速度变慢应用程序的整体性能远远超出了我的承受能力。

  • 有人知道如何优化条件断点吗?它所做的只是检查eax=0。我已经读过somepostsexplaining为什么有条件的断点会这么慢地减速,而那些断点才是合理的,所以我认为这是一个死胡同。
  • 我几乎可以用内存图像来做我想做的事情。是否可以修补一些指令以插入诸如if eax = 0 { <whatever>}之类的东西,以便在<whatever>上添加unconditional
  • 断点?

    编辑

根据评论,行动计划如下所示

.dvalloc <bytes>store the result in a variable称为patch

a 004bfa08 JMP patch
a patch MOV eax,esi
a patch+x CMP eax,0
a patch+y JNE 004bfa0a
a patch+z JMP 004bfa0a

现在,我应该能够在patch+z上添加一个无条件断点,以转储我需要的信息而无需停止应用程序。

bp patch+z ".echotime;.echo Breakpoint patch+z;~.;r;!dpx;gc"

编辑2

以下POC在实时调试会话中起作用,但是仍必须将其转换为不会暂停应用程序,等待按键或任何操作的脚本。

已执行命令

.dvalloc 1000

a 004bfa00
JMP 0x0c570000
NOP

a 0xc570000
mov edi,edx
mov esi,eax
mov ebp,edi
cmp eax,0
jne 0x004bfa06
jmp 0x004bfa06

bp 0c570011 ".echo Hello World"

已执行的命令,包括输出/上下文

0:010> .dvalloc 1000
Allocated 1000 bytes starting at 0c570000

0:010> u 004bf9f8 LD
application+0xbf9f8:
004bf9f8 53              push    ebx
004bf9f9 56              push    esi
004bf9fa 57              push    edi
004bf9fb 55              push    ebp
004bf9fc 51              push    ecx
004bf9fd 890c24          mov     dword ptr [esp],ecx
004bfa00 8bfa            mov     edi,edx |
004bfa02 8bf0            mov     esi,eax |-> these get overwritten so repeat in patch
004bfa04 8bef            mov     ebp,edi |
004bfa06 8bd5            mov     edx,ebp
004bfa08 8bc6            mov     eax,esi
004bfa0a e8e5feffff      call    application+0xbf8f4 (004bf8f4)

0:010> a 004bfa00
JMP 0x0c570000
NOP

0:010> u 004bf9f8 LD
application+0xbf9f8:
004bf9f8 53              push    ebx
004bf9f9 56              push    esi
004bf9fa 57              push    edi
004bf9fb 55              push    ebp
004bf9fc 51              push    ecx
004bf9fd 890c24          mov     dword ptr [esp],ecx
004bfa00 e9fb050b0c      jmp     0c570000
004bfa05 90              nop
004bfa06 8bd5            mov     edx,ebp
004bfa08 8bc6            mov     eax,esi
004bfa0a e8e5feffff      call    application+0xbf8f4 (004bf8f4)

0:010> a 0xc570000
0c570000 mov edi,edx
mov edi,edx
0c570002 mov esi,eax
mov esi,eax
0c570004 mov ebp,edi
mov ebp,edi
0c570006 cmp eax,0
cmp eax,0
0c57000b jne 0x004bfa06
jne 0x004bfa06
0c570011 jmp 0x004bfa06
jmp 0x004bfa06
0c570016 

0:010> u 0x0c570000 L6
0c570000 8bfa            mov     edi,edx
0c570002 8bf0            mov     esi,eax
0c570004 8bef            mov     ebp,edi
0c570006 3d00000000      cmp     eax,0
0c57000b 0f85f5f9f4f3    jne     application+0xbfa06 (004bfa06)
0c570011 e9f0f9f4f3      jmp     application+0xbfa06 (004bfa06)

0:010> bp 0c570011 ".echo Hello World"

编辑3

手动修补7个正在运行的可执行文件是成功的,但是根据.dvalloc返回的地址,汇编的JMP指令包含另一条指令。我以为这很简单,就是从.dvalloc获得的地址中减去我们跳转到的地址,但事实并非如此。

   -------------------------------------------------------------
   .dvalloc+0x11 |a jmp 004bfa06 |opcode |cd       |LE
   --------------|---------------|-------|---------|------------
1. 00df0011      |e9f0f96cff     |e9     |f0f96cff |ff 6c f9 f0
2. 00e30011      |e9f0f968ff     |e9     |f0f968ff |ff 68 f9 f0
3. 00f00011      |e9f0f95bff     |e9     |f0f95bff |ff 5b f9 f0
4. 00ff0011      |e9f0f94cff     |e9     |f0f94cff |ff 4c f9 f0
5. 093a0011      |e9f0f911f7     |e9     |f0f911f7 |f7 11 f9 f0
6. 0c570011      |e9f0f9f4f3     |e9     |f0f9f4f3 |f3 f4 f9 f0
7. 0ce70011      |e9f0f964f3     |e9     |f0f964f3 |f3 64 f9 f0
   -------------------------------------------------------------

第一个f也许是一个符号位?

编辑4

毕竟,计算很简单,虽然花了我足够长的时间。实际上,第一个f是符号。

  • 获取要跳转的地址。就我而言004bfa06
  • 减去jmp 004bfa06指令的存储器位置的末尾。就我而言,始终是.dvalloc+0x16.dvalloc+0x11是指令的开头)
  • 应用于我的上一次尝试(7),给出了

004fba01 - 0ce70016 = f3 64 f9 f0. 
The instruction to edit the memory at 0ce70011 then becomes e9f0f964f3.

下面是我设置断点的函数序言。 004bfa08 (MOV param_1,ESI)处的指令是多余的,因为004bfa02 (MOV ESI,param_1)处的先前指令是有用的,但我不知道如何从此处进行。

                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     int * __register FUN_004bf9f8(int param_1, int param_2, 
     int *             EAX:4          <RETURN>
     int               EAX:4          param_1
     int               EDX:4          param_2
     int               ECX:4          param_3
     undefined4        Stack[-0x14]:4 local_14

004bf9f8 53              PUSH       EBX
004bf9f9 56              PUSH       ESI
004bf9fa 57              PUSH       EDI
004bf9fb 55              PUSH       EBP
004bf9fc 51              PUSH       param_3
004bf9fd 89 0c 24        MOV        dword ptr [ESP]=>local_14,param_3
004bfa00 8b fa           MOV        EDI,param_2
004bfa02 8b f0           MOV        ESI,param_1
004bfa04 8b ef           MOV        EBP,EDI
004bfa06 8b d5           MOV        param_2,EBP
004bfa08 8b c6           MOV        param_1,ESI
004bfa0a e8 e5 fe        CALL       FUN_004bf8f4
         ff ff
004bfa0f 8b d8           MOV        EBX,param_1

[使用cdb,我有以下条件断点bp 004bf9f8“ .if(@eax = 0){.echotime; .echo断点004bf9f8; r}; gc”因为这是调查间歇性问题,所以必须保持联系。 ..

windbg breakpoints monkeypatching cdb
2个回答
1
投票

这可能非常不专业。说真的我的x86汇编程序知识几乎为零。我非常喜欢看到@blabb或其他真正了解他的工作的人的回答。无论如何,这就是我使用32位记事本(C:\Windows\SysWow64\notepad.exe)所实现的。


0
投票

E9操作码只能跳+-2GB,因此在x64中有点残缺您可能需要加载暂存寄存器并跳到那里

© www.soinside.com 2019 - 2024. All rights reserved.