我有这个问题我需要帮助。我应该检测这个问题的密码(答案),这是汇编中的参数之一。
输出:
在此级别中,您需要使用gdb来查找密码 作为参数传递给具有6个参数的函数。对于x86-64, 使用寄存器传递参数的助记符是Diane的丝质连衣裙 售价89美元。 (rdi rsi rdx rcx r8 r9)
输入密码:
我相信函数的objdump代码有6个参数 -
00000000004006a1 <foo>:
4006a1: 55 push %rbp
4006a2: 48 89 e5 mov %rsp,%rbp
4006a5: 53 push %rbx
4006a6: 48 83 ec 48 sub $0x48,%rsp
4006aa: 48 89 7d d8 mov %rdi,-0x28(%rbp)
4006ae: 48 89 75 d0 mov %rsi,-0x30(%rbp)
4006b2: 48 89 55 c8 mov %rdx,-0x38(%rbp)
4006b6: 48 89 4d c0 mov %rcx,-0x40(%rbp)
4006ba: 4c 89 45 b8 mov %r8,-0x48(%rbp)
4006be: 4c 89 4d b0 mov %r9,-0x50(%rbp)
4006c2: c7 45 e4 01 00 00 00 movl $0x1,-0x1c(%rbp)
4006c9: 48 8b 45 c0 mov -0x40(%rbp),%rax
4006cd: 48 89 c7 mov %rax,%rdi
4006d0: e8 5b fe ff ff callq 400530 <strlen@plt>
4006d5: 89 45 ec mov %eax,-0x14(%rbp)
4006d8: 8b 45 ec mov -0x14(%rbp),%eax
4006db: 48 63 d8 movslq %eax,%rbx
4006de: 48 8b 45 b0 mov -0x50(%rbp),%rax
4006e2: 48 89 c7 mov %rax,%rdi
4006e5: e8 46 fe ff ff callq 400530 <strlen@plt>
4006ea: 48 39 c3 cmp %rax,%rbx
4006ed: 74 07 je 4006f6 <foo+0x55>
4006ef: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%rbp)
4006f6: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%rbp)
4006fd: eb 31 jmp 400730 <foo+0x8f>
4006ff: 8b 45 e8 mov -0x18(%rbp),%eax
400702: 48 63 d0 movslq %eax,%rdx
400705: 48 8b 45 b8 mov -0x48(%rbp),%rax
400709: 48 01 d0 add %rdx,%rax
40070c: 0f b6 10 movzbl (%rax),%edx
40070f: 8b 45 e8 mov -0x18(%rbp),%eax
400712: 48 63 c8 movslq %eax,%rcx
400715: 48 8b 45 b0 mov -0x50(%rbp),%rax
400719: 48 01 c8 add %rcx,%rax
40071c: 0f b6 00 movzbl (%rax),%eax
40071f: 38 c2 cmp %al,%dl
400721: 74 09 je 40072c <foo+0x8b>
400723: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%rbp)
40072a: eb 0c jmp 400738 <foo+0x97>
40072c: 83 45 e8 01 addl $0x1,-0x18(%rbp)
400730: 8b 45 e8 mov -0x18(%rbp),%eax
400733: 3b 45 ec cmp -0x14(%rbp),%eax
400736: 7c c7 jl 4006ff <foo+0x5e>
400738: 8b 45 e4 mov -0x1c(%rbp),%eax
40073b: 48 83 c4 48 add $0x48,%rsp
40073f: 5b pop %rbx
400740: 5d pop %rbp
400741: c3 retq
我相信从4006aa到4006be是参数。但是,当我逐个输入这些寄存器的值作为答案时,它说它不是正确的答案(例如,-0x28)。我尝试输入十进制,十六进制和二进制的答案。我使用gdb来调试它并打印出函数中的6个参数寄存器,并将这些值单独作为答案使用,它也没有用。我被卡住了。我可以就如何解决这个问题提供一些指导吗?
请注意,我无法访问此问题的c代码或人类编写的汇编代码。只有objdump代码和可执行文件。
如果您想亲自尝试一下,我可以为此提供可执行文件:https://www.mediafire.com/file/uglm044vw87lb11/ParamsRegs
答案 0 :(得分:2)
4006e5: callq 400530 <strlen@plt>
调用函数来确定字符串的长度。它使用与函数相同的调用约定,在RDI中使用const char *
arg。它来自你的第四个功能arg:
4006b6: mov %rcx,-0x40(%rbp)
4006c9: mov -0x40(%rbp),%rax
4006cd: mov %rax,%rdi
此C标准库函数返回rax
中字符串的大小。你的函数接受它的低32位并将其符号扩展到rbx
(可能是源int len = strlen(arg4);
):
4006d5: mov %eax,-0x14(%rbp)
4006d8: mov -0x14(%rbp),%eax
4006db: movslq %eax,%rbx
在4006de
到4006e5
,同样的过程再次完成,另一个字符串设置为4006be: mov %r9,-0x50(%rbp)
,在第二次调用之后,该函数比较长度:
4006ea: cmp %rax,%rbx
我的猜测是,其中一个字符串是您要查找的密码,另一个是您输入的字符串。只需在4006a1
暂停执行,使用info registers
打印寄存器,使用rcx
查看r9
和x/s <value in rcx/r9>
。
或者,如果此函数的调用者将您的输入解析为多个字符串参数,可能使用scanf
,那么这两个字的长度必须相同。