|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <sys/ptrace.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
|
|
void dump(unsigned char *buf,long target_addr,ssize_t sz);
|
|
|
|
int main( int argc ,char *argv[] )
|
|
{
|
|
const int npath = 32;
|
|
char path[npath];
|
|
pid_t pid;
|
|
long target_addr;
|
|
int read_sz;
|
|
int fd;
|
|
off_t ofs;
|
|
ssize_t sz;
|
|
unsigned char *buf;
|
|
|
|
/* 引数の取得 */
|
|
if( argc < 4 ){
|
|
printf("Usage:\n");
|
|
printf(" # %s pid target_addr(hex) read_sz(hex)\n\n",argv[0]);
|
|
exit(1);
|
|
}
|
|
pid = atoi(argv[1]);
|
|
sscanf(argv[2],"%lx",&target_addr);
|
|
sscanf(argv[3],"%x",&read_sz);
|
|
|
|
/* 読み出しバッファの確保 */
|
|
buf = malloc(read_sz);
|
|
if(buf == NULL){
|
|
fprintf(stderr,"Failed to malloc (size: %d)\n",read_sz);
|
|
exit(1);
|
|
}
|
|
|
|
/* 読み出し対象のトレース状態化と/porc/<PID>/memのオープン */
|
|
if(ptrace(PTRACE_ATTACH,pid,NULL,NULL) != 0 ){
|
|
fprintf(stderr,"Failed to attach (pid: %d)\n",pid);
|
|
exit(1);
|
|
}
|
|
if(waitpid(pid,NULL,0) < 0 ){ /* ATTACH の完了を待つ */
|
|
fprintf(stderr,"Failed to waitpid (pid: %d)\n",pid);
|
|
exit(1);
|
|
}
|
|
|
|
snprintf(path,npath,"/proc/%d/mem",pid);
|
|
fd = open(path, O_RDONLY);
|
|
if ( fd < 0 ){
|
|
fprintf(stderr,"Failed to open:%s\n",path);
|
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
|
exit(1);
|
|
}
|
|
|
|
/* 目的のアドレスまでシークし、読み出す */
|
|
ofs = lseek(fd,target_addr,SEEK_SET);
|
|
if ( ofs == (off_t)-1){
|
|
fprintf(stderr,"Failed to lseek, errno:%d\n",errno);
|
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
|
exit(1);
|
|
}
|
|
|
|
sz = read(fd,buf,read_sz);
|
|
if( sz != read_sz){
|
|
fprintf(stderr,"Failed to read, errno:%d %s\n",errno,strerror(errno));
|
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
|
exit(1);
|
|
}
|
|
|
|
/* メモリの内容表示 */
|
|
dump(buf,target_addr,sz);
|
|
|
|
close(fd);
|
|
ptrace(PTRACE_DETACH,pid,NULL,NULL);
|
|
free(buf);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
void dump(unsigned char *buf,long target_addr,ssize_t read_sz){
|
|
ssize_t sz;
|
|
char disp_ascii[17];
|
|
|
|
memset(disp_ascii,'\0',sizeof(disp_ascii));
|
|
|
|
for( sz = 0 ; sz < read_sz ; sz++ ){
|
|
if( sz%16 == 0 && sz == 0 )printf("%07lx: ",target_addr+sz);
|
|
if( sz%16 == 0 && sz != 0 )printf(" %s\n%07lx: ",disp_ascii,target_addr+sz);
|
|
if( sz%2 == 0 ){
|
|
printf("%02x",buf[sz]);
|
|
}else{
|
|
printf("%02x ",buf[sz]);
|
|
}
|
|
if(buf[sz] < 0x20 || buf[sz] >= 0x7F){
|
|
disp_ascii[sz%16] = '.';
|
|
}else{
|
|
disp_ascii[sz%16] = buf[sz];
|
|
}
|
|
}
|
|
if(sz%16 != 0){
|
|
for( sz = 16 - sz%16 ; sz != 0 ; sz-- ){
|
|
if( sz%2 == 0 ){
|
|
printf(" ");
|
|
}else{
|
|
printf(" ");
|
|
}
|
|
disp_ascii[16-sz] = ' ';
|
|
}
|
|
}
|
|
printf(" %s\n",disp_ascii);
|
|
}
|