Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:The design of the exoskeleton. Monograph
.pdf
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;
}
/****************************************************
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
