比如咱们刚学了 boot0 这种 freestanding binary object 怎么生成,于是之前的 mmap & call 程序就可以用这个手法,而不是手动从 elf 格式里头扣
payload: payload.c
${CC} -ffreestanding -nostdinc -nostdlib -Wl,--oformat,binary -Wl,--no-dynamic-linker $< -o $@
echo "generate payload" && xxd $@
.PHONY: disasm
objdump -m i386 -b binary -D payload
-ffreestanding
- 独立执行环境-nostdinc
- 不要标准库包含 (不懂)-nostdlib
- 不要标准库 (libc.so crtbegin crt0 这种(好像))-Wl,args
args 是传递给链接器的参数,其中 ,
代替空格--oformat binary
- 输出二进制文件--no-dynamic-linker
- 不要动态链接器 (.interp段内容)于是乎我们只需要这么搞
#include <sys/mman.h>
void *mem = mmap(NULL, 1024 * 1024 * 2, PORT_READ | PORT_EXEC, MAP_ANON, -1, 0);
FILE *f = fopen("payload", "rb");
fread(mem, 64, 1, f);
准备函数原型并且发起调用
int func(int);
printf("call -> %d\n", ((int(*)(int))mem)(42) );
In a freestanding environment, the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.
差不多就是不要求标准库的那种,独立于 c 语言库的一种执行环境。
.set ORIGIN, 0x600
.set LOAD, 0x7c00
.set MAGIC, 0xaa55
.set PRT_OFF, 0x1be # Partition table
.set B0_BASE, 0x1b2
.set B0_OFF, (B0_BASE-0x200)
.intel_syntax noprefix
.globl start
.code16
start: cld
xor ax, ax
mov es, ax
mov ds, ax
mov ss, ax
mov sp, LOAD
mov si, sp
# https://stackoverflow.com/a/36899426
mov di, offset start
mov cx, 0x100
rep
movsw
mov bp, di
mov cl, 0x8
rep
stosw
inc byte ptr -0xe[di]
jmp [main-LOAD+ORIGIN]
main:
mov si, offset message
call putstr
hlt
putstr.1: call putchr
putstr: lodsb
test al, 0x80
jz putstr.1
and al, ~0x80
putchr:
push bx
mov bx, 0x7
mov ah, 0xe
int 0x10
pop bx
ret
message:
.ascii "\nHello, world\r\n;) literal kernel"
crlf:
.ascii "\r"
.byte '\n' | 0x80
.byte 0x80
.org PRT_OFF
partbl:
.fill 0x40, 0x1, 0x0 # Partition table
.word MAGIC # Magic number
.org 0x200
endblock:
OUTPUT_FORMAT("elf32-i386-freebsd")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS {
. = ORG;
.text : { *(.text .text.*) } = 0xcccccccc
.data : { *(.data .data.*) }
_edata = .; PROVIDE (edata = .);
.bss : { *(.bss .bss.*) }
_end = .; PROVIDE (end = .);
/DISCARD/ : { *(.interp) }
}
cc -m32 -march=i386 -nostdinc -nostdlib -ffreestanding -ffunction-section -fdata-section -mno-mmx -mno-sse -mno-avx -mno-avx2 -msoft-float -c boot.S -o boot0.o
ld --eh-frame-hdr -m elf_i386 -T boot.ldscript -N -S --oformat binary --no-resegment boot0.o -o boot0
修了修了修了!
stackoverflow yyds
https://github.com/sinsong/literal/commit/ca2150955adead55e6eb500e6bcf4f4d69d96e81
莉特雅 literal
写代码业余爱好者 amateur coder