commit 5ef5abcd0c2983d10ea677a551381c7e12ab30da
parent 44205c07bf99aac643e5cc740af808a60a59ce8f
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date: Tue, 7 Jul 2026 14:46:55 +0200
Header separation
Diffstat:
7 files changed, 121 insertions(+), 100 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -4,11 +4,15 @@ include ../Makefile
.PHONY: clean
.DEFAULT_GOAL := stabbish
-stabbish: main.o busybox/busybox.inc.o
+stabbish: main.o payload.o magic.o utils.o busybox/busybox.inc.o
$(info $() LD $@)
@$(CC) $(CFLAGS) $^ -o $@
-main.o: main.c busybox/busybox.inc.h magic.h payload.h utils.h
+main.o: main.c busybox/busybox.inc.h
+ $(info $() CC $@)
+ @$(CC) $(CFLAGS) -c $< -o $@
+
+%.o: %.c %.h
$(info $() CC $@)
@$(CC) $(CFLAGS) -c $< -o $@
@@ -28,4 +32,4 @@ busybox/busybox.inc.o: busybox/busybox.inc.s $(BUSYBOX)
clean:
$(info $() CLEAN $(shell basename $(shell pwd)))
- @rm -rf main.o stabbish busybox
+ @rm -rf *.o stabbish busybox
diff --git a/src/magic.c b/src/magic.c
@@ -0,0 +1,26 @@
+#include "magic.h"
+
+#include <unistd.h>
+
+const struct magic MAGICS[] = {
+ {"xzcat", 6, {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}},
+ {"zcat", 2, {0x1F, 0x8B}},
+ {"bzcat", 3, {0x42, 0x5A, 0x68}},
+};
+
+struct magic magic_detect(fd file) {
+ static struct magic try_return = {NULL, 0, {0x00}};
+
+ unsigned char header[10];
+
+ size_t trys(header_len, read(file, &header, 10));
+
+ for (int i = 0; i < tsizeof(MAGICS); i++) {
+ if (header_len > MAGICS[i].length &&
+ memcmp(header, MAGICS[i].byte, MAGICS[i].length) == 0) {
+ return MAGICS[i];
+ }
+ }
+
+ return try_return;
+}
diff --git a/src/magic.h b/src/magic.h
@@ -2,7 +2,6 @@
#include <stdlib.h>
#include "utils.h"
-#include <unistd.h>
struct magic {
const char *tool;
@@ -10,25 +9,6 @@ struct magic {
unsigned char byte[16];
};
-const struct magic MAGICS[] = {
- {"xzcat", 6, {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}},
- {"zcat", 2, {0x1F, 0x8B}},
- {"bzcat", 3, {0x42, 0x5A, 0x68}},
-};
-
-static struct magic magic_detect(fd file) {
- static struct magic try_return = {NULL, 0, {0x00}};
-
- unsigned char header[10];
-
- size_t trys(header_len, read(file, &header, 10));
-
- for (int i = 0; i < tsizeof(MAGICS); i++) {
- if (header_len > MAGICS[i].length &&
- memcmp(header, MAGICS[i].byte, MAGICS[i].length) == 0) {
- return MAGICS[i];
- }
- }
+struct magic magic_detect(fd file);
- return try_return;
-}
+extern const struct magic MAGICS[];
diff --git a/src/payload.c b/src/payload.c
@@ -0,0 +1,35 @@
+#define _GNU_SOURCE
+
+#include <elf.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/sendfile.h>
+#include <unistd.h>
+
+#include "payload.h"
+
+fd elf_payload(const char *path) {
+ static fd try_return = -1;
+
+ fd trys(in, open(path, O_RDONLY));
+
+ ElfW(Ehdr) header;
+ try(read(in, &header, sizeof(header)));
+
+ size_t trys(size, lseek(in, 0, SEEK_END));
+ off_t offset = header.e_shoff + (header.e_shentsize * header.e_shnum);
+ size_t payload_size = size - offset;
+
+ if (payload_size == 0) {
+ close(in);
+ return ENOPAYLOAD;
+ }
+
+ int trys(payload, memfd_create("payload", 0));
+ try(sendfile(payload, in, &offset, payload_size));
+ try(lseek(payload, SEEK_SET, 0));
+
+ close(in);
+
+ return payload;
+}
diff --git a/src/payload.h b/src/payload.h
@@ -1,9 +1,4 @@
#pragma once
-#include <elf.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/sendfile.h>
-#include <unistd.h>
#include "utils.h"
@@ -15,28 +10,4 @@
#define ENOPAYLOAD -2
-static fd elf_payload(const char *path) {
- static fd try_return = -1;
-
- fd trys(in, open(path, O_RDONLY));
-
- ElfW(Ehdr) header;
- try(read(in, &header, sizeof(header)));
-
- size_t trys(size, lseek(in, 0, SEEK_END));
- off_t offset = header.e_shoff + (header.e_shentsize * header.e_shnum);
- size_t payload_size = size - offset;
-
- if (payload_size == 0) {
- close(in);
- return ENOPAYLOAD;
- }
-
- int trys(payload, memfd_create("payload", 0));
- try(sendfile(payload, in, &offset, payload_size));
- try(lseek(payload, SEEK_SET, 0));
-
- close(in);
-
- return payload;
-}
+fd elf_payload(string path);
diff --git a/src/utils.c b/src/utils.c
@@ -0,0 +1,47 @@
+#define _GNU_SOURCE
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+char *pasprintf(string __restrict str, ...) {
+ va_list ap;
+ va_start(ap, str);
+
+ char *out;
+ if (vasprintf(&out, str, ap) == -1)
+ out = NULL;
+
+ va_end(ap);
+ return out;
+}
+
+int memexecv(fd exe, char **argv, char **envp, struct stdstream std) {
+ int try_return = -1;
+ pid_t trys(pid, fork());
+
+ if (pid) {
+ int wstatus;
+ waitpid(pid, &wstatus, 0);
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) {
+ fprintf(stderr, "Child process exited with code %i\n",
+ WEXITSTATUS(wstatus));
+ return -1;
+ }
+ } else {
+ if (std.in >= 0)
+ dup2(std.in, 0);
+ if (std.out >= 0)
+ dup2(std.out, 1);
+ if (std.err >= 0)
+ dup2(std.err, 2);
+
+ exit(fexecve(exe, argv, envp));
+ }
+
+ return 0;
+}
diff --git a/src/utils.h b/src/utils.h
@@ -1,18 +1,11 @@
#pragma once
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
#include <errno.h>
-#include <stdarg.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
typedef int fd;
+typedef const char *string;
#define shift(n) \
if (n < argc) { \
@@ -38,46 +31,11 @@ typedef int fd;
#define try(cmd) try2(cmd, != -1)
-static char *pasprintf(const char *__restrict str, ...) {
- va_list ap;
- va_start(ap, str);
-
- char *out;
- if (vasprintf(&out, str, ap) == -1)
- out = NULL;
-
- va_end(ap);
- return out;
-}
-
struct stdstream {
fd in;
fd out;
fd err;
};
-static int memexecv(fd exe, char **argv, char **envp, struct stdstream std) {
- int try_return = -1;
- pid_t trys(pid, fork());
-
- if (pid) {
- int wstatus;
- waitpid(pid, &wstatus, 0);
- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) {
- fprintf(stderr, "Child process exited with code %i\n",
- WEXITSTATUS(wstatus));
- return -1;
- }
- } else {
- if (std.in >= 0)
- dup2(std.in, 0);
- if (std.out >= 0)
- dup2(std.out, 1);
- if (std.err >= 0)
- dup2(std.err, 2);
-
- exit(fexecve(exe, argv, envp));
- }
-
- return 0;
-}
+char *pasprintf(string __restrict str, ...);
+int memexecv(fd exe, char **argv, char **envp, struct stdstream std);