picoCTF: asm4 writeup
Description
What will asm4(“picoCTF_f97bb”) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submission for this question will NOT be in the normal flag format.
- Category: Reverse Engineering
- Points: 400
Hints
Treat the Array argument as a pointer.
Source Code
asm4: <+0>: push ebp <+1>: mov ebp,esp <+3>: push ebx <+4>: sub esp,0x10 <+7>: mov DWORD PTR [ebp-0x10],0x27a <+14>: mov DWORD PTR [ebp-0xc],0x0 <+21>: jmp 0x518 <asm4+27> <+23>: add DWORD PTR [ebp-0xc],0x1 <+27>: mov edx,DWORD PTR [ebp-0xc] <+30>: mov eax,DWORD PTR [ebp+0x8] <+33>: add eax,edx <+35>: movzx eax,BYTE PTR [eax] <+38>: test al,al <+40>: jne 0x514 <asm4+23> <+42>: mov DWORD PTR [ebp-0x8],0x1 <+49>: jmp 0x587 <asm4+138> <+51>: mov edx,DWORD PTR [ebp-0x8] <+54>: mov eax,DWORD PTR [ebp+0x8] <+57>: add eax,edx <+59>: movzx eax,BYTE PTR [eax] <+62>: movsx edx,al <+65>: mov eax,DWORD PTR [ebp-0x8] <+68>: lea ecx,[eax-0x1] <+71>: mov eax,DWORD PTR [ebp+0x8] <+74>: add eax,ecx <+76>: movzx eax,BYTE PTR [eax] <+79>: movsx eax,al <+82>: sub edx,eax <+84>: mov eax,edx <+86>: mov edx,eax <+88>: mov eax,DWORD PTR [ebp-0x10] <+91>: lea ebx,[edx+eax*1] <+94>: mov eax,DWORD PTR [ebp-0x8] <+97>: lea edx,[eax+0x1] <+100>: mov eax,DWORD PTR [ebp+0x8] <+103>: add eax,edx <+105>: movzx eax,BYTE PTR [eax] <+108>: movsx edx,al <+111>: mov ecx,DWORD PTR [ebp-0x8] <+114>: mov eax,DWORD PTR [ebp+0x8] <+117>: add eax,ecx <+119>: movzx eax,BYTE PTR [eax] <+122>: movsx eax,al <+125>: sub edx,eax <+127>: mov eax,edx <+129>: add eax,ebx <+131>: mov DWORD PTR [ebp-0x10],eax <+134>: add DWORD PTR [ebp-0x8],0x1 <+138>: mov eax,DWORD PTR [ebp-0xc] <+141>: sub eax,0x1 <+144>: cmp DWORD PTR [ebp-0x8],eax <+147>: jl 0x530 <asm4+51> <+149>: mov eax,DWORD PTR [ebp-0x10] <+152>: add esp,0x10 <+155>: pop ebx <+156>: pop ebp <+157>: ret
Solution
- Note: Filename that has the assembly code test.S
- Looking at the assembly code we have it looks complex to solve by hand. I tried the x86 assembly emulator discussed in the previous post (asm3). But it gives me compilation errors probably because I’m using a string argument.
- So I got to improvise. You also can use GCC to execute this assembly code. Simply, this technique involves mapping our assembly code to a C program and then using GCC to compile that C program. Which ultimately executes our assembly code.
- To start with we got to format our assembly code function (asm4) so that our C program can call the function.
.intel_syntex prefix .global asm4 asm4: push ebp mov ebp,esp push ebx sub esp,0x10 mov DWORD PTR [ebp-0x10],0x27a mov DWORD PTR [ebp-0xc],0x0 jmp asm4+27 add DWORD PTR [ebp-0xc],0x1 mov edx,DWORD PTR [ebp-0xc] mov eax,DWORD PTR [ebp+0x8] add eax,edx movzx eax,BYTE PTR [eax] test al,al jne asm4+23 mov DWORD PTR [ebp-0x8],0x1 jmp asm4+138 mov edx,DWORD PTR [ebp-0x8] mov eax,DWORD PTR [ebp+0x8] add eax,edx movzx eax,BYTE PTR [eax] movsx edx,al mov eax,DWORD PTR [ebp-0x8] lea ecx,[eax-0x1] mov eax,DWORD PTR [ebp+0x8] add eax,ecx movzx eax,BYTE PTR [eax] movsx eax,al sub edx,eax mov eax,edx mov edx,eax mov eax,DWORD PTR [ebp-0x10] lea ebx,[edx+eax*1] mov eax,DWORD PTR [ebp-0x8] lea edx,[eax+0x1] mov eax,DWORD PTR [ebp+0x8] add eax,edx movzx eax,BYTE PTR [eax] movsx edx,al mov ecx,DWORD PTR [ebp-0x8] mov eax,DWORD PTR [ebp+0x8] add eax,ecx movzx eax,BYTE PTR [eax] movsx eax,al sub edx,eax mov eax,edx add eax,ebx mov DWORD PTR [ebp-0x10],eax add DWORD PTR [ebp-0x8],0x1 mov eax,DWORD PTR [ebp-0xc] sub eax,0x1 cmp DWORD PTR [ebp-0x8],eax jl asm4+51 mov eax,DWORD PTR [ebp-0x10] add esp,0x10 pop ebx pop ebp ret
- Now that our assembly code is using intel syntex, asm4 function is global. We can start creating our C program (I’m calling it solve.c). I’ve explained what’s happening in the comments.
#include <stdio.h> int main(int argc, char const *argv[]) { /* 1. Call asm4(). Passing the argument "picoCTF_f97bb". 2. Now print the result after calling the function. 3. Note: %x denotes hex output */ printf("\n\nOutput => 0x%x\n\n", asm4("picoCTF_f97bb")); return 0; }
- Now we need to create a Makefile that has the commands to build and run our C program. Which contains:
all: gcc -m32 -c test.S -o test.o -fno-stack-protector -no-pie gcc -m32 -c solve.c -o solve.o -fno-stack-protector -no-pie gcc -m32 -o a.out solve.o test.o -fno-stack-protector -no-pie ./a.out clean: rm a.out *.o
- Now we can execute the Makefile by typing “Make”:

- Flag: 0x256
Additional
- When you execute make. You might get a error like so:
"fatal error: bits/libc-header-start.h: No such file or directory" while compiling HTK
- This happens when your using a 64bit system and you want to compile to x86 (32bit). To fix this you must install the x86 gcc components in your system. I fixed this issue by installing this package:
sudo apt-get install gcc-multilib
- Resources I found helpful to fix this issue:
I hope you have learned something valuable. If you like this post please share it with your fellow hacker mates and if you have any questions & or suggestions please feel free to post them down in the comments. Iād love to hear and learn from you.
Have a great day guys š. See you in the next post.