This PicoCTF Playlist section is called Intro to Assembly, the challenges will go deeper into assembly values, I've already played with some low level code like IDA and Microcorruption, but maybe it will be fun to revisit some concepts.
Bit-O-Asm-1
The first challenge is pretty simple, we have an assembly dump file, and we need to know what is the value in the EAX.
So, what is an assembly dump?
The files like and executable can be read as low level language, and this can be interpreted like a line by line command. This can be used for reverse engineering, taking these commands and transforming into C++ for example, so the users can understand and re-compile the original code.
With that in mind, the computer also have some registers, that store values for computer calculation, one of them is called EAX, and we need the value stored in them.
Here's the dump file:
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x4],edi
<+11>: mov QWORD PTR [rbp-0x10],rsi
<+15>: mov eax,0x30
<+20>: pop rbp
<+21>: ret
The values in assembly works just like a variable in a programming language, so in line <+15>
we have
MOV
(move the value to)
EAX, 0x30
(from 0x30
to EAX
, making EAX = 0x30
)
But we actually need the decimal value, so we put it in our python script HexToDec.py, then we can have the answer:
python3 HexToDec.py 0x30
We take the result with picoCTF{value} and we have the flag:
Answer:Bit-O-Asm-1
picoCTF{48}
Bit-O-Asm-2
This one have the same solution and steps as the last one, actually all the challenges in this document have the same steps, with something more to it.
This one should teach that a value can be pointed to another address, in this case we want the value in EAX
, but the value is actually a line above, that's because assembly can have relative addresses. The address is RBP
(register) -0x4
(minus 4 from the register address).
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x14],edi
<+11>: mov QWORD PTR [rbp-0x20],rsi
<+15>: mov DWORD PTR [rbp-0x4],0x9fe1a
<+22>: mov eax,DWORD PTR [rbp-0x4]
<+25>: pop rbp
<+26>: ret
The solution is the decimal value of 0x9fe1a, so we put it in our python script HexToDec.py, then we can have the answer:
python3 HexToDec.py 0x9fe1a
Answer:Bit-O-Asm-2
picoCTF{654874}
Bit-O-Asm-3
This one teaches us operations, like multiplication and addition in assembly.
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x14],edi
<+11>: mov QWORD PTR [rbp-0x20],rsi
<+15>: mov DWORD PTR [rbp-0xc],0x9fe1a
<+22>: mov DWORD PTR [rbp-0x8],0x4
<+29>: mov eax,DWORD PTR [rbp-0xc]
<+32>: imul eax,DWORD PTR [rbp-0x8]
<+36>: add eax,0x1f5
<+41>: mov DWORD PTR [rbp-0x4],eax
<+44>: mov eax,DWORD PTR [rbp-0x4]
<+47>: pop rbp
<+48>: ret
In this case we need to track where the EAX
is/was, and can have the last result (because it will be modified through the dump file)
For multiplication and addition for Hex values, we will use python terminal and make the calculations there. Just type python
in terminal/cmd and we are set:
- At
<+29>
we have the set of value toEAX
, value at addressRBP-0xC
- At
<+15>
the value toRBP-0xC
is set to0x9fe1a
, makingEAX=0x9fe1a
- At
<+32>
the EAX is multiplied by the value at addressRBP-0x8
- At
<+22>
the value toRBP-0x8
is set to0x4
, makingEAX=0x9fe1a*0x4 = 0x27F868
- At
<+36>
we have the value0x1f5
added toEAX
, making itEAX=0x27F868+0x1f5 = 0x27FA5D
The solution is the decimal value of 0x27FA5D, so we put it in our python script HexToDec.py, then we can have the answer:
python3 HexToDec.py 0x27FA5D
Answer:Bit-O-Asm-3
picoCTF{2619997}
Bit-O-Asm-4
This one teaches us comparisons and branching code (also known as if, elseif, else) and jumps.
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x14],edi
<+11>: mov QWORD PTR [rbp-0x20],rsi
<+15>: mov DWORD PTR [rbp-0x4],0x9fe1a
<+22>: cmp DWORD PTR [rbp-0x4],0x2710
<+29>: jle 0x55555555514e <main+37>
<+31>: sub DWORD PTR [rbp-0x4],0x65
<+35>: jmp 0x555555555152 <main+41>
<+37>: add DWORD PTR [rbp-0x4],0x65
<+41>: mov eax,DWORD PTR [rbp-0x4]
<+44>: pop rbp
<+45>: ret
- At the line
<+22>
it compares(CMP) the values atRBP-0x4
address and0x2710
and the result will be stored. - At the line
<+29>
it checks the Compare operation if the result is equal or less of the last values [other way to see is(RBP-0x4) <= 0x2710
]. If it's true (ifRBP-0x4
is less or equal0x2710
) then jump to the line<+37>
, if it does not, then keep going through the line<+31>
This is kinda difficult to explain, but the J in jmp
or jle
means jump, that's kinda a GOTO another line. And the cmp
is a Compare, something like an IF command.
Going step by step:
- Line
<+22>
Compare theRBP-0x4
address and0x2710
values - Line
<+15>
Set value atRBP-0x4
address to0x9fe1a
, making the comparison0x2710
and0x9fe1a
- Line
<+29>
Compare if0x9fe1a
is equal or less than0x2710
, it is not, the statement is false, so No Jump happens - Line
<+31>
subtract (SUB
) value atRBP-0x4
address by0x65
, making itRBP-0x4=0x9fe1a-0x65 = 0x9FDB5
- Line
<+35>
Jump (jmp
) to the line<+41>
- Line
<+41>
SetEAX
value as the value atRBP-0x4
. SoEAX=0x9FDB5
The solution is the decimal value of 0x9FDB5, so we put it in our python script HexToDec.py, then we can have the answer:
python3 HexToDec.py 0x9FDB5
Answer:Bit-O-Asm-4
picoCTF{654773}
Top comments (2)
My mind is stuck now haha, congratulations on the post, I hope to pay attention to assembly in the future. Something I want to learn.
Oh Assembly is very hard, it's kinda magical when you understand it, but it's not easy hahha, I'm still trying.