1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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 <ahs3@ahs3.net>
*
* 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define ARG_OFFSET 0x4000e4
#define AXF_FILE "./linux-system-useless.axf"
#define BUFFER_LENGTH 400
void
usage() {
fprintf(stderr, "usage: paxf <output-axf> <kernel-parameters>\n\n");
fprintf(stderr, "where:\n");
fprintf(stderr,
" <output-axf> => name to use for patched axf file\n");
fprintf(stderr,
" <kernel-parameters> => 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);
}
}
|