mirror of https://github.com/flysand7/ciabatta.git
Write proper plt relocations in entry assembly, fix stack checking not working correctly
This commit is contained in:
parent
c8df2f9d42
commit
c72164fff0
15
build.sh
15
build.sh
|
@ -3,17 +3,12 @@
|
||||||
[ ! -d "lib" ] && mkdir "lib"
|
[ ! -d "lib" ] && mkdir "lib"
|
||||||
[ ! -d "bin" ] && mkdir "bin"
|
[ ! -d "bin" ] && mkdir "bin"
|
||||||
|
|
||||||
|
[ "$1" != "-shared" ] && echo "static"
|
||||||
|
|
||||||
nasm -f elf64 "src/linux/crt_entry.asm" -o "bin/crt_entry.o"
|
nasm -f elf64 "src/linux/crt_entry.asm" -o "bin/crt_entry.o"
|
||||||
clang -fPIC -nostdlib -I "include" -g "src/linux/crt_ctors.c" -c -o "bin/crt_ctors.o"
|
clang -fPIC -nostdlib -I "include" -g "src/linux/crt_ctors.c" -c -o "bin/crt_ctors.o"
|
||||||
clang -fPIC -nostdlib -I "include" -g "src/ciabatta.c" -c -o "bin/ciabatta.o"
|
clang -fPIC -nostdlib -I "include" -g "src/ciabatta.c" -c -o "bin/ciabatta.o"
|
||||||
|
|
||||||
rm "$LIB_FILE" 2> /dev/null
|
# Create a test executable
|
||||||
|
clang -pie -nostdlib -Iinclude \
|
||||||
if [ "$1" != "-shared" ]; then
|
tests/empty.c bin/ciabatta.o bin/crt_ctors.o bin/crt_entry.o
|
||||||
[ -f "lib/ciabatta.a" ] && rm "lib/ciabatta.a"
|
|
||||||
llvm-ar -q "lib/ciabatta.a" "bin/crt_ctors.o" "bin/crt_entry.o" "bin/ciabatta.o"
|
|
||||||
else
|
|
||||||
clang -fPIC -nostdlib -shared -o "lib/ciabatta.so" "bin/ciabatta.o"
|
|
||||||
cp "bin/crt_ctors.o" "lib/ctors.o"
|
|
||||||
cp "bin/crt_entry.o" "lib/entry.o"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -2,20 +2,12 @@
|
||||||
bits 64
|
bits 64
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
default rel
|
||||||
global _start
|
global _start
|
||||||
; global _init
|
extern __libc_global_fini
|
||||||
; global _fini
|
extern __libc_global_init
|
||||||
extern __libc_global_fini
|
extern __libc_start_main
|
||||||
extern __libc_global_init
|
extern main
|
||||||
extern __libc_start_main
|
|
||||||
extern main
|
|
||||||
|
|
||||||
; _init:
|
|
||||||
; push ebp
|
|
||||||
; mov ebp, esp
|
|
||||||
; _fini:
|
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
xor ebp, ebp
|
xor ebp, ebp
|
||||||
;; Save rtld_fini address to r9
|
;; Save rtld_fini address to r9
|
||||||
|
@ -28,20 +20,16 @@ _start:
|
||||||
push rax
|
push rax
|
||||||
push rsp
|
push rsp
|
||||||
;; Load fini and init initializers as function parameters
|
;; Load fini and init initializers as function parameters
|
||||||
%ifdef CIA_SHARED
|
push rbx
|
||||||
mov rcx, __libc_global_init wrt ..got
|
lea rbx, [__libc_global_init wrt ..plt]
|
||||||
mov r8, __libc_global_fini wrt ..got
|
mov rcx, rbx
|
||||||
%else
|
lea rbx, [__libc_global_fini wrt ..plt]
|
||||||
mov rcx, __libc_global_init
|
mov r8, rbx
|
||||||
mov r8, __libc_global_fini
|
lea rbx, [main wrt ..plt]
|
||||||
%endif
|
mov rdi, rbx
|
||||||
mov rdi, main
|
pop rbx
|
||||||
;; Call start main
|
;; Call start main
|
||||||
%ifdef CIA_SHARED
|
|
||||||
call __libc_start_main wrt ..plt
|
call __libc_start_main wrt ..plt
|
||||||
%else
|
|
||||||
call __libc_start_main
|
|
||||||
%endif
|
|
||||||
;; No idea why halt it, I guess that's a funny
|
;; No idea why halt it, I guess that's a funny
|
||||||
;; way to crash your application if the function we called
|
;; way to crash your application if the function we called
|
||||||
;; returns instead of calling the exit syscall
|
;; returns instead of calling the exit syscall
|
||||||
|
|
|
@ -10,15 +10,15 @@ void __libc_start_main(
|
||||||
int argc, char **argv,
|
int argc, char **argv,
|
||||||
int (*init)(int, char**, char**),
|
int (*init)(int, char**, char**),
|
||||||
void (*fini)(void),
|
void (*fini)(void),
|
||||||
void (*runtime_ld_fini)(void),
|
void (*dl_fini)(void),
|
||||||
void *stack_end
|
void *stack_end
|
||||||
) {
|
) {
|
||||||
|
// Get the envp
|
||||||
char **envp = argv + (argc + 1);
|
char **envp = argv + (argc + 1);
|
||||||
init(argc, argv, envp);
|
init(argc, argv, envp);
|
||||||
main(argc, argv, envp);
|
main(argc, argv, envp);
|
||||||
fini();
|
fini();
|
||||||
if(runtime_ld_fini != NULL) {
|
// glibc bug
|
||||||
runtime_ld_fini();
|
dl_fini();
|
||||||
}
|
|
||||||
syscall_exit(0);
|
syscall_exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,35 @@
|
||||||
|
|
||||||
#if os_is_linux()
|
#if os_is_linux()
|
||||||
|
|
||||||
|
// Standard handles file descriptors
|
||||||
#define STDIN_FILENO 0
|
#define STDIN_FILENO 0
|
||||||
#define STDOUT_FILENO 1
|
#define STDOUT_FILENO 1
|
||||||
#define STDERR_FILENO 2
|
#define STDERR_FILENO 2
|
||||||
|
|
||||||
|
// arch_prctl syscall codes
|
||||||
|
#define ARCH_SET_GS 0x1001
|
||||||
|
#define ARCH_SET_FS 0x1002
|
||||||
|
#define ARCH_GET_FS 0x1003
|
||||||
|
#define ARCH_GET_GS 0x1004
|
||||||
|
#define ARCH_GET_CPUID 0x1011
|
||||||
|
#define ARCH_SET_CPUID 0x1012
|
||||||
|
|
||||||
|
// open syscall modes
|
||||||
|
#define O_ACCMODE 0003
|
||||||
|
#define O_RDONLY 00
|
||||||
|
#define O_WRONLY 01
|
||||||
|
#define O_RDWR 02
|
||||||
|
#define O_CREAT 0100 /* not fcntl */
|
||||||
|
#define O_EXCL 0200 /* not fcntl */
|
||||||
|
#define O_NOCTTY 0400 /* not fcntl */
|
||||||
|
#define O_TRUNC 01000 /* not fcntl */
|
||||||
|
#define O_APPEND 02000
|
||||||
|
#define O_NONBLOCK 04000
|
||||||
|
#define O_NDELAY O_NONBLOCK
|
||||||
|
#define O_SYNC 010000
|
||||||
|
#define O_FSYNC O_SYNC
|
||||||
|
#define O_ASYNC 020000
|
||||||
|
|
||||||
#define SYS_read 0
|
#define SYS_read 0
|
||||||
#define SYS_write 1
|
#define SYS_write 1
|
||||||
#define SYS_open 2
|
#define SYS_open 2
|
||||||
|
@ -67,6 +92,8 @@
|
||||||
#define SYS_execve 59
|
#define SYS_execve 59
|
||||||
#define SYS_exit 60
|
#define SYS_exit 60
|
||||||
|
|
||||||
|
#define SYS_arch_prctl 158
|
||||||
|
|
||||||
// Syscall stubs
|
// Syscall stubs
|
||||||
|
|
||||||
static __inline i64 __syscall0(i64 n) {
|
static __inline i64 __syscall0(i64 n) {
|
||||||
|
@ -132,10 +159,26 @@ static inline i64 syscall_write(u32 fd, char const *buf, u64 count) {
|
||||||
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
|
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline i64 syscall_open(char const *filename, int flags, int mode) {
|
||||||
|
return __syscall3(SYS_open, (i64)filename, (i64)flags, (i64)mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline i64 syscall_close(u32 fd) {
|
||||||
|
return __syscall1(SYS_close, fd);
|
||||||
|
}
|
||||||
|
|
||||||
static inline i64 syscall_exit(int code) {
|
static inline i64 syscall_exit(int code) {
|
||||||
return __syscall1(SYS_exit, (i64)code);
|
return __syscall1(SYS_exit, (i64)code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline i64 syscall_arch_prctl_set(int code, u64 value) {
|
||||||
|
return __syscall2(SYS_arch_prctl, code, (i64)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline i64 syscall_arch_prctl_get(int code, u64 *value) {
|
||||||
|
return __syscall2(SYS_arch_prctl, code, (i64)value);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "syscall.h should only be included in LINUX code"
|
#error "syscall.h should only be included in LINUX code"
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char string[] = "hi";
|
||||||
|
printf("%s\n", string);
|
||||||
|
return 0;
|
||||||
|
}
|
8
test.sh
8
test.sh
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ "$1" != "-shared" ]; then
|
|
||||||
clang -static -nostdlib tests/empty.c lib/ciabatta.a -Iinclude
|
|
||||||
else
|
|
||||||
clang -g -fno-stack-protector -fPIE tests/empty.c -c -o tests/empty.o
|
|
||||||
ld -no-pie -nostdlib lib/entry.o tests/empty.o lib/ciabatta.so lib/ctors.o -Iinclude
|
|
||||||
fi
|
|
|
@ -15,8 +15,8 @@ static inline i64 syscall_write(u32 fd, char const *buf, u64 count) {
|
||||||
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
|
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
|
||||||
}
|
}
|
||||||
|
|
||||||
char string[] = "Hello, world!\n";
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
||||||
|
char string[] = "Hello, world!\n";
|
||||||
syscall_write(STDOUT_FILENO, string, sizeof string);
|
syscall_write(STDOUT_FILENO, string, sizeof string);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue