Created
December 27, 2016 19:01
-
-
Save vi/92f537c617e34609cbce141d810b6274 to your computer and use it in GitHub Desktop.
memdump based on https://unix.stackexchange.com/questions/6301
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Source: http://unix.stackexchange.com/a/251769/17594 | |
// Modifications: long long, exit codes, diagnostics | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <limits.h> | |
#include <sys/ptrace.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
void dump_memory_region(FILE* pMemFile, unsigned long long start_address, long long length, int serverSocket) | |
{ | |
unsigned long long address; | |
int pageLength = 4096; | |
unsigned char page[pageLength]; | |
fseeko(pMemFile, start_address, SEEK_SET); | |
//fprintf(stderr, "length=%llx\n", length); | |
for (address=start_address; address < start_address + length; address += pageLength) | |
{ | |
//fprintf(stderr, "address=%llx\n", address); | |
fread(&page, 1, pageLength, pMemFile); | |
if (serverSocket == -1) | |
{ | |
// write to stdout | |
fwrite(&page, 1, pageLength, stdout); | |
} | |
else | |
{ | |
send(serverSocket, &page, pageLength, 0); | |
} | |
} | |
} | |
int main(int argc, char **argv) { | |
if (argc == 2 || argc == 4) | |
{ | |
int pid = atoi(argv[1]); | |
long ptraceResult = ptrace(PTRACE_ATTACH, pid, NULL, NULL); | |
if (ptraceResult < 0) | |
{ | |
printf("Unable to attach to the pid specified\n"); | |
return; | |
} | |
wait(NULL); | |
char mapsFilename[1024]; | |
sprintf(mapsFilename, "/proc/%s/maps", argv[1]); | |
FILE* pMapsFile = fopen(mapsFilename, "r"); | |
char memFilename[1024]; | |
sprintf(memFilename, "/proc/%s/mem", argv[1]); | |
FILE* pMemFile = fopen(memFilename, "r"); | |
int serverSocket = -1; | |
if (argc == 4) | |
{ | |
unsigned int port; | |
int count = sscanf(argv[3], "%d", &port); | |
if (count == 0) | |
{ | |
printf("Invalid port specified\n"); | |
return; | |
} | |
serverSocket = socket(AF_INET, SOCK_STREAM, 0); | |
if (serverSocket == -1) | |
{ | |
printf("Could not create socket\n"); | |
return; | |
} | |
struct sockaddr_in serverSocketAddress; | |
serverSocketAddress.sin_addr.s_addr = inet_addr(argv[2]); | |
serverSocketAddress.sin_family = AF_INET; | |
serverSocketAddress.sin_port = htons(port); | |
if (connect(serverSocket, (struct sockaddr *) &serverSocketAddress, sizeof(serverSocketAddress)) < 0) | |
{ | |
printf("Could not connect to server\n"); | |
return; | |
} | |
} | |
char line[256]; | |
while (fgets(line, 256, pMapsFile) != NULL) | |
{ | |
fprintf(stderr, "%s", line); | |
unsigned long long start_address = 0; | |
unsigned long long end_address = 0; | |
if (2 != sscanf(line, "%llx-%llx\n", &start_address, &end_address) ) { | |
fprintf(stderr, "Failed to parse maps line\n"); | |
exit(2); | |
} | |
//fprintf(stderr, "start=%llx end=%llx\n", start_address, end_address); | |
dump_memory_region(pMemFile, start_address, end_address - start_address, serverSocket); | |
} | |
fclose(pMapsFile); | |
fclose(pMemFile); | |
if (serverSocket != -1) | |
{ | |
close(serverSocket); | |
} | |
ptrace(PTRACE_CONT, pid, NULL, NULL); | |
ptrace(PTRACE_DETACH, pid, NULL, NULL); | |
exit(0); | |
} | |
else | |
{ | |
fprintf(stderr, "%s <pid>\n", argv[0]); | |
fprintf(stderr, "%s <pid> <ip-address> <port>\n", argv[0]); | |
exit(1); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment