./c0de/c/memdump.txt

0.
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.
/* Creator: K-sPecial (xzziroz.net) of .aware (awarenetwork.org)
 * Date: 07/03/2005
 * Name: memdump.c
 * Version: 
 *  07/02/2005 1.00 - memdump.c created
 *  07/03/2005 1.10 - added some error checking code on the memory reading section, not very necessary, but
 *   indeed a perk to have. also modified a strange issue where I was reading a byte at a time from ptrace()
 *   (not sure how that worked out) even though it returns a word.. who knows.. it works the same as it did
 *   just in a more correct aspect. Thanks to m0x for pointing this out.
 *
 * Description: sometimes you can execute a binary, but you don't have read access so you can't
 *  debug it or run 'strings' on it, etc. This program tricks it's way around such an issue by
 *  having a child exec the binary, then having the parent ptrace all of it's data/text memory
 *  region into a file. 
 *
 * Compile: gcc -o memview memview.c
 * Notes: I didn't figure this out, I simply incorporated it into a neat little tool of it's own.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
 
_Bool getresp (char *question);
 
int main (int argc, char **argv) { 
	char *line = NULL, file[128];
	FILE *in, *out;
	pid_t pid;
	unsigned int ini, fim;
	size_t len = 0;
	int myerrno, word;
 
	if (argc < 2) {
		fprintf(stderr, "-> you failed to specify an argument (a program's memory to dump)\n");
		exit(1);
	}
 
	if (pid = fork()) { 
		sleep(1);
		sprintf(file, "/proc/%d/maps", pid);
		printf("file: %s\n", file);
		if ((in = fopen(file, "r")) == NULL) { 
			myerrno = errno;
			fprintf(stderr, "-!> error opening file '%s' for writing: %s\n", file, strerror(myerrno));
			exit(1);
		}
		printf("- sigint at any time to abort\n");
		while (getline(&line, &len, in) != -1) {
			printf("\nCurrent line from 'maps': %s", line);
			if (getresp("Parse this memory location? ")) {
				if (sscanf(line, "%x-%x", &ini, &fim) != 2) {
					printf("-?> your last request could not be processed! Moving to next line in 'maps'\n");
					continue;
				}
 
				printf("Enter a output filename: ");
				fgets(file, 128, stdin);
				*(file+strlen(file)-1) = 0;
 
				if ((out = fopen(file, "w")) == NULL) {
					myerrno = errno;
					fprintf(stderr, "-!> error opening file '%s' for writing: %s\n", file, strerror(myerrno));
					exit(1);
				}
				errno = 0;
				while (ini <= fim) {
					word = ptrace(PTRACE_PEEKDATA, pid, (void *)ini, (void *)0);
					if (word == -1 && (errno == EBUSY || errno == EFAULT || errno == EIO || errno == EPERM || errno == ESRCH)) {
						perror("-?> memory read failed");
						break;
					}
					fwrite(&word, sizeof(word), 1, out);
					ini += 4;
				}
				fclose(out);
			}
		}
		if (line) free (line);
		fclose(in);
	}
	else if (pid == -1)
		perror("-!> unable to fork");
	else {
		ptrace(PTRACE_TRACEME, 0, NULL, NULL);
		execve(*(argv+1), 0, 0);
	}
}
 
_Bool getresp (char *question) { 
	size_t len = 0;
	char *line = NULL;
	fwrite(question, strlen(question), 1, stdout);
	getline(&line, &len, stdin);
	*line = tolower(*line);
	if (*line == 'y' && line) { free(line); return(1); }
	if (line) free(line);
	return(0);
}
 
 
 
 

Back