nkmmtyp_dump_20150524.c

プロトタイプ - kanata, 2015/05/24 09:24

ダウンロード (2.721 KB)

 
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
  /* 読み出し対象のトレース状態化と/porc/<PID>/memのオープン */
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 ){ /* ATTACH の完了を待つ */
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
}
クリップボードから画像を追加 (サイズの上限: 100 MB)