crackmes
crackmes copied to clipboard
Q&A on using Radare2
Hello, I'm new to Reverse Engineering and thank you from providing the tutorial. I encountered one issue under crackme03.c that as I have installed Radare2 and run r2 ./crackme03.64, I get a prompt like [0x000005d0]>, but when I enter afl, no result is returned. Any possible cause and/or solution to this issue? (Debian 9/Radare2 v3.0.1)
From https://leotindall.com/tutorial/an-intro-to-x86_64-reverse-engineering/:
It turns out that the command we want is aaaa: analyze using all functions using all normal and all experimental techniques. This means that Radare has a list of functions available to us. We can view it with afl: analyze functions, displaying a list.
Did you run aaaa
first?
Yeah, that's it. Thanks!
Still, more issues are coming up on the "visual mode 2" of radare2:
-
I can toggle between the columns and scroll vertically to browse the code, yet how can I scroll horizontally to view the lines stretching beyond the margin of the box? (Or else, do I have to fit my font size for the lengthy lines?)
-
You wrote:
Every time a jump instruction appears, the block ends and lines come out, pointing to other blocks. For instance, in the top block (the beginning of the function), the jne instruction which checks for the argument number causes a red line to come out to the left and a green one to the right.
However, I can tell every single character of the flown lines is displayed in cyan.
- You also wrote:
On the right, you should see a block that looks a bit like this:
.---------------------------------------------.
| 0x7cc ;[ga] |
| ; const char * s |
| ; 0x8a4 |
| ; "Need exactly one argument." |
| lea rdi, str.Need_exactly_one_argument. |
| call sym.imp.puts;[gh] |
| ; -1 |
| mov eax, 0xffffffff |
| jmp 0x7c6;[gg] |
`---------------------------------------------'
And what I get is like this:
:::| ; CODE XREF from main (0x742) :::| 0x000007b7 lea rdi, str.Need_exactly_one_argument. ; 0x884 ; "Need exactly one argument." :::| 0x000007be call sym.imp.puts ; int puts(const char *s) :::| 0x000007c3 mov eax, 0xffffffff ; -1 `====< 0x000007c8 jmp 0x7b1
It seems that the main diffs are remarks like ;[ga] ;[gh] and ;[gg], but what do they indicate?
Hey, I've just finished the crackme03.c section and here are two more issues:
- You wrote:
This block sets rax to r8d (which we know is zero), then loads a single byte from its third argument, indexed by eax. Going back to our arg list, this argument is &local_2h, so it’s loading (&local_2h)[0].
It then adds a byte loaded from the second argument indexed by eax ((&local_9h)[0]), and compares it to a byte loaded from its first argument indexed by eax (argv[1][0]). Remember that this is a loop, so eax will change. In other words:
while (/* something?? */) { char temp = arg3[eax] + arg2[eax]; if (temp != arg1[eax]) { return 0; // failure } }
...
while (arg2[eax] != 0) { char temp = arg3[eax] + arg2[eax]; if (temp != arg1[eax]) { return 0; // failure } eax++; } return 1;
...
Looking at the arguments passed in main, we can see that the program is adding (&local_2h)[eax] to (&local_9h)[eax]. I suggest going back to the main function (exit visual mode; pdf@main) to look at what each of those values will be.
It seems that each 'eax' in these paragraphs should have been 'rax', as 'eax' is a different register used to indicate status rather than offset.
- You wrote:
Anyway, our table of values starting at local_2h is [2, 3, 2, 3, 5, 0]. These aren’t printable ASCII characters, so presumably the hard-coded password is stored at the other input value: local_9h.
The mov instruction above is sized for a double word (dword); a 32-bit value. It’s followed by a word-sized value, then a byte-sized zero. That works out to 4+2 = 6 bytes, plus a null terminator, so it’s a good bet that these three locations together form a string. Indeed, if we write out the values with byte seperation, it makes sense: 42 6d 41 6c 41 64 00 is a well-formed null-terminated string, with values in the printable ASCII range.
All that’s left is to add the offsets to them, giving us 44 70 43 6e 44 64 00. Translating these to ASCII, we get: DpCnDd.
As 0x6c + 3 = 0x6f and 0x41 + 5 = 0x46, the big-endian result ought to be 44 70 43 6f 46 64 00, or DpCoFd.