Last modified: 2023-09-09
Analyze and get the knowledge of executables.
file ./sample strings ./sample # -i: Ignore case # -A: Print N lines of trailing context # -B: Print N lines of leading context strings ./example | grep -i password -A 10 -B 10 # -B: signature binwalk -B ./sample # Dump hex hexdump ./sample # -C: canonical hex+ASCII display # -n: length hexdump -C -n 64 ./sample # Dump hex hd ./somefile # -n: only length bytes of input (ex. display the first 28 bytes) # -s: skip offset bytes from the beginning (ex. no display the first 568 bytes) hd -n 28 -s 568 example.so # only display the first 64 bytes hd -n 64 example.bin xxd ./sample xxd ./sample | head # Hex editor with GUI ghex ./sample.bin
Relocation Read-Only, which makes the global offset table (GOT) read-only.
- Stack Canaries
Tokens placed after a stack to detect a stack overflow.
Non-Executable. It prevents from shellcode.
Read-Write-Executable. It's vulnerable to shellcode.
Position Independent Executable. It loads the program dependencies into random locations.
# Get information readelf -a ./sample # Change MSB <=> LSB by editing binary number. hexedit ./sample (MSB) 7F 45 4C 46 02 02 01 ... <=> (LSB) 7F 45 4C 46 02 01 01 ...
# -d: disassemble objdump -d example.obj # -M: option objdump -M intel -d example.obj
OLE is a mechanism that allows users to create and edit documents containing items or "objects" created by multiple applications.
It dumps the information of the OLE files.
oledump.py example.doc # -s: stream number to analyze # -d: dump oledump.py -s 8 -d example.doc oledump.py -s 9 -d example.doc
Then decrypt the output using online tools like CyberChef.
Download the Oletools to use it.
Copy the above Visual Basic code, and access to OneCompiler.
Select the programming language "Visual Basic".
Paste the copied code to the editor, then click Run.
To check if a binary is compressed with packer such as UPX, dump the hex and extract text related to the packer as below.
# -B: Print before 20 lines from matched string. # -A: Print after 20 lines from matched string. hd ./sample | grep UPX -B 20 -A 20 xxd ./sample | grep UPX -B 20 -A 20
If found, we can decompress it.
upx -d ./sample
Cutter is a reverse engineering platform powered by Rizin.
We can also use Decompiler Explorer online tool.
- If you find “??” instructions in the analyzer of Ghidra, right-click on it and select “Disassemble”.
- If you find “UD2 (Undefined Instruction)” instruction in the analyzer of Ghidra, replace them with “NOP” by right-clicking and selecting “patch instruction”.
It is used for decompiling .NET files.
AvaloniaILSpy is also available for Linux.
chmod 700 sample ./sample
If the program allow you to input some text, you can try first.
"printf", a function in the C language, is vulnerable to display the internal values from inputs.
# the value of the pointer > %p # the value of the 10th pointer > %10$p
GDB is a GNU debugger which is used for reverse engineering.
Before starting, you need to change the permission for the executable so that the program can be executed.
chmod +x ./executable
Now statt gdb.
Find the interesting function and get the address.
gdb> info function
When you find the interesting function, such as main, strcmp, etc., set the breakpoint at the address.
gdb> break *<address-of-the-function> # e.g. gdb> break *0x0000000000400580
By the way, you can delete them if you want.
gdb> info breakpoints # Delete all breakpoints gdb> delete # Delete the specific breakpoint gdb> delete <the-number-of-the-breakpoint> # e.g. gdb> delete 1 gdb> delete 2
Since you set the breakpoint, the program will stop at the breakpoint.
To observe the information of the current position in the function, run the following command.
gdb> disassemble # for the specific function gdb> disassemble <function>
To proceed step by step.
gdb> stepi # to proceed until the next function gdb> step
To proceed until the next function.
First off, check the address of registers.
gdb> info registers
Then examine values of registers.
To get the value as string,
gdb> x/s <address-of-the-register> # e.g. gdb> x/s 0x7fffffffdeb0 # or you can specify register names directly gdb> x/s $rax gdb> x/s $rbx gdb> x/s $rcx gdb> x/s $rdx
To get the value as decimal,
gdb> x/d <address-of-the-register> # e.g. gdb> x/d 0x7fffffffdeb0 # or you can specify register names directly gdb> x/d $rax gdb> x/d $rbx gdb> x/d $rcx gdb> x/d $rdx
gdb> set $eip = <address> # e.g. gdb> set $eip = 0x565561a9
gdb> jump *0x0040096a