From 7cfa935df23105fec704e7311ebdba410798c3d5 Mon Sep 17 00:00:00 2001 From: Al Stone Date: Fri, 30 Nov 2012 16:08:01 -0700 Subject: first commit of the patch tool Signed-off-by: Al Stone --- Makefile | 21 +++++++++++ paxf.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 Makefile create mode 100644 paxf.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0ed0c94 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +# +# patch a binary .axf file with a new set of kernel parameters +# + +CC ?= gcc +CFLAGS ?= -g + +OBJ = paxf.o + + +all: paxf + +paxf: paxf.o + $(CC) $(CFLAGS) -o paxf $(OBJ) + +clean: + rm -f paxf $(OBJ) + +.c.o: + $(CC) $(CFLAGS) -c $< + diff --git a/paxf.c b/paxf.c new file mode 100644 index 0000000..3e167e6 --- /dev/null +++ b/paxf.c @@ -0,0 +1,129 @@ +/********************************************************************** + * Given a linux-system.axf file built in a certain way, replace + * the kernel parameters used with whatever I'd like to put in + * there instead. + * + * This is a quick and dirty hack; if it works for *anything* other + * than this, I think I'll laugh hysterically. + * + * + * Copyright (c) 2012, Al Stone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 (only) of the GNU General + * Public License as published by the Free Software Foundation. + * + **********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARG_OFFSET 0x4000e4 +#define AXF_FILE "./linux-system-useless.axf" +#define BUFFER_LENGTH 400 + +void +usage() { + fprintf(stderr, "usage: paxf \n\n"); + fprintf(stderr, "where:\n"); + fprintf(stderr, + " => name to use for patched axf file\n"); + fprintf(stderr, + " => the kernel parameters wanted as a\n"); + fprintf(stderr, + " single string (assume there are NO\n"); + fprintf(stderr, + " parameters provided by default)\n"); +} + +int +main(int argv, char *argc[]) { + + int infd, outfd; + char *fname; + char *kargs; + + /* crude argument handling */ + if (argv < 3) { + usage(); + exit(1); + } + fname = argc[1]; + kargs = argc[2]; + + outfd = open(fname, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (! (outfd > 0)) { + fprintf(stderr, "? cannot open %s as output\n", fname); + exit(1); + } + + if (strlen(kargs) > BUFFER_LENGTH) { + fprintf(stderr, "? not enough space for the kernel args (%d)\n", + strlen(kargs)); + exit(1); + } + + /* + * map in the entire axf file to use as a template, then copy + * it all to the new location, except for the bits we need to + * change + */ + unsigned char *axf = NULL; + struct stat stat_buf; + off_t axf_size; + int count; + unsigned char *buf; + + if (stat(AXF_FILE, &stat_buf) == 0) { + axf_size = stat_buf.st_size; + } + else { + fprintf(stderr, "? cannot stat %s (%d)\n", AXF_FILE, errno); + exit(1); + } + + infd = open(AXF_FILE, O_RDONLY); + if (infd) { + axf = mmap(NULL, axf_size, PROT_READ, MAP_PRIVATE, infd, 0); + if (axf <= 0) { + fprintf(stderr, "? memory map failed (%d)\n", errno); + exit(1); + } + + /* copy everything before the kernel args */ + lseek(infd, 0, SEEK_SET); + lseek(outfd, 0, SEEK_SET); + write(outfd, axf, ARG_OFFSET); + + /* + * replace the BUFFER_LENGTH space in the input axf file + * with the arguments we really want + */ + buf = malloc(BUFFER_LENGTH + 1); + memset(buf, ' ', BUFFER_LENGTH); + memcpy(buf, kargs, strlen(kargs)); + write(outfd, buf, BUFFER_LENGTH); + + /* copy everything after the kernel args */ + write(outfd, axf + ARG_OFFSET + BUFFER_LENGTH, + axf_size - (ARG_OFFSET + BUFFER_LENGTH)); + + close(outfd); + free(buf); + munmap(axf, axf_size); + close(infd); + } + else { + fprintf(stderr, "? cannot open %s as input\n", AXF_FILE); + exit(1); + } +} + -- cgit