/********************************************************************** * 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); } }