0% found this document useful (0 votes)
36 views

Reverse Engineering Assignment

The assignment report focuses on the reverse engineering of compiled C programs using the gdb debugger to find hidden flags within the memory. This report includes detailed analyses of four challenges, each increasing in complexity. The challenges involved finding number flags in RAM, determining if a flag is a number, and tracking variations of changing numbers during script execution. The report includes a section dedicated to each challenge, detailing the reverse engineering process, gdb

Uploaded by

adane
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Reverse Engineering Assignment

The assignment report focuses on the reverse engineering of compiled C programs using the gdb debugger to find hidden flags within the memory. This report includes detailed analyses of four challenges, each increasing in complexity. The challenges involved finding number flags in RAM, determining if a flag is a number, and tracking variations of changing numbers during script execution. The report includes a section dedicated to each challenge, detailing the reverse engineering process, gdb

Uploaded by

adane
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Title: - Reverse Engineering Assignment Report

Master of Cybersecurity, AAIT

Prepared By: -
Adane Getnet | GSR/3704/15 [email protected]
Sewalem Alemu | GSR/0198/15

Submitted to: - Dr. Marco Rocchett


March 19 202
Table of Contents
Abstract.................................................................................................................................................. 2
Introduction .......................................................................................................................................... 2
Assignment Overview ........................................................................................................................... 2
Process Description ............................................................................................................................... 3
Challenge 1 (Easiest) .......................................................................................................................... 3
The flag of ex1 is a number,................................................................................................................. 3
Challenge 2: ....................................................................................................................................... 4
 The flag of ex2 is a number ..................................................................................................... 4
Challenge 3: ....................................................................................................................................... 5
 The flag of ex3 is a number? ....................................................................................................... 5
Challenge 4(hard) .............................................................................................................................. 6
 The flag of ex4 is a pair of numbers that changes over the execution of the script.\ ................... 6

PAGE 1
Abstract
The assignment report focuses on the reverse engineering of compiled C programs using the gdb
debugger to find hidden flags within the memory. This report includes detailed analyses of four
challenges, each increasing in complexity. The challenges involved finding number flags in
RAM, determining if a flag is a number, and tracking variations of changing numbers during
script execution. The report includes a section dedicated to each challenge, detailing the reverse
engineering process, gdb commands used, and identification of the source code.

Introduction
This assignment report explored the process of reverse engineering built C programs using the
gdb debugger. The aim was to employ debugging methodologies to retrieve concealed data from
executable files, offering practical exposure to examining generated code and comprehending the
inner workings of programs at a lower abstraction level. We gained a better understanding of
memory management, program execution, and debugging tools such as gdb by breaking down
and decoding the compiled programs. This report demonstrated how we reversed four tasks with
different levels of difficulty, outlining the procedures followed, gdb commands used, and
discoveries made along the inquiry. We hope to improve our abilities to reverse engineer, debug,
and find hidden information in compiled binaries with this activity.

Assignment Overview
1. We utilized debugging techniques to analyze compiled code and understand program
behavior at a lower level.
2. We extracted hidden information from executable files by dissecting and decoding the
compiled programs.
3. We enhanced our skills in memory management, program execution, and debugging tools
such as gdb.
4. We investigated four challenges of varying complexity to practice reverse engineering
and debugging skills.

PAGE 2
Process Description
We explained the steps followed during the reverse engineering process.

CHALLENGE 1 (EASIEST)
The flag of ex1 is a number, somewhere in the RAM?

Step 1:- Load the compiled C program into gdb.

Step 2:- Set breakpoints at relevant points. In our case at main methods

Step 3:- Run the program and observe memory changes.

Mov BYTE PTR [rbp-0x1], 0x1: Store the value 1 in the memory location [rbp-0x1].

Step 4:- Inspect memory locations for any hidden strings or numbers.

 Once we got the flag, the number was 1

Step 5:- expected c code will be

#include <stdio.h>

int main() {

char Val =1;

return 0;

Observation: - The function initializes a variable with the value 1 and performs minimal operations.

PAGE 3
CHALLENGE 2:
 The flag of ex2 is a number, somewhere in the RAM
Step 1:- Similar to Challenge 1, but with increased complexity.
 Load the Target in gdb
 Set breakpoints at relevant points where I suspected the flag might be accessed or
manipulated. in my case started by setting a breakpoint at the beginning of the main
function: (gdb) break main

Breakdown of the instructions:


1. push rbp: Pushes the value of the base pointer (rbp) onto the stack. This is typically done at
the beginning of a function to set up the stack frame.
2. mov rbp, rsp: Moves the value of the stack pointer (rsp) into the base pointer (rbp). This
establishes the stack frame for the function.
3. mov QWORD PTR [rbp-0x8], 0x10000: Stores the value 0x10000 (65536 in decimal) into
the memory location [rbp-0x8]. The QWORD PTR specifies that it’s a 64-bit value.
4. mov eax, 0x0: Sets the value of the eax register to zero.
5. pop rbp: Pops the value from the stack back into the base pointer (rbp). This is the reverse
operation of the initial push rbp.
6. ret: Returns from the function. It pops the return address from the stack and transfers control
back to the calling function.
Step 2:- Pay attention to memory regions where the flag might be stored. We
Used gdb commands like x (examine memory) and info registers to inspect memory and
registers.

 The assembly code initializes a 64-bit variable (QWORD PTR [rbp-0x8]) with the
value 0x10000.


 A flag is a number 65536
Step 4:- Write a C program that you think is the source code of the program
#include <stdio.h>
int main() {
long int value = 65536;
return result;
}

PAGE 4
CHALLENGE 3:
 The flag of ex3 is a number?
Step 1: Load the compiled C program into GDB.

Step 2: - I interpreted the instruction code as follows


1. sub 0x20, rsp: Allocate 32 bytes of space on the stack.
2. mov fs:0x28, rax: Load the value of the segment register fs at offset 0x28 into rax
3. mov rax, rbp-0x8): Store the value of rax (stack canary) at [rbp-0x8].
4. xor eax, eax: Set eax (accumulator) to 0.
5. movq $0x32445341, [rbp-0x12]: Store the value 0x32445341 at [rbp-0x12].
6. movw $0x0,[rbp-0xa]: Store the value 0x0 (null) in the lower 2 bytes of [rbp-0xa].
7. mov $0x0, eax: Set eax to 0.
8. mov (rbp-0x8), rdx: Load the value from [rbp-0x8] into rdx.
9. sub fs:0x28, rdx: Calculate the difference between the stack canary (fs:0x28) and the stored value (rdx).
10. je 0x55555555518b <main+66>: If the difference is zero (no stack overflow), jump to address
0x55555555518b.
11. call 0x555555555050 __stack_chk_fail@plt: Otherwise, call stack fail
Step 3:- Set breakpoints at key points in the program to inspect memory and registers. Stepped
through instructions, inspected contents, and identified any operations related to the flag.

 QWORD PTR is an 8-byte data size of ASCII value so that the flag is “ASD2”, So that the
flag is not a number
Step 4: Equivalent C code
#include <stdio.h>
int main() {
char valu[8]="ASD2";
short a=0;
if(valu[8]){
}
return 0;

PAGE 5
CHALLENGE 4(HARD)
 The flag of ex4 is a pair of numbers that changes over the execution of the script.\
Step 1:- disassembling and Assembly instruction interpretation.

This assembly code initializes two variables (V1 and V2), performs a loop, and modifies their values
based on certain conditions. The final result depends on the execution path taken within the loop.

1. mov DWORD PTR [rbp-0x4], 0x3: Store the value 3 in the memory location [rbp-0x4].
2. mov DWORD PTR [rbp-0x8], 0x0: Store the value 0 in the memory location [rbp-0x8].
3. jmp 0x55555555515c: Unconditional jump to the address 0x55555555515c.
4. cmp DWORD PTR [rbp-0x8], 0x0: Compare the value at [rbp-0x8] with 0.
5. je 0x555555555154: If the comparison result is equal (zero), jump to the address 0x555555555154.
6. add DWORD PTR [rbp-0x4], 0x1: Add 1 to the value at [rbp-0x4].
7. jmp 0x555555555158: Unconditional jump to the address 0x555555555158
8. sub DWORD PTR [rbp-0x4], 0x1: Subtract 1 from the value at [rbp-0x4].
9. add DWORD PTR [rbp-0x8], 0x1: Add 1 to the value at [rbp-0x8].
10. cmp DWORD PTR [rbp-0x8], 0x2: Compare the value at [rbp-0x8] with 2.
11. jle 0x555555555141: If the comparison result is less than or equal (non-positive), jump to the
address 0x555555555141.

Execution flow analysis

V1=3; and V2=0;

PAGE 6
loop 1 loop 2
=> 0x000055555555515c <+51>: cmp DWORD PTR [rbp-0x8],0x2 => 0x000055555555515c <+51>: cmp DWORD PTR [rbp-0x8],0x2
=> 0x0000555555555160 <+55>: jle 0x555555555141 <main+24> => 0x0000555555555160 <+55>: jle 0x555555555141 <main+24>
V2<2 //jump V2<2 //jump
=> 0x0000555555555141 <+24>: mov DWORD PTR [rbp-0x8],0x0 => 0x0000555555555141 <+24>: mov DWORD PTR [rbp-0x8],0x0
V2=0 //set v2 =0 V2=0 //Rest V2 to 0
=> 0x0000555555555148 <+31>: cmp DWORD PTR [rbp-0x8],0x0 => 0x0000555555555148 <+31>: cmp DWORD PTR [rbp-0x8],0x0
=> 0x000055555555514c <+35>: je 0x555555555154 <main+43> => 0x000055555555514c <+35>: je 0x555555555154 <main+43>
V2=0 //jump V2=0 //jump
=> 0x0000555555555154 <+43>: sub DWORD PTR [rbp-0x4],0x1 => 0x0000555555555154 <+43>: sub DWORD PTR [rbp-0x4],0x1
V1=2 //V1 decrement by 1 V1=1 //V1 decrement by 1
=> 0x0000555555555158 <+47>: add DWORD PTR [rbp-0x8],0x1 => 0x0000555555555158 <+47>: add DWORD PTR [rbp-0x8],0x1
V2=1 //V2 increment by 1 V2=1 //V2 increment by 1

loop 3 loop 4
=> 0x000055555555515c <+51>: cmp DWORD PTR [rbp-0x8],0x2 => 0x000055555555515c <+51>: cmp DWORD PTR [rbp-0x8],0x2
=> 0x0000555555555160 <+55>: jle 0x555555555141 <main+24> => 0x0000555555555160 <+55>: jle 0x555555555141 <main+24>
V2<2 //jump V2<2 //jump
=> 0x0000555555555141 <+24>: mov DWORD PTR [rbp-0x8],0x0 => 0x0000555555555141 <+24>: mov DWORD PTR [rbp-0x8],0x0
V2=0 //Reset V2 to 0 V2=0 //Reset V2 to 0
=> 0x0000555555555148 <+31>: cmp DWORD PTR [rbp-0x8],0x0 =>0x0000555555555148 <+31>: cmp DWORD PTR [rbp-0x8],0x0
=> 0x000055555555514c <+35>: je 0x555555555154 <main+43> => 0x000055555555514c <+35>: je 0x555555555154 <main+43>
V2=0 //jump V2=0 //jump
=> 0x0000555555555154 <+43>: sub DWORD PTR [rbp-0x4],0x1 =>0x0000555555555154 <+43>: sub DWORD PTR [rbp-0x4],0x1
V1=0 //V1 decrement by 1 V1=-1 //V1 decrement by 1
=> 0x0000555555555158 <+47>: add DWORD PTR [rbp-0x8],0x1 =>0x0000555555555158 <+47>: add DWORD PTR [rbp-0x8],0x1
V2=1 //V2 increment by 1 V2=1 // V1 increment by 1

observation
 we observed that there is a loop that changes the value of two numbers (V1 and V2 in our case)
 the loop is recursive /non-stop
 V1 continuously decrease from the initialized value where V2=0
 V2 where rest to zero in each loop
 from Assembly instruction code there is else case if V2 >2 V1 and V2 increase by 1

Step 3: Source code of the program


 The source code was developed based on assembly instruction and observation of continuous
execution.

#include <stdio.h>
int main () {
int V1 = 3;
int V2 = 0;
while (V2 <= 2) {
V2=0;
if (V2 != 0) {
V1++;
} else {
V1--;
}
V2++;
}
return 0;
}

PAGE 7

You might also like