如何在用GDB调试C程序时找出内联常量的值?
假设我有一个已编译的二进制程序,没有调试符号,源代码与C中的类似:如何在用GDB调试C程序时找出内联常量的值?,c,debugging,assembly,gdb,reverse-engineering,C,Debugging,Assembly,Gdb,Reverse Engineering,假设我有一个已编译的二进制程序,没有调试符号,源代码与C中的类似: char code[] = "1234"; if (atoi(code) == 4321) { puts("Right"); } else { puts("Wrong"); } 我用GDB调试程序 当我单步执行程序时,是否有办法找出定义为4321的整数的值?在一般情况下否,例如如果x
char code[] = "1234";
if (atoi(code) == 4321)
{
puts("Right");
}
else
{
puts("Wrong");
}
我用GDB调试程序
当我单步执行程序时,是否有办法找出定义为4321的整数的值?在一般情况下否,例如如果x<10可能被编译为cmp reg,9/jle对于x86 x在一般情况下否,例如如果x<10可能被编译为cmp reg,9/jle对于x86 x,内联常量应该显示在程序集中。您在程序集中看到了什么?定义为4321的整数的值是4321。不清楚你在问什么。@n.“代词m:”我似乎很清楚:鉴于只有编译器从这个C源代码生成的机器代码,你能在其中的某个地方找到4321吗?我认为这意味着你也没有C源代码,但这有点模棱两可。使用精简二进制文件和C源代码,对asm与源代码的匹配方式进行反向工程当然要容易得多。为澄清这个问题,重新修改了内联常量应该显示在程序集中的问题。您在程序集中看到了什么?定义为4321的整数的值是4321。不清楚你在问什么。@n.“代词m:”我似乎很清楚:鉴于只有编译器从这个C源代码生成的机器代码,你能在其中的某个地方找到4321吗?我认为这意味着你也没有C源代码,但这有点模棱两可。使用剥离二进制和C源代码,对asm与源代码的匹配方式进行反向工程当然要容易得多。为clarityOk修改了问题,以便澄清-在这种情况下,如果您运气好,并且没有经过特定编译器的优化,则无法分析程序集本身以找出值?好的,只是澄清一下-在这种情况下,没有办法如果幸运的话,您可以分析程序集本身,并且您的特定编译器没有对其进行优化以找出值?
foo: # @foo
push rax # reserve 8 bytes for the local array
mov byte ptr [rsp + 4], 0 # Silly compiler, could have made the next instruction a qword store of a sign-extended 32-bit immediate to get the 0-termination for free.
mov dword ptr [rsp], 875770417 # the ASCII bytes of the "4321" array initializer
mov rdi, rsp
xor esi, esi
mov edx, 10
call strtol # atoi compiled to strtol(code, NULL, 10)
cmp eax, 4321 # compare retval with immediate constant
mov eax, offset .L.str
mov edi, offset .L.str.1
cmove rdi, rax # select which string literal to pass to puts, based on FLAGS from the compare
pop rax # clear up the stack
jmp puts # TAILCALL
.section .rodata # Godbolt filters directives, re-added this one.
.L.str:
.asciz "Right"
.L.str.1:
.asciz "Wrong"