在Assembly中传递参数

时间:2018-05-24 06:58:42

标签: function assembly parameters objdump

我有这个问题我需要帮助。我应该检测这个问题的密码(答案),这是汇编中的参数之一。

输出:

在此级别中,您需要使用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

1 个答案:

答案 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

4006de4006e5,同样的过程再次完成,另一个字符串设置为4006be: mov %r9,-0x50(%rbp),在第二次调用之后,该函数比较长度:

4006ea: cmp %rax,%rbx

我的猜测是,其中一个字符串是您要查找的密码,另一个是您输入的字符串。只需在4006a1暂停执行,使用info registers打印寄存器,使用rcx查看r9x/s <value in rcx/r9>

或者,如果此函数的调用者将您的输入解析为多个字符串参数,可能使用scanf,那么这两个字的长度必须相同。