1
|
#include <stdio.h>
|
2
|
#include <stdlib.h>
|
3
|
#include <string.h>
|
4
|
#include <unistd.h>
|
5
|
#include <fcntl.h>
|
6
|
#include <errno.h>
|
7
|
#include <sys/ptrace.h>
|
8
|
#include <sys/types.h>
|
9
|
#include <sys/stat.h>
|
10
|
#include <sys/wait.h>
|
11
|
|
12
|
void dump(unsigned char *buf,long target_addr,ssize_t sz);
|
13
|
|
14
|
int main( int argc ,char *argv[] )
|
15
|
{
|
16
|
const int npath = 32;
|
17
|
char path[npath];
|
18
|
pid_t pid;
|
19
|
long target_addr;
|
20
|
int read_sz;
|
21
|
int fd;
|
22
|
off_t ofs;
|
23
|
ssize_t sz;
|
24
|
unsigned char *buf;
|
25
|
|
26
|
|
27
|
if( argc < 4 ){
|
28
|
printf("Usage:\n");
|
29
|
printf(" # %s pid target_addr(hex) read_sz(hex)\n\n",argv[0]);
|
30
|
exit(1);
|
31
|
}
|
32
|
pid = atoi(argv[1]);
|
33
|
sscanf(argv[2],"%lx",&target_addr);
|
34
|
sscanf(argv[3],"%x",&read_sz);
|
35
|
|
36
|
|
37
|
buf = malloc(read_sz);
|
38
|
if(buf == NULL){
|
39
|
fprintf(stderr,"Failed to malloc (size: %d)\n",read_sz);
|
40
|
exit(1);
|
41
|
}
|
42
|
|
43
|
|
44
|
if(ptrace(PTRACE_ATTACH,pid,NULL,NULL) != 0 ){
|
45
|
fprintf(stderr,"Failed to attach (pid: %d)\n",pid);
|
46
|
exit(1);
|
47
|
}
|
48
|
if(waitpid(pid,NULL,0) < 0 ){
|
49
|
fprintf(stderr,"Failed to waitpid (pid: %d)\n",pid);
|
50
|
exit(1);
|
51
|
}
|
52
|
|
53
|
snprintf(path,npath,"/proc/%d/mem",pid);
|
54
|
fd = open(path, O_RDONLY);
|
55
|
if ( fd < 0 ){
|
56
|
fprintf(stderr,"Failed to open:%s\n",path);
|
57
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
58
|
exit(1);
|
59
|
}
|
60
|
|
61
|
|
62
|
ofs = lseek(fd,target_addr,SEEK_SET);
|
63
|
if ( ofs == (off_t)-1){
|
64
|
fprintf(stderr,"Failed to lseek, errno:%d\n",errno);
|
65
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
66
|
exit(1);
|
67
|
}
|
68
|
|
69
|
sz = read(fd,buf,read_sz);
|
70
|
if( sz != read_sz){
|
71
|
fprintf(stderr,"Failed to read, errno:%d %s\n",errno,strerror(errno));
|
72
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
73
|
exit(1);
|
74
|
}
|
75
|
|
76
|
|
77
|
dump(buf,target_addr,sz);
|
78
|
|
79
|
close(fd);
|
80
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
81
|
free(buf);
|
82
|
return EXIT_SUCCESS;
|
83
|
}
|
84
|
|
85
|
void dump(unsigned char *buf,long target_addr,ssize_t read_sz){
|
86
|
ssize_t sz;
|
87
|
char disp_ascii[17];
|
88
|
|
89
|
memset(disp_ascii,'\0',sizeof(disp_ascii));
|
90
|
|
91
|
for( sz = 0 ; sz < read_sz ; sz++ ){
|
92
|
if( sz%16 == 0 && sz == 0 )printf("%07lx: ",target_addr+sz);
|
93
|
if( sz%16 == 0 && sz != 0 )printf(" %s\n%07lx: ",disp_ascii,target_addr+sz);
|
94
|
if( sz%2 == 0 ){
|
95
|
printf("%02x",buf[sz]);
|
96
|
}else{
|
97
|
printf("%02x ",buf[sz]);
|
98
|
}
|
99
|
if(buf[sz] < 0x20 || buf[sz] >= 0x7F){
|
100
|
disp_ascii[sz%16] = '.';
|
101
|
}else{
|
102
|
disp_ascii[sz%16] = buf[sz];
|
103
|
}
|
104
|
}
|
105
|
if(sz%16 != 0){
|
106
|
for( sz = 16 - sz%16 ; sz != 0 ; sz-- ){
|
107
|
if( sz%2 == 0 ){
|
108
|
printf(" ");
|
109
|
}else{
|
110
|
printf(" ");
|
111
|
}
|
112
|
disp_ascii[16-sz] = ' ';
|
113
|
}
|
114
|
}
|
115
|
printf(" %s\n",disp_ascii);
|
116
|
}
|