mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
perform in-place replacement via O_RDWR
This commit is contained in:
parent
47eac0cdad
commit
2c098b35a4
1 changed files with 10 additions and 25 deletions
|
@ -39,14 +39,14 @@
|
||||||
"https://github.com/jart/cosmopolitan\n"
|
"https://github.com/jart/cosmopolitan\n"
|
||||||
|
|
||||||
#define MANUAL \
|
#define MANUAL \
|
||||||
" -f FROM -t TO -o OUTPUT INPUT \n" \
|
" -f FROM -t TO INPUT \n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
"DESCRIPTION\n" \
|
"DESCRIPTION\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" string replacement in ELF binary .rodata\n" \
|
" in-place string replacement in ELF binary .rodata\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" this program may be used to replace strings in the\n" \
|
" this program may be used to replace strings in the\n" \
|
||||||
" .rodata sections of ELF binaries.\n" \
|
" .rodata sections of ELF binaries, in-place.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
"FLAGS\n" \
|
"FLAGS\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
|
@ -59,8 +59,6 @@
|
||||||
" -t TO target string replacement. must be shorter\n" \
|
" -t TO target string replacement. must be shorter\n" \
|
||||||
" than FROM string for replacement to work\n" \
|
" than FROM string for replacement to work\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" -o OUTPUT output file\n" \
|
|
||||||
"\n" \
|
|
||||||
" INPUT ELF binary containing strings to replace\n" \
|
" INPUT ELF binary containing strings to replace\n" \
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
|
@ -69,8 +67,7 @@ static const char *exepath;
|
||||||
static Elf64_Shdr *rodata;
|
static Elf64_Shdr *rodata;
|
||||||
static char *rostart;
|
static char *rostart;
|
||||||
static char *roend;
|
static char *roend;
|
||||||
static const char *outpath;
|
static int exefd;
|
||||||
static int outfd;
|
|
||||||
|
|
||||||
static wontreturn void Die(const char *thing, const char *reason) {
|
static wontreturn void Die(const char *thing, const char *reason) {
|
||||||
tinyprint(2, thing, ": ", reason, "\n", NULL);
|
tinyprint(2, thing, ": ", reason, "\n", NULL);
|
||||||
|
@ -108,8 +105,8 @@ static void Pwrite(const void *data, size_t size, uint64_t offset) {
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
const char *p, *e;
|
const char *p, *e;
|
||||||
for (p = data, e = p + size; p < e; p += (size_t)rc, offset += (size_t)rc) {
|
for (p = data, e = p + size; p < e; p += (size_t)rc, offset += (size_t)rc) {
|
||||||
if ((rc = pwrite(outfd, p, e - p, offset)) == -1) {
|
if ((rc = pwrite(exefd, p, e - p, offset)) == -1) {
|
||||||
DieSys(outpath);
|
DieSys(exepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,19 +132,13 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
bool partial = false;
|
bool partial = false;
|
||||||
params.n = 0;
|
params.n = 0;
|
||||||
struct Param *param;
|
struct Param *param;
|
||||||
while ((opt = getopt(argc, argv, "hvf:t:o:")) != -1) {
|
while ((opt = getopt(argc, argv, "hvf:t:")) != -1) {
|
||||||
if (params.n >= ARRAYLEN(params.p)) {
|
if (params.n >= ARRAYLEN(params.p)) {
|
||||||
param = NULL;
|
param = NULL;
|
||||||
} else {
|
} else {
|
||||||
param = &(params.p[params.n]);
|
param = &(params.p[params.n]);
|
||||||
}
|
}
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'o':
|
|
||||||
if (outpath) {
|
|
||||||
Die(prog, "outpath already provided");
|
|
||||||
}
|
|
||||||
outpath = optarg;
|
|
||||||
break;
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (!param) {
|
if (!param) {
|
||||||
Die(prog, "too many replacements provided");
|
Die(prog, "too many replacements provided");
|
||||||
|
@ -199,9 +190,6 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
Die(prog, "need to_string for replacement");
|
Die(prog, "need to_string for replacement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!outpath) {
|
|
||||||
Die(prog, "need outpath to write file");
|
|
||||||
}
|
|
||||||
if (optind == argc) {
|
if (optind == argc) {
|
||||||
Die(prog, "missing input argument");
|
Die(prog, "missing input argument");
|
||||||
}
|
}
|
||||||
|
@ -389,7 +377,7 @@ static struct Input input;
|
||||||
|
|
||||||
static void OpenInput(const char *path) {
|
static void OpenInput(const char *path) {
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = open(path, O_RDONLY)) == -1)
|
if ((fd = open(path, O_RDWR)) == -1)
|
||||||
DieSys(path);
|
DieSys(path);
|
||||||
if ((input.size = lseek(fd, 0, SEEK_END)) == -1)
|
if ((input.size = lseek(fd, 0, SEEK_END)) == -1)
|
||||||
DieSys(path);
|
DieSys(path);
|
||||||
|
@ -399,7 +387,7 @@ static void OpenInput(const char *path) {
|
||||||
DieSys(path);
|
DieSys(path);
|
||||||
if (!IsElf64Binary(input.elf, input.size))
|
if (!IsElf64Binary(input.elf, input.size))
|
||||||
Die(path, "not an elf64 binary");
|
Die(path, "not an elf64 binary");
|
||||||
close(fd);
|
exefd = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReplaceString(struct Param *param) {
|
static void ReplaceString(struct Param *param) {
|
||||||
|
@ -473,11 +461,8 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
#undef NEXT_ROLOC
|
#undef NEXT_ROLOC
|
||||||
|
|
||||||
if ((outfd = creat(outpath, 0755)) == -1) {
|
|
||||||
Die(prog, "unable to open file for writing");
|
|
||||||
}
|
|
||||||
Pwrite(input.map, input.size, 0);
|
Pwrite(input.map, input.size, 0);
|
||||||
if (close(outfd)) {
|
if (close(exefd)) {
|
||||||
Die(prog, "unable to close file after writing");
|
Die(prog, "unable to close file after writing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue