gpt4 book ai didi

visual-studio-2010 - Visual Studio 只在程序集的第二行中断?

转载 作者:行者123 更新时间:2023-12-04 20:15:36 27 4
gpt4 key购买 nike

简短说明:

在我的 .CODE 的第一行设置断点汇编程序中的段不会停止程序的执行。

问题:

Visual Studio 的调试器会导致它无法在用汇编编写的程序的第一行创建断点吗?这是调试器的一些奇怪之处,是多字节指令中断的情况,还是我只是在做一些愚蠢的事情?

细节:

我在 Visual Studio 中编译并运行了以下汇编程序:

; Tell MASM to use the Intel 80386 instruction set.
.386
; Flat memory model, and Win 32 calling convention
.MODEL FLAT, STDCALL
; Treat labels as case-sensitive (required for windows.inc)
OPTION CaseMap:None

include windows.inc
include masm32.inc
include user32.inc
include kernel32.inc
include macros.asm

includelib masm32.lib
includelib user32.lib
includelib kernel32.lib

.DATA
BadText db "Error...", 0
GoodText db "Excellent!", 0

.CODE
main PROC
;int 3 ; <-- If uncommented, this will not break.
mov ecx, 6 ; <-- Breakpoint here will not hit.
xor eax, eax ; <-- Breakpoint here will.
_label: add eax, ecx
dec ecx
jnz _label
cmp eax, 21
jz _good
_bad: invoke StdOut, addr BadText
jmp _quit
_good: invoke StdOut, addr GoodText
_quit: invoke ExitProcess, 0
main ENDP
END main

如果我尝试在主函数的第一行设置断点, mov ecx, 6 ,它被忽略,程序不停止地执行。如果我在之后的行上设置它,只会命中断点, xor eax, eax ,或任何后续行。

我什至尝试过插入软件断点, int 3 , 作为函数的第一行,也被忽略。

我注意到的第一件事很奇怪:在达到我的一个断点后查看反汇编给了我以下信息:
01370FFF  add         byte ptr [ecx+6],bh  
--- [Path]\main.asm
xor eax, eax
00841005 xor eax,eax --- <-- Breakpoint is hit here
_label: add eax, ecx
00841007 add eax,ecx
dec ecx
00841009 dec ecx
jnz _label
0084100A jne _label (841007h)
cmp eax, 21
0084100C cmp eax,15h

这里有趣的是 xor在 Visual Studio 眼中,是我程序中的第一个操作。缺席的是线路 move ecx, 6 .它认为我的来源开始的正上方是实际设置的行 ecx to 6.所以我的程序的实际启动已经根据反汇编被破坏了。

如果我编写程序的第一行 int 3 ,我的代码在反汇编中的上面出现的行是:
00F80FFF  add         ah,cl

正如其中一个答案所建议的那样,我关闭了 ASLR,看起来反汇编更稳定一些:
.CODE
main PROC
;mov ecx, 6
xor eax, eax
00401000 xor eax,eax --- <-- Breakpoint is present here, but not hit.
_label: add eax, ecx
00401002 add eax,ecx --- <-- Breakpoint here is hit.
dec ecx
00401004 dec ecx

在反汇编中可以看到完整的程序,但问题仍然存在。尽管我的程序从预期的地址开始, 第一个断点显示在反汇编中,它仍然被跳过。放置 int 3因为第一行仍然导致以下行:
00400FFF  add         ah,cl  

并且不会停止执行,并再次在反汇编中重新破坏我的程序 View 。我的程序的下一行在位置 00401001 ,我认为这是有道理的,因为 int 3是一个一字节的指令,但为什么它会在反汇编中消失呢?

即使使用“Step Into (F11)”命令启动程序也不允许我在第一行中断。事实上,没有断点,用 F11 启动程序根本不会停止执行。

除了我在这里详述的内容之外,我不确定我还能尝试解决什么问题。这超出了我目前对汇编和调试器的理解。

最佳答案

01370FFF add byte ptr [ecx+6],bh



至少我可以解开一个谜团。注意地址,0x1370fff。 CODE 段永远不会从这样的地址开始,段从 0x1000 的倍数的地址开始。这使得起始地址的最后 3 个十六进制数字始终为 0。调试器感到困惑并开始在错误的地址反汇编代码,减一。实际起始地址为 0x1371000。反汇编开始时很糟糕,因为在 0x1370fff 处有一个 0。这是一个多字节的 ADD 指令。所以它会显示垃圾一段时间,直到它偶然 catch 真正的机器代码指令。

您需要帮助它并给它一个命令以在正确的地址开始反汇编。在地址框中的 VS 中,键入“0x1371000”。

另一个值得注意的怪癖是起始地址的奇怪值。进程通常从地址 0x400000 开始。您打开了一个称为 ASLR 的功能,地址空间布局随机化。它是一种防病毒功能,可使程序在不可预测的起始地址处启动。不错的功能,但它并不能完全帮助调试程序。不清楚您如何构建此代码,但您需要/DYNAMICBASE:NO 链接器选项将其关闭。

您需要记住的另一个重要的调试器怪癖是它们设置断点的方式。他们通过修补代码,用 int 3 替换指令的起始字节来做到这一点。操作说明。当断点命中时,它会迅速用原始机器码指令字节替换该字节。所以你永远不会看到这个。如果您选择错误的地址来设置断点,则会出错,例如在多字节指令的中间。它现在不再破坏代码,改变的字节弄乱了原始指令。当您开始进行错误的反汇编时,您很容易陷入这个陷阱。

好吧,以正确的方式做到这一点。改为使用调试器的 STEP 命令开始调试。

关于visual-studio-2010 - Visual Studio 只在程序集的第二行中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13080069/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com