:::success
# **OT Lab1 - Understanding Assembly**
## **Gideon Emmanuel Oki**
:::
## Task 1 - Preparation.
:::info
a. You can use any debugger/disassembler as long as it supports the given task architecture (32bit or 64bit)
b. Try to stay away from decompilers, as this will help you to better understand the nature of your task based on assembly only, remember in real-world tasks you will have to deal with much larger binaries.
c. IMPORTANT: Please check what each binary does before running it (don’t trust us 😈)
d. Check some writeups about some CTF to see what you should/shouldn’t include in your report
e. Try to do the lab in a Linux VM, as you might need to disable ASLR
:::
For this, I opted for **gdb** (GNU Debugger).
I also opted to do this lab on a Virtual Machine with Ubuntu 22.10.
:::warning

VM and OS information.
---

Installed GNU Debugger version.
:::
To install gdb if it isn't present the command `sudo apt install gdb` can be used.
## Task 2 - Theory.
:::info
a. What is `ASLR`, and why do we need it?
:::
`ASLR` stands for **Address Space Layout Randomization** and it is a security technique used by our modern operating systems to protect against some common memory related vulnerabilities. ASLR adds an extra layer of security to an operating system making it harder for a threat actor to locate and exploit vulnerabilities in memory. As a crucial security mechanism it protects systems against attacks like buffer overflow and code injection attack.
:::info
b. How can the debugger insert a breakpoint in the debugged binary/application?
:::
For a debugger to insert a breakpoint in the binary or application, the debugger needs to modify the binary code which is done by replacing the original instruction at the breakpoint location and with this in place, it would trigger a breakpoint interupt when executed. This will cause the debugger to take control of the program. Once this happens, the developer can inspect the program's state, modify the program state and can stop execution at other points in the program.
## Task 3 - Reversing.
:::info
a. Disable ASLR in your Linux VM using the following command:
`sudo sysctl -w kernel.randomize_va_space=0`
:::
First I started off by checking the status of the ASLR.
:::warning

checking ASLR status and then disabling it as requested.
:::
:::info
b. Load the binaries from the **Task 3** folder into a disassembler/debugger.
:::
For this I downloaded the folder and got to work. On close inspection I realized I had 3 files within the folder namely sample32, sample64 and sample64-2.
:::warning

files to be loaded into the disassembler.
:::
I started with sample32.
First I needed to know some more about this file as such I used the info command in gdb to get more details about the file.
:::warning

loading sample32 and getting more information about the file.
---

checking the two functions in the binary.
---

more information about the file.
:::
Then I moved on to the sample64 file.
:::warning

---

checking the fuctions within sample64.
---

checking more information including the architecture of the file.
:::
Then finally I checked sample64-2.
This file was somewhat confusing at first. I then tried to get as much information about the file.
:::warning

some info about sample64-2. Standout out is the fact that it doesn't display funcions in the file.
---


getting some more details about the file.
:::
The sample64-2 file once I ran the disassemble main command i could see sample_function in the output as such I could simply just go ahead to check the details of the second function.
:::info
c. Do the function prologue and epilogue differ in 32bit and 64bit?
:::
Yes, the fuction prologue and epilogue differ in 32bits and 64bits. The variation could be due to calling convention and register usage between the two architectures under consideration. The use of stack pointers and frame pointers could also lead to the variation as well.
:::warning

prologue and epilogue for 32bit main function.
---

prologue and epilogue for 64bit main function.
:::
:::info
d. Do function calls differ in 32bit and 64bit? What about argument passing?
:::
Yes, **Function Calls** differ between 32bit and 64bit majorly due to the difference in the calling convention between the two architectures. For **Arguement Passing**, the same can be said for instance the way they handle their stack alignment which could inturn affect the way the stack is managed.
The differences between Function Calls and Argument Passing is an important reason why a code compiled for one architecture may not be compartible with the other without some modification or recompilation.
:::info
e. What does the command `ldd` do? “ `ldd BINARY-NAME` ”.
:::
This command prints the shared library dependencies of an executable or shared library file.
This means when I type `ldd abcde`, this would display the shared libraries that `abcde` depends on.
`ldd` stands for **List Dynamic Dependencies**. `sudo apt install gcc-multilib -y` was used to install some important cross-compiling libraries.
:::warning

output of `ldd` for the binaries.
:::
:::info
f. Why in the “sample64-2“ binary, the value of i didn’t change even if our input was very long?
:::
On close inspection of the assembly code and its possible C code equivalent. This is what I can deduce:
a. It prints a message to the console, which includes the address of a local variable.
b. It reads user input from the console into a buffer.
c. It prints the user input back to the console
**`i`** would probably have a maximum value and would ignore inputs beyond certain length.
## Task 4 - Reversing.
:::info
a. You will have multiple binaries in the Task 4 folder, Try to reverse them by recreating them using any programming language of your choice (C is preferred)
:::
For this, I approached it one bin file at a time.
**For bin1:**
:::warning

disassembled main function in bin1.
:::
```C=
#include <stdio.h>
#include <time.h>
int main() {
time_t rawtime;
struct tm *timeinfo;
rawtime = time(NULL);
timeinfo = localtime(&rawtime);
printf("Current date and time: %04d-%02d-%02d %02d:%02d:%02d\n",
timeinfo->tm_year + 1900,
timeinfo->tm_mon + 1,
timeinfo->tm_mday,
timeinfo->tm_hour,
timeinfo->tm_min,
timeinfo->tm_sec);
return 0;
}
```
bin1 C code.
**For bin2:**
:::warning

disassembled main function for bin2.
:::
```C=
#include <stdio.h>
int main() {
int arr[20];
int i;
for (i = 0; i < 20; i++) {
arr[i] = i * 2;
}
for (i = 0; i < 20; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
```
bin2 C code.
For bin3.
:::warning

disassembled main function for bin3.
:::
```C=
#include <stdio.h>
int main() {
int arr[20];
int i;
for (i = 0; i < 20; i++) {
arr[i] = i * 3;
}
for (i = 0; i < 20; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
```
C code of bin3.
**For bin4.**
:::warning

disassembled main function for bin4.
:::
```C=
#include <stdio.h>
int main() {
int number;
printf("Enter a number: ");
scanf("%d", &number);
if (number % 2 == 0) {
printf("The number %d is even.\n", number);
} else {
printf("The number %d is odd.\n", number);
}
return 0;
}
```
**For bin5.**
:::warning

disassembly process for bin5.
:::
```C=
#include <stdio.h>
long factorial(int n) {
long result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
int main() {
int input;
printf("Enter a non-negative integer: ");
scanf("%d", &input);
if (input < 0) {
printf("Invalid input, only non-negative integers are allowed.\n");
return 0;
}
long fact = factorial(input);
printf("Factorial of %d is %ld\n", input, fact);
return 0;
}
```
C code of bin5.
**For bin6.**
:::warning

disassembly process for bin6.
:::
```C=
#include <stdio.h>
void main() {
int num1, num2, sum;
printf("Enter two integers: ");
scanf("%d%d", &num1, &num2);
sum = num1 + num2;
printf("%d + %d = %d\n", num1, num2, sum);
}
```
C code of bin6.
:::success
**REFERENCES**
- https://gist.github.com/jarun/ea47cc31f1b482d5586138472139d090
:::