September 13, 2026
Reverse Engineering Intro 1: Binaries
This article covers the fundamentals of Reverse Engineering; Binaries. There are numerous articles on the internet covering this topic, theβ¦

By Dave
4 min read
This article covers the fundamentals of Reverse Engineering; Binaries. There are numerous articles on the internet covering this topic, the problem however is the issue of comprehension. Most articles i have read are filled with overcomplicated explanations that often renders me frustrated and discouraged from reading further. This article dumbs it down for you.
What Are Binaries?
In simple words, binaries are sets of instructions that tells the CPU what operations to perform. When you write C, Python, or Rust, that source code is human-readable. A binary is the translation into the only language the computer actually understands: instructions encoded as 0s and 1s. Binaries are compiled, meaning the majority of software are binaries.
Why Do I Need This Information?
Well, if you're reading this article, the probability of you being in the cyber security space or tech in general is high. As a cyber security analyst you ought to know this information because
- Malware doesn't come with source code. If you're doing incident response or threat analysis, the binary is the only ground truth you get. Everything else β vendor reports, YARA rules, behavioral summaries β is someone else's interpretation of what the binary does.
- Vulnerability research often starts where source ends. Closed-source software, firmware, embedded devices, old legacy systems with no surviving source β reversing is frequently the only way in.
- It builds true mental models of computers. Reverse engineering is fundamentally about better understanding how computers work, not just about hacking β you stop treating "the compiler," "the stack," "a function call" as black boxes and start seeing exactly what they cost in instructions
- It's the foundation under exploit development, CTFs, and defensive tooling alike. When ever you're given a task or you come across a program you wish to analyse, the very first instinct should be on reconnaissance; "What does this program do?".
Let's get to the technicalities. Let's look at a simple program and try to find out what it entails.
I created a simple crackme(a CTF challenge)to help us understand better how binaries operate. We are to find the password.
For this operation, we use a tool known as "OBJDUMP". Objdump is a linux tool(oh yeah, forgot to mention RE mostly happens in a linux environment, you gotta switch to linux lol) that aids you to inspect binaries. When you run the command.
The first stage of all challenges is reconnaissance. Let's run some commands to figure out what we're up against.
File crackme01File crackme01File: Its function is to identify what type of file something actually is by examining its contents, rather than simply trusting the filename extension. That last part is key: not stripped means function names, variable names, and debug symbols are still embedded in the binary. That's a gift.
Lets run another command;
strings crackme01strings crackme01Strings are readable text sequences embedded in a binary: error messages, menu text, prompt text, format specifiers, URLs, file paths, registry keys, hardcoded credentials, debug log messages, and imported/exported symbol names. They typically live in sections like .rodata/.rdata, but can also appear in .data, resources, or scattered in code. We're trying to to see if the author(me) left some sort of information for us.
It seems he(I) did. Let's try out this password and see what we get!
Yeah No, it didn't work out!. I guess we would do this the fun way.
objdump -d crackme01objdump -d crackme01
This command gives you an output as such as this. Please, worry less about the length of it, worry less about how much you do not understand, stay with me and let's get through this. The core information as to how to solve this challenge is found in the
section.From the main section, something attracts us. Here we find the binary that assesses if we indeed typed the decoy password.
We were duped, the actor deliberately hardcoded the password to trick us to thinking we actually got it.
Block 1 β the decoy check (1371β13a2)
1371β1385: set up and call strcmp(input, DECOY_PASSWORD)
138aβ138c: test the result, jne 13a4 (jump ahead if DIFFERENT)1371β1385: set up and call strcmp(input, DECOY_PASSWORD)
138aβ138c: test the result, jne 13a4 (jump ahead if DIFFERENT)If we don't jump (strings were equal β decoy typed):
138eβ1398: puts("Close, but no...")
139d: mov $0x1,%eax β set return value to 1
13a2: jmp 140a β jump straight to the end of main138eβ1398: puts("Close, but no...")
139d: mov $0x1,%eax β set return value to 1
13a2: jmp 140a β jump straight to the end of mainBlock 2 β setting up check_layer2 (13a4β13ae)
13a4: lea -0x90(%rbp),%rax β address of your input
13ab: mov %rax,%rdi β put it in the 1st argument box
13ae: call check_layer2 β check_layer2(input)13a4: lea -0x90(%rbp),%rax β address of your input
13ab: mov %rax,%rdi β put it in the 1st argument box
13ae: call check_layer2 β check_layer2(input)Notice this address, 13a4, is exactly where Block 1's jne jumps to if you didn't type the decoy. That's the literal mechanism connecting "you didn't fall for the decoy" to "now we actually run the real check." The jump target isn't arbitrary β it's precisely the next if statement's setup code.
13b3β13b5: test %eax,%eax, jne 13cd (jump ahead if check_layer2 PASSED)13b3β13b5: test %eax,%eax, jne 13cd (jump ahead if check_layer2 PASSED)If we don't jump (check_layer2 returned 0 β failed):
13b7β13c1: puts("Access denied.")
13c6: mov $0x1,%eax
13cb: jmp 140a13b7β13c1: puts("Access denied.")
13c6: mov $0x1,%eax
13cb: jmp 140aBlock 3 β setting up check_layer3 (13cdβ13d7)
13cd: lea -0x90(%rbp),%rax β address of your input, again
13d4: mov %rax,%rdi β 1st argument box
13d7: call check_layer3 β check_layer3(input)13cd: lea -0x90(%rbp),%rax β address of your input, again
13d4: mov %rax,%rdi β 1st argument box
13d7: call check_layer3 β check_layer3(input)Same story β 13cd is exactly where Block 2's jne sends you if check_layer2 passed. Each check's "you passed" jump target is precisely the next check's setup code. That's the chain, made entirely of jump targets pointing forward.
Scrumbling through the
sections, we would notice that there has been a lot of "Call" functions to the sections of "Layer 2" and "Layer 3". Let's go investigate.
Going through the first few lines; this part grabs my attention. "0xc" is hex for 12, therefore, it seems what we're in search of is a 12 digit password. Reading through the binary, all the check_layer2 section talks about is the length of the password alongside the fact that it has been XORed. XOR is reversible.
Too Be Continuedβ¦β¦β¦ Anyways; here is the link to download the resources: