プロジェクト

全般

プロフィール

ねこみみタイフーン » nkmmtyp_dump_20150524.c

プロトタイプ - kanata, 2025/04/13 16:38

 
#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);
}
(1-1/3)