0

I have this question that I need help on. I'm supposed to detect the password (the answer) to this problem which is one of the parameters in assembly.

Output:

In this level, you will need to use gdb to find the password as it is being passed as a parameter to a function with 6 parameters. For x86-64, the mnemonic for passing parameters using registers is Diane's Silk Dress Cost $89. (rdi rsi rdx rcx r8 r9)

Enter the password:

The objdump code of the function I believe has the 6 parameters --

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

I believe from 4006aa to 4006be is the parameters. However, when I entered the values of those registers one by one individually as the answer, it said it wasn't the right answer (ex, -0x28). I tried inputting the answers in decimal, hex, and binary. I used gdb to debug it and print out the 6 parameter registers in the function and use those values gotten as the answer individually, it didn't work either. I'm stuck. Can I have some guidance on how to go about this problem?

note that I don't have access to the c code for this problem, or the assembly code written by a human. Only the objdump code, and the executable.

Here's the executable that I was given for this if you guys want to try it yourself to be able to help me out: https://www.mediafire.com/file/uglm044vw87lb11/ParamsRegs

  • That's an amusing mnemonic. The way I remember the x86-64 SysV calling convention is that the args are set up so `memcpy` could inline as `rep movsb` ([rdi] <- [rsi]), but with rcx and rdx swapped because the calling-convention designer wanted to avoid using RCX for a fixed purpose in functions with only 3 args, because it has more required uses than RDX (e.g. shift counts). (See [amd64.org mailing list archive links](https://stackoverflow.com/questions/4429398/why-does-windows64-use-a-different-calling-convention-from-all-other-oses-on-x86/35619528#35619528).) – Peter Cordes May 24 '18 at 07:15
  • Can you copy-paste `objdump` output without collapsing spaces? That's *very* ugly to read vs. having all the mnemonics start at a consistent column. Anyway, yes it has 6 args. The compiler spills all the register args to the stack at the start of the function, so we can tell it was compiled in debug mode (and that there are 6 args). I don't see any accesses to `8(%rbp)` or any other positive offset, so there aren't any stack args beyond the 6 register args. – Peter Cordes May 24 '18 at 07:19
  • 1
    @PeterCordes I like his mnemonic more than yours. – David Hoelzer May 24 '18 at 10:27
  • @DavidHoelzer: Mine was never intended to be a memory aid, more like an additional fun fact about how the ABI was designed / why it makes sense once you do remember it. (I'm lucky to have a good memory, so I tend to just remember things after having to look them up a couple times. But having it make some kind of sense and connect with other things I know helps it stick.) – Peter Cordes May 24 '18 at 10:51
  • Sorry, @PeterCordes, I think you took my comment too seriously. :) :) – David Hoelzer May 24 '18 at 16:24
  • @DavidHoelzer: yes, apparently >.< I agree the OP's mnemonic is more fun. :) – Peter Cordes May 24 '18 at 18:17
  • Line `4006d5` and `4006d8` is fun. And `4006c9` and `4006ce`. Is there any reason y the compiler did this? – sivizius May 24 '18 at 18:47

1 Answers1

2

4006e5: callq 400530 <strlen@plt> calls a function to determine the length of a string. It uses the same calling convention as your function, taking a const char * arg in RDI. It's set here, from your 4th function arg:

4006b6: mov %rcx,-0x40(%rbp)
4006c9: mov -0x40(%rbp),%rax
4006cd: mov %rax,%rdi

This C standard library function returns the size of the string in rax. Your function takes the low 32 bits of it and sign-extends that into rbx (presumably the source did int len = strlen(arg4);):

4006d5: mov %eax,-0x14(%rbp)
4006d8: mov -0x14(%rbp),%eax
4006db: movslq %eax,%rbx

At 4006de to 4006e5 the same procedure is done again with another string set at 4006be: mov %r9,-0x50(%rbp) and after this second call, the function compares the lengths:

4006ea: cmp %rax,%rbx

my guess is, that one of this strings is the password you are looking for and the other one is the string you put in. Just pause the execution at 4006a1, print the registers with info registers, look at rcx and r9 with x/s <value in rcx/r9>.

Or if the caller of this function parses your input into multiple string args, maybe with scanf, then those two words need to be the same length.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
sivizius
  • 450
  • 2
  • 14