Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

The design of the exoskeleton. Monograph

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
161
warn_opt(2,current->lcpcnt); if (r.eax) add_mem(r.eax,current->lcpar[0]*current->lcpar[1],0,n,1); }
else if (!strcmp(f,"realloc")) { debug("%x, %d)",Xv(current->lcpar[0]),current->lcpar[1]); debug(" = %x\n",(int)r.eax); DD(); warn_opt(2,current->lcpcnt); if (current->lcpar[0]) { if (r.eax) add_mem(current->lcpar[0],current->lcpar[1],r.eax,n,1); } else { if (r.eax) add_mem(r.eax,current->lcpar[1],0,n,1); } }
else if (!strcmp(f,"free")) { debug("%x) = <void>\n",Xv(current->lcpar[0])); DD(); warn_opt(1,current->lcpcnt); delete_mem(current->lcpar[0],1); }
else if (!strcmp(f,"getenv")) { get_string_from_child(current->lcpar[0],buf,sizeof(buf)); if (r.eax) get_string_from_child(r.eax,b2,sizeof(buf)); debug("%x \"%s\") = %x",Xv(current->lcpar[0]),buf,(int)r.eax); if (r.eax) debug("\"%s\"\n",b2); else debug("\n"); DD(); warn_opt(1,current->lcpcnt); add_mem(current->lcpar[0],strlen(buf)+1,0,n,0); add_mem(r.eax,strlen(b2)+1,0,n,0); }
else if (!strcmp(f,"atexit")) { debug("%x) = %d\n",Xv(current->lcpar[0]),(int)r.eax); DD(); debug("*******************************************************\n" "* In some cases, atexit() statement can be not traced *\n" "* properly (see documentation). *\n" "*******************************************************\n"); warn_opt(1,current->lcpcnt); }
else if (!strcmp(f,"strcpy")) { get_string_from_child(current->lcpar[1],b2,sizeof(buf));
162
debug("%x, %x \"%s\") = %x\n",Xv(current->lcpar[0]), Xv(current->lcpar[1]),b2,(int)r.eax); DD(); warn_opt(2,current->lcpcnt); add_mem(current->lcpar[0],strlen(b2)+1,0,n,0); add_mem(current->lcpar[1],strlen(b2)+1,0,n,0); modify_lasti(current->lcpar[0],n,0,0,0); indent(0); debug("\\ data migration: %x to %x\n",current->lcpar[1],current->lcpar[0]); }
else if (!strcmp(f,"memcpy") || !strcmp(f,"memmove")) { debug("%x, %x, %d) = %x\n",Xv(current->lcpar[0]), Xv(current->lcpar[1]),current->lcpar[2],(int)r.eax); DD(); warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[2],0,n,0); add_mem(current->lcpar[1],current->lcpar[2],0,n,0); modify_lasti(current->lcpar[0],n,0,0,0); indent(0); debug("\\ data migration: %x to %x\n",current->lcpar[1],current->lcpar[0]); }
else if (!strcmp(f,"memset")) { debug("%x, %x, %d) = %x\n",Xv(current->lcpar[0]), current->lcpar[1],current->lcpar[2],(int)r.eax); DD(); warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[2],0,n,0); modify_lasti(current->lcpar[0],n,0,0,0); indent(0); }
else if (!strcmp(f,"bzero")) { debug("%x, %d) = %x\n",Xv(current->lcpar[0]), current->lcpar[1],(int)r.eax); DD(); warn_opt(2,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[1],0,n,0); modify_lasti(current->lcpar[0],n,0,0,0); }
else if (!strcmp(f,"bcopy")) { debug("%x, %x, %d) = %x\n",Xv(current->lcpar[0]), Xv(current->lcpar[1]),current->lcpar[2],(int)r.eax); DD();
163
warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[2],0,n,0); add_mem(current->lcpar[1],current->lcpar[2],0,n,0); modify_lasti(current->lcpar[1],n,0,0,0); indent(0); debug("\\ data migration: %x to %x\n",current->lcpar[0],current->lcpar[1]); }
else if (!strcmp(f,"memcmp") || !strcmp(f,"bcmp")) { debug("%x, %x, %d) = %x\n",Xv(current->lcpar[0]), Xv(current->lcpar[1]),current->lcpar[2],(int)r.eax); DD(); warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[2],0,n,0); add_mem(current->lcpar[1],current->lcpar[2],0,n,0); }
else if (!strcmp(f,"getc")) { FILE x; int fd; int off=((int)&x._fileno - (int)&x); fd=ptrace(PTRACE_PEEKDATA,pid,current->lcpar[0]+off,0); debug("%x [%d]) = '%c' %d\n",Xv(current->lcpar[0]), Xf(fd),isprint(r.eax)?(int)r.eax:'?',(int)r.eax); DD(); warn_opt(1,current->lcpcnt); add_mem(current->lcpar[0],sizeof(x),0,n,0); }
else if (!strcmp(f,"strcmp")) { get_string_from_child(current->lcpar[0],buf,sizeof(buf)); get_string_from_child(current->lcpar[1],b2,sizeof(buf)); debug("%x \"%s\", %x \"%s\") = %x\n",current->lcpar[0],buf, current->lcpar[1],b2,(int)r.eax); DD(); warn_opt(2,current->lcpcnt); add_mem(current->lcpar[0],strlen(buf)+1,0,n,0); add_mem(current->lcpar[1],strlen(b2)+1,0,n,0); }
else if (!strcmp(f,"strncmp")) { get_string_from_child(current->lcpar[0],buf,sizeof(buf)); get_string_from_child(current->lcpar[1],b2,sizeof(buf)); debug("%x \"%s\", %x \"%s\", %d) = %x\n",Xv(current->lcpar[0]),buf, Xv(current->lcpar[1]),b2,current->lcpar[2],(int)r.eax); DD();
164
warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],strlen(buf)+1,0,n,0); add_mem(current->lcpar[1],strlen(b2)+1,0,n,0); }
else if (!strcmp(f,"strncpy")) { get_string_from_child(current->lcpar[1],b2,sizeof(buf)); debug("%x, %x \"%s\", %d) = %x\n",Xv(current->lcpar[0]), Xv(current->lcpar[1]),b2,current->lcpar[2],(int)r.eax); DD(); warn_opt(3,current->lcpcnt); add_mem(current->lcpar[0],current->lcpar[2],0,n,0); add_mem(current->lcpar[1],strlen(b2)+1,0,n,0); modify_lasti(current->lcpar[0],n,0,0,0); indent(0); debug("\\ data migration: %x to %x\n",current->lcpar[1],current->lcpar[0]); }
else fatal("display_specific called on something non-specific",0);
RD();
}
/***************************************************************** * Check if we handle this one separately, save all the stuff... * *****************************************************************/
static inline char check_specific(char* n,unsigned int esP,int pcnt) { int i;
if (strcmp(n,"strlen")) if (strcmp(n,"getenv")) if (strcmp(n,"strcpy")) if (strcmp(n,"memcpy")) if (strcmp(n,"strdup")) if (strcmp(n,"calloc")) if (strcmp(n,"malloc")) if (strcmp(n,"realloc")) if (strcmp(n,"free")) if (strcmp(n,"getc")) if (strcmp(n,"strcmp"))
165
if (strcmp(n,"strncmp")) if (strcmp(n,"strncpy")) if (strcmp(n,"atexit")) if (strcmp(n,"memmove")) if (strcmp(n,"memset")) if (strcmp(n,"bzero")) if (strcmp(n,"bcopy")) if (strcmp(n,"memcmp")) if (strcmp(n,"bcmp"))
return 0;
strncpy(current->lcname,n,MAXNAME); current->lcpcnt=pcnt;
for (i=0;i<MAXPARS;i++) current->lcpar[i]=ptrace(PTRACE_PEEKDATA,pid,esP+i*4,0);
return 1;
}
/********************* * Clean up old mess * *********************/
static void remove_process(void) { int i;
if (!current) fatal("trying to remove process but current is NULL",0);
if (current->gopt+current->bopt) debug("+++ Parameter prediction %0.2f%% successful [%d:%d] +++\n",100.0*((float)current-
>gopt)/((float)(current->gopt+current->bopt)),current->bopt,current->gopt);
if (T_dostep) break_exitcond();
for (i=0;i<MAXNEST;i++) { if (current->wlog[i]) free(current->wlog[i]); }
if (current->mem) {
166
int i; for (i=0;i<current->memtop;i++) if ((*current->mem)[i].descr) free((*current->mem)[i].descr); for (i=0;i<current->memtop;i++) if ((*current->mem)[i].lasti) free((*current->mem)[i].lasti); free(current->mem); }
if (current->b) bfd_close(current->b); if (current->syms) free(current->syms);
if (current->map) { int i; for (i=0;i<current->mtop+1;i++) { if ((*current->map)[i].name) free((*current->map)[i].name); if ((*current->map)[i].descr) free((*current->map)[i].descr); if ((*current->map)[i].lasti) free((*current->map)[i].lasti); } free(current->map); }
if (current->fd) { int i; for (i=0;i<current->fdtop;i++) { if ((*current->fd)[i].name) free((*current->fd)[i].name); if ((*current->fd)[i].descr) free((*current->fd)[i].descr); } free(current->fd); }
if (current->fnaddr) free(current->fnaddr); bzero(current,sizeof(struct fenris_process)); current=0;
}
/******************************************** * Duplicate some structures. I do not even * * want to think how would it look like for * * partially shared process info (clone()). * ********************************************/
static void clone_process(const int newpid) { int i;
167
struct fenris_process *p;
if (!current) fatal("trying to clone process but current is NULL",0);
p=current; add_process(newpid); memcpy(current,p,sizeof(struct fenris_process)); current->pid=newpid; current->syscall=0;
for (i=0;i<MAXNEST;i++) { if (current->wlog[i]) current->wlog[i]=strdup(current->wlog[i]); }
if (current->mem) { int i; current->mem=malloc((1+TABINC+current->memtop)*sizeof(struct fenris_mem)); memcpy(current->mem,p->mem,(1+TABINC+current->memtop)*sizeof(struct fenris_mem)); for (i=0;i<current->memtop;i++) { if ((*p->mem)[i].descr) (*current->mem)[i].descr=strdup((*p->mem)[i].descr); if ((*p->mem)[i].lasti) (*current->mem)[i].lasti=strdup((*p->mem)[i].lasti); } }
if (current->map) { int i; current->map=malloc((1+TABINC+current->mtop)*sizeof(struct fenris_map)); memcpy(current->map,p->map,(1+TABINC+current->mtop)*sizeof(struct fenris_map)); for (i=0;i<current->mtop;i++) { if ((*p->map)[i].descr) (*current->map)[i].descr=strdup((*p->map)[i].descr); if ((*p->map)[i].name) (*current->map)[i].name=strdup((*p->map)[i].name); if ((*p->map)[i].lasti) (*current->map)[i].lasti=strdup((*p->map)[i].lasti); } }
if (current->fd) { int i; current->fd=malloc((1+TABINC+current->fdtop)*sizeof(struct fenris_fd)); memcpy(current->fd,p->fd,(TABINC+current->fdtop+1)*sizeof(struct fenris_fd)); for (i=0;i<current->fdtop;i++) { if ((*p->fd)[i].descr) (*current->fd)[i].descr=strdup((*p->fd)[i].descr); if ((*p->fd)[i].name) (*current->fd)[i].name=strdup((*p->fd)[i].name); } }
168
if (current->fnaddr) { current->fnaddr=malloc((1+TABINC+current->idtop)*sizeof(int)); memcpy(current->fnaddr,p->fnaddr,current->idtop*sizeof(int)); }
current->b=0; current->syms=0;
current=p;
}
/********************************* * Get string from ptraced child * *********************************/
static inline void get_string_from_child(const unsigned int addr, char* buf,int max) { int i=0; char *b=buf;
while (b<buf+max) { AS_UINT(*b)=ptrace(PTRACE_PEEKDATA,pid,addr+i,0);
if (AS_UINT(*b)==-1) { *b=0; return; // Lame, but what can I do? For strings, acceptable. }
if (b[0] && ((!isprint(b[0])) || (b[0]=='"'))) b[0]='?'; if (b[1] && ((!isprint(b[1])) || (b[1]=='"'))) b[1]='?'; if (b[2] && ((!isprint(b[2])) || (b[2]=='"'))) b[2]='?'; if (b[3] && ((!isprint(b[3])) || (b[3]=='"'))) b[3]='?'; if (!(b[0] && b[1] && b[2] && b[3])) return; b+=4; i+=4; }
buf[max-1]=0;
}
static inline int issuit(const char c) { if (isprint(c)) return 1; if (/*c=='\n' || */ c=='\t') return 1;
169
return 0; }
static inline void print_string(const unsigned int addr,const char* where) { char b[5] = {0,0,0,0,0}; int miau=0; AS_UINT(b) = ptrace(PTRACE_PEEKDATA,pid,addr,0); if (issuit(b[0]) && issuit(b[1]) && issuit(b[2]) && issuit(b[3])) { debug(" \"%s",b); miau=4; while (strlen(b)==4) { AS_UINT(b) = ptrace(PTRACE_PEEKDATA,pid,addr+miau,0); if (b[0] && !isprint(b[0])) b[0]='?'; if (b[1] && !isprint(b[1])) b[1]='?'; if (b[2] && !isprint(b[2])) b[2]='?'; if (b[3] && !isprint(b[3])) b[3]='?'; if (miau<MAXUNKNOWN) debug("%s",b); miau+=strlen(b); } debug("\""); if (miau>=MAXUNKNOWN) debug("..."); } if (miau) add_mem(addr,miau+1,2,where,0); }
/**************************** * Get memory from child :> * ****************************/
static inline void get_mem_from_child(const unsigned int addr, char* buf,int max) { int i=0; char *b=buf;
while (max % 4) max--;
while (b<buf+max) { AS_UINT(*b)=ptrace(PTRACE_PEEKDATA,pid,addr+i,0); b+=4; i+=4; }
}
170
/******************* * Check for error * *******************/
char errbuf[64];
static inline char* toerror(int q) { if (q<0) sprintf(errbuf,"%d (%s)",q,strerror(-q)); else sprintf(errbuf,"%d",q); return errbuf; }
/************************ * Quick fork() handler * ************************/
static void trace_fork(void) {
int p=0,q=0,off,ser; struct user u;
off=(unsigned int)&u.regs.eax - (unsigned int)&u; errno=1234; // This is the speed zone. ptrace(PTRACE_SINGLESTEP,pid,1,0); while (errno) p=ptrace(PTRACE_PEEKUSER,pid,off, errno=0); if (p>0) q=ptrace(PTRACE_ATTACH,p,0,0); // End of speed zone.
ser=errno; indent(0); debug("%sfork () = %s\n",in_libc?"[L] ":"",toerror((int)p));
if (q) fatal("PTRACE_ATTACH failed",ser); debug("+++ New process %d attached +++\n",p); clone_process(p); r.eax=p;
}
/****************************************************