-
https://man7.org/linux/man-pages/man2/syscall.2.html
- register conventions
- x64: rdi rsi rdx r10 r8 r9
- register conventions
-
https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic.html
__libc_start_main()
- GNU Hurd / glibc / How libc startup in a process works
CALL _get_initial_narrow_environment
MOV EDI,EAX
CALL __p___argv
MOV ESI,dword ptr [EAX]
CALL __p___argc
PUSH EDI
PUSH ESI
PUSH dword ptr [EAX]
CALL FUN_00402100
-
executable
- contains: 1 or more segments
-
segment
- describes: execution view (loadable)
- contains: 0 or more sections
-
section
- describes: linking view (instructions, data, symbols...)
-
./files/ELF101.png
-
https://fasterthanli.me/series/making-our-own-executable-packer/part-1
# Imports
objdump --dynamic-syms
# Externally visible / Exports
# ELF format
# Given: Symbol table '.dynsym'
nm --demangle --dynamic --defined-only --extern-only _
readelf -Ws _ | awk '{ if (!match("0000000000000000", $2)) print }'
# PE Format
winedump -j export foo.dll
mingw-objdump -p foo.dll
# sections + binary position
objdump -h
readelf --sections
~/opt/pax-utils/dumpelf
# dump a section
objcopy --dump-section .text=output.bin input.o
Sections | Lifecycle |
---|---|
argc,argv,envp |
|
stack | grows to bottom (lower addresses) |
heap | grows to top (higher addresses) |
uninitialized data aka. .bss |
zeroed by exec |
initialized data aka. .data |
read by exec |
initialized read-only data aka. .rodata |
read by exec |
global offset table aka. .got |
updated by _dl_runtime_resolve , replacing pointer to stub in .plt |
executable code aka. .text |
read by exec |
procedure linkage table aka. .plt |
-
.text
: executable code; RX (=AX) segment; only loaded once, as contents will not change- CONTENTS, ALLOC, LOAD, READONLY, CODE
- finding address range
-
.rela.text
: list of relocations against.text
-
.data
: initialised data; RW (=WA) segment -
.rodata
: initialised read-only data; R (=A) segment -
.bss
: uninitialized data; RW segment -
.plt
: PLT (Procedure Linkage Table) (IAT equivalent) -
.got
: GOT (Global Offset Table), used to access dynamically linked global variables, created during link time, may be populated during runtime -
.got.plt
: used to access dynamically linked functions -
.symtab
: global symbol table -
.dynamic
: Holds all needed information for dynamic linking -
.dynsym
: symbol tables dedicated to dynamically linked symbols -
.strtab
: string table of.symtab
section -
.dynstr
: string table of.dynsym
section -
.interp
: RTLD embedded string -
.rel.dyn
: global variable relocation table, used for ASLR -
.rel.plt
: function relocation table, used for ASLR -
Technovelty - PLT and GOT - the key to code sharing and dynamic libraries
-
c - Why this piece of code can get environment variable address? - Stack Overflow
https://www.sigflag.at/blog/2020/writeup-plaidctf2020-golfso/
https://man7.org/linux/man-pages/man2/syscall.2.html
- frame
- contains: ebp; local vars; args; return address = eip saved by
call
- contains: ebp; local vars; args; return address = eip saved by
- X86 Emulator Plugin
- Every time an instruction is fetched, the plugin tells IDA to turn that location into code
- ~/Downloads/BH_Eagle_ida_pro.pdf
https://stackoverflow.com/questions/27581279/make-text-segment-writable-elf
https://stackoverflow.com/questions/54134394/segmentation-fault-with-a-variable-in-section-data
https://stackoverflow.com/questions/4812869/how-to-write-self-modifying-code-in-x86-assembly
https://0x00sec.org/t/polycrypt-experiments-on-self-modifying-programs/857
https://guyonbits.com/from-rodata-to-rwdata-introduction-to-memory-mapping-and-ld-scripts/
gdb p (int)mprotect($rax - $rax%4096, 4096, 7)
without libc
gdb # 10: __NR_mprotect set $rax = 10 set $rdi = addr set $rsi = len set $rdx = 3 jump syscall
? push/pop registers
https://stackoverflow.com/questions/25740781/change-page-permission-using-gdb
https://red0xff.github.io/writeups/volgactf_fhash/#6acb76aa304fcff925cebfc5ac2534de
; function init ~= `enter` instruction
push rbp
mov rbp,rsp
push rbx
; stack space for locals
sub rsp,0x18
; store argv[1]
mov rsi,qword [rsi + 0x8]
; [...]
; return value of next call
mov eax,0x0
; arguments of next call
mov rdi,0x1
call fun_0123
; mem ptr can be stored as extra local var
LEA RAX,[DAT_00100973]
MOV qword ptr [RBP + local_10],RAX
; ...added with var for addressing at index
MOV EAX,dword ptr [RBP + local_18]
MOVSXD RDX,EAX
MOV RAX,qword ptr [RBP + local_10]
ADD RAX,RDX
; [...]
; release stack space
add rsp,0x18
; function exit ~= `leave` instruction
pop rbx
pop rsp
ret
Frame | $rbp Offset | Value | Address |
---|---|---|---|
+ | argc,argv,envp |
[...] | |
1 | + | parameters | [bgn]0x7fffffffffb0 |
1 | + | $rip |
[bgn]0x7fffffffffa8 |
1 | + | $rbp |
[end]0x7fffffffffa0 |
1 | + | [alignment] | [end]0x7fffffffff94 |
1 | + | locals | [end]0x7fffffffff30 |
2 | + | parameters | [...] |
2 | + | $rip |
[...] |
2 | 0 | $rbp |
[...] |
2 | - | [alignment] | [...] |
2 | - | locals | [...] |
2 | - | $rsp |
[...] |
$rbp
aka. frame pointer$rip
aka. return address
ah
, - PRESERVES 0xffff00ff bits ofeax
, equivalent forrax
al
,ax
- PRESERVES {8,16} high bits ofeax
, equivalent forrax
eax
- ZEROES 32 high bits ofrax
gcc -no-pie -nostdlib foo.s -o foo
# || 32 bits
gcc -m32 -no-pie -nostdlib foo.s -o foo
# || Using Intel syntax
nasm -f elf -o foo.o foo.asm
ld -m elf_i386 -o foo foo.o
# || Using AT&T syntax
as -o foo.o foo.asm
ld -o foo foo.o
http://asm.sourceforge.net/intro/hello.html https://cs.lmu.edu/~ray/notes/gasexamples/ https://stackoverflow.com/questions/36861903/assembling-32-bit-binaries-on-a-64-bit-system-gnu-toolchain
https://stackoverflow.com/questions/46756320/change-a-call-address-in-memory
objdump -d _.so | grep func
nm -A _so | grep func
dumpbin /exports _.dll | find "func"
# || CFF Explorer
c++filt -n _ZdlPvm
readelf -Ws _.so
objdump -TC _.so
nm -gC _.so
# From raw data
# Reference: https://www.synacktiv.com/posts/challenges/sharkyctf-ezdump-writeups-linux-forensics-introduction.html
objdump -b binary -m i386:x64-32:intel -D shellcode.bin
ida -m 0x100 -b 16 foo.com
# multiarch
sudo apt install \
binutils-aarch64-linux-gnu \
binutils-mips-linux-gnu \
binutils-powerpc-linux-gnu \
binutils-arm-linux-gnueabi \
qemu-user \
qemu-user-static
# arm
sudo apt install \
qemu-system-arm \
qemu-arm -L /usr/arm-linux-gnueabihf/ crackme
https://github.com/OAlienO/CTF/tree/master/2018/HITCON-CTF/Baldis-RE-Basics https://padraignix.github.io/reverse-engineering/2020/05/18/nsec2020-crackme/
sudo apt install \
gcc-arm-linux-gnueabi \
gcc-arm-linux-gnueabihf \
binutils-arm-linux-gnueabi \
libc6-armel-cross \
libc6-dev-armel-cross
arm-linux-gnueabi-gcc ~/code/wip/hello.c -o hello_arm_static -static
https://www.acmesystems.it/arm9_toolchain
qemu-arm -g 18080 _
gdb-multiarch _
# set arch mips
# set endian big
# target remote localhost:18080
https://padraignix.github.io/reverse-engineering/2020/05/18/nsec2020-crackme/
qemu-system-x86_64 -s -S -m 512 -fda winxp.img
https://github.com/VoidHack/write-ups/tree/master/Square%20CTF%202017/reverse/floppy
- Toolchains.net - Toolchain resources
- ggx - How To Retarget the GNU Toolchain in 21 Patches
- crosstool-NG - versatile (cross) toolchain generator
- GitHub - tpoechtrager/osxcross: Mac OS X cross toolchain for Linux, FreeBSD, OpenBSD and Android (Termux)
https://in4k.github.io/wiki/lsc-wiki-rtld
https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld https://access.redhat.com/blogs/766093/posts/1975793
-
far return (
retf
)- next address pushed before call
cs=0x23
: x86 modecs=0x33
: x86-64 mode
-
https://blukat29.github.io/2016/10/hitcon-quals-2016-mixerbox/
uint32_t read_le_int32(unsigned char *b) {
return uint32_t(b[0]) |
(uint32_t(b[1]) << 8) |
(uint32_t(b[2]) << 16) |
(uint32_t(b[3]) << 24);
}
- virtual address (VA) = original virtual address of object loaded into memory
- relative virtual address (RVA) = VA - ImageBase
- e.g. 0x1000 = 0x401000 - 0x400000
- file offset of entry point = (.OptionalHeaders[EntryPointAddress] – .SectionHeaders[VirtualAddress[.text]]) + .SectionHeaders[PointerToRawData[.text]]
- ImageBase = ld script variable
__executable_start
= 0x400000 - SectionHeaders == ProgramHeaders
- ! segment starts at next page-aligned virtual address due to mmap behaviour