TryHackMe - Intro to x86-64
Room: Intro to x86-64
This room will look at the basic primitives of Intel’s x86-64 assembly language, and will use these primitives to understand the construction of basic programs using loops, functions and procedures. The tasks attached to this room will use the r2 reverse engineering framework. Note, this room uses AT&T syntax.
# open the binary in debugging mode
r2 -d <binary>
# analyses all symbols and entry points in the executable
aa
# ensure that you are using the AT&T syntax
e asm.syntax=att
# find a list of the functions
afl
# print disassembly function
pdf @main
Since the architecture is x86-64, the registers are 64 bit and Intel has a list of 16 registers:
64 bit | 32 bit |
---|---|
%rax | %eax |
%rbx | %ebx |
%rcx | %ecx |
%rdx | %edx |
%rsi | %esi |
%rdi | %edi |
%rsp | %esp |
%rbp | %ebp |
%r8 | %r8d |
%r9 | %r9d |
%r10 | %r10d |
%r11 | %r11d |
%r12 | %r12d |
%r13 | %r13d |
%r14 | %r14d |
%r15 | %r15d |
Even though the registers are 64 bit, meaning they can hold up to 64 bits of data, other parts of the registers can also be referenced. In this case, registers can also be referenced as 32 bit values as shown. What isn’t shown is that registers can be referenced as 16 bit and 8 bit(higher 4 bit and lower 4 bit).
The first 6 registers are known as general purpose registers. The %rsp is the stack pointer and it points to the top of the stack which contains the most recent memory address. The stack is a data structure that manages memory for programs. %rbp is a frame pointer and points to the frame of the function currently being executed - every function is executed in a new frame.
The following questions involve analysing the if2 binary.
-
What is the value of var_8h before the popq and ret instructions?
Open program with
r2 -d if2
. Then, analyze withaa
. Runpdf @main
to find the address of the instruction before popq. Rundb <address>
to set a breakpoint anddc
to reach it. Then at the zero offset after runningpx @rbp-0x8
, the value is 0x60, or 96. -
What is the value of var_ch before the popq and ret instructions?
Run
px @rbp-0xc
, the value at the zero offset is 00. -
What is the value of var_4h before the popq and ret instructions?
Run
px @rbp-0x4
, the value at the zero offset is 01. -
What operator is used to change the value of var_8h, input the symbol as your answer (symbols include +, -, *, /, &, |):
The value is changed using the
andl $0x64, var_8h
instruction; the operator is&
.
Use the loop2 binary to answer the following questions.
-
What is the value of var_8h on the second iteration of the loop?
Drop a breakpoint at the comparison function and run
dc
three times. The first comparison is unconditionally jumped to, the third is the second iteration of the loop.px @rbp-0x8
says 5. -
What is the value of var_ch on the second iteration of the loop?
px @rbp-0xc
says 0. -
What is the value of var_8h at the end of the program?
px @rbp-0x8
says 2. -
What is the value of var_ch at the end of the program?
px @rbp-0xc
says 0.
crackme1 and crackme2
Go to the crackme folder and analyse the crackme1 binary. This binary checks if the user has a correct password, and this can be done by running the binary and entering the password.
-
What is the password?
Put a breakpoint at the strcmp function. We can see the %rdi and %rsi registers being loaded before
callq sym.imp.strcmp
. This is because the conventional use of %rdi and %rsi are as the 1st and 2nd argument, respectively. Justpx
these arguments, and the password you didn’t provide is the answer. Mine actually showed 127.0.1, but given the format I intuited the password to be 127.0.0.1.
Analyze the crackme2 binary and try find the correct password, as with the previous question.
-
What is the correct password?
The file /home/tryhackme/install_files/secret.txt is opened in the program. It contains the string “vs3curepwd”. After “Please enter password” is printed, I saw “%11s” being saved into %rdi, the first argument, for scanf. The secret.txt string was 10 characters long (plus 1 character for ‘/n’), which is the length expected for the password. Once the strlen of the provided password is checked, we enter a loop of accessing each character of the provided string against the one from the file. Except we iterate over one in reverse, and the last character is checked against the first of the other until the opposite occurs. If every character matches like so, it is the correct password. To verify, I changed the contents of the secret.txt file to
aaaaaaaaaa
among other 10 character strings and provided their reverse as passwords, and binary exited successfully.