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

Проектирование экзоскелета. Монография

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
141
void fatal(const char* x, const int err) { int i;
if (T_dostep) { signal(SIGPIPE,SIG_IGN); break_shutup=1; break_sendentity(); }
switch (err) {
case -2: case -1: debug(">> Exit condition: %s\n",x); break;
case 0: debug(">> Error condition: %s\n",x); break;
default: debug(">> OS error : %s [%d]\n" ">> Error condition: %s\n" ,strerror(err),err,x);
}
if (T_dostep && !fatal_there) { fatal_there=1;
break_sendentity_force(); }
if (pid>0) { if (current && current->syscall) debug(">> This condition occured during syscall %s (%d) in pid %d
(eip %x).\n",
scnames[current->syscall & 0xff],current->syscall,pid,(int)r.eip); else debug(">> This condition occured while tracing pid %d (eip
%x).\n",pid,(int)r.eip);
}
142
if (current && (current->cycles)) debug(">> Traced %u user CPU cycles (%d libcalls, %d fncalls, %d " "syscalls).\n",current->cycles,current->libcalls,current->fncalls, current->syscalls);
if (err>-1)
debug("\n**************************************************\n"
"* If you believe this is because of programming *\n" "* error, please report above message, along with *\n" "* information about your working environment and *\n" "* traced application, to the author of this *\n" "* utility (e-mail: lcamtuf@coredump.cx). Thanks! *\n" "**************************************************\n\n");
fflush(0); fclose(ostream);
// If you go down in flames, aim for something expensive. for (i=0;i<MAXCHILDREN;i++) if (ps[i].pid>0) kill(ps[i].pid,9);
if (sd>0) { shutdown(sd,2); close(sd); } // for (i=3;i<128;i++) close(i);
if (running_under_ncaegir) { char buf[100]; printf("\033[0;37m\n\033[1;41mFenris has terminated, press
RETURN to close...\033[0;37m\n");
read(0,buf,sizeof(buf)); }
#ifdef DEBUG
143
if (err>-1) abort(); #endif /* DEBUG */
exit(1);
}
/*********************************************** * Produce nice graphical indentation and such * ***********************************************/
static inline void indent(const int corr) { static char intbuf[MAXINDENT+2]; static int tib; if (T_noindent) return; intbuf[0]=0; if (current->nest>=0) { tib=(corr+current->nest)>MAXINDENT?MAXINDENT:(corr+current-
>nest);
if (tib>0) { memset(intbuf,' ',tib); intbuf[tib]=0; } }
if (T_addip) debug("[%08x] ",(int)r.eip); if ((current->nest+corr)<0) debug("%d:-- %s",pid,intbuf); else debug("%d:%02d %s",pid,corr+current->nest,intbuf);
}
/******************************************************** * Here we simply execute what we have to execute after *
144
* fork() and syncing with our parent process. * ********************************************************/
extern int sd; // Debugger socket. static int start_child(const char** argv) { int ret,n=1; ret=fork(); if (ret<0) fatal("cannot fork",errno); if (ret) { pid=ret; return ret; } if (runasuser) { if (initgroups(runasuser,runasgid)) fatal("initgroups failed",errno); if (setgid(runasgid)) fatal("setgid failed",errno); if (setuid(runasuid)) fatal("setuid failed",errno); debug("+++ [%s] Executing '%s",runasuser,argv[1]); } else debug("+++ Executing '%s",argv[1]); while (argv[++n]) debug(" %s",argv[n]); debug("' (pid %d, %s) +++\n",getpid(),is_static?"static":"dynamic"); fflush(0); { int i; // Close our own mess. for (i=3;i<64;i++) if (i!=sd) close(i); }
if (ptrace(PTRACE_TRACEME,0,0,0)) fatal("PTRACE_TRACEME
failed",errno);
execvp(argv[1],(void*)&argv[1]); perror(">> OS error "); kill(getppid(),SIGUSR1); fatal("cannot execute requested binary",-1); return 0; // sanity. }
/*******************************************
145
* Temporarily remove int3 traps from code * *******************************************/
static void remove_traps(void) { int i; for (i=0;i<MAXSIG;i++) { unsigned int addr=get_handler(i); if (!addr) return; if ((addr >> 24) == CODESEG || INLIBC(addr)) { unsigned int chg; chg=ptrace(PTRACE_PEEKDATA,pid,addr-1,0); if (current->shret[i]) chg = ( chg & 0xffffff00 ) + 0xc3; /* c3: ret */ else chg = ( chg & 0xffffff00 ) + 0x90; /* 90: nop */ ptrace(PTRACE_POKEDATA,pid,addr-1,chg); } } }
/************************ * Reinstall int3 traps * ************************/
static void install_traps(void) { int i; for (i=0;i<MAXSIG;i++) { unsigned int addr=get_handler(i); if (!addr) return; if ((addr >> 28) == CODESEG || INLIBC(addr)) { unsigned int chg; chg=ptrace(PTRACE_PEEKDATA,pid,addr-1,0); chg = ( chg & 0xffffff00 ) + 0xcc; /* cc: int3 */ ptrace(PTRACE_POKEDATA,pid,addr-1,chg);
146
} } }
#define remove_handler(i) add_handler(i,0)
/********************** * Add signal handler * **********************/
static inline void add_handler(int i,unsigned int a) { if (i<0 || i>=MAXSIG) return; current->sh[i]=a; }
static inline void set_withret(int i,char val) { if (i<0 || i>=MAXSIG) return; current->shret[i]=val; }
/************************* * Remove signal handler * *************************/
inline unsigned int get_handler(int i) { if (i<0 || i>=MAXSIG) return 0; return current->sh[i]; }
/******************************************* * Add or update memory region information * *******************************************/
147
static inline void add_mem(unsigned int start, int len, unsigned int
newaddr,const char* who,char auth) {
int i; char* doingmerge=0; unsigned int owner=0; char U=0; char buf[MAXDESCR], b2[MAXDESCR]; struct fenris_mem* f; if (current->nest<0) return; // No, sorry. if (len<=0) return; // Sorry even more. if (start + len < start) fatal("start + len < start in add_mem",0); if (!start || (start>0xffffff00)) return; if (newaddr==2) { newaddr=0; U=1; } if (newaddr) { // We have some authoritative buffer size readjustment. // Expect finding buffer with matching address. In // emergency, you might have to create new buffer description.
f=lookup_mem(start);
if (!f) {
// Oh man. if (!U) { indent(0); debug("- remap: non-existing buffer %x ->
%x:%d\n",start,newaddr,len);
} else { sprintf(b2,"- remap: non-existing buffer %x ->
%x:%d\n",start,newaddr,len);
nappend(pdescr,b2,MAXDESCR); }
148
if (!current->memtop) { current->memtop=TABINC; current->mem=malloc(sizeof(struct fenris_mem)*TABINC); }
for (i=0;i<current->memtop;i++) if (!(*current->mem)[i].descr) break;
if (i==current->memtop) { current->memtop+=TABINC; current->mem=realloc(current->mem,sizeof(struct
fenris_mem)*(current->memtop+1));
}
snprintf(buf,MAXDESCR,"from hell, resized in %s",who); (*current->mem)[i].descr=strdup(buf); (*current->mem)[i].addr=newaddr; (*current->mem)[i].len=len; (*current->mem)[i].owner=current->fntop; return;
}
if ( (f->addr != start) ) { if (!U) { indent(0); debug("- remap: %x -> %x:%d, but nearest is: %x:%d
(%s)\n",start,newaddr,len,f->addr,f->len,f->descr);
} else { sprintf(b2,"- remap: %x -> %x:%d, but nearest is: %x:%d
(%s)\n",start,newaddr,len,f->addr,f->len,f->descr);
nappend(pdescr,b2,MAXDESCR);
149
} return; }
if (!U) { indent(0); debug("\\ remap: %x:%d -> %x:%d\n",f->addr,f->len,newaddr,len); } else { sprintf(b2,"\\ remap: %x:%d -> %x:%d\n",f->addr,f->len,newaddr,len); nappend(pdescr,b2,MAXDESCR); }
snprintf(buf,MAXDESCR,"resized from %d in %s",f->len,who); free(f->descr); f->descr=strdup(buf); f->len = len; f->addr=newaddr; f->auth=auth;
} else {
mergeloop:
f=lookup_inrange(start,len);
if (f) { if (!T_nodesc) { if (f->auth) { if (!U) { indent(0); debug("\\ UNEXPECTED is-within: %x:%d in %x:%d (%s)\n",f->addr,f-
>len,start,len,f->descr);
} else {
150
sprintf(b2,"\\ UNEXPECTED is-within: %x:%d in %x:%d (%s)\n",f-
>addr,f->len,start,len,f->descr);
nappend(pdescr,b2,MAXDESCR); } } if (!U) { indent(0); debug("\\ discard: mem %x:%d (%s) [is within %x:%d]\n",f->addr,f-
>len,f->descr,start,len);
} else { sprintf(b2,"\\ discard: mem %x:%d (%s) [is within %x:%d]\n",f->addr,f-
>len,f->descr,start,len);
nappend(pdescr,b2,MAXDESCR); } }
f->addr=0; free(f->descr); if (f->lasti) free(f->lasti); f->lasti=0; f->descr=0; f->len=0;
f=0; goto mergeloop; }
if (!auth) f=lookup_mem(start+len+1); else f=0; if (!f) f=lookup_mem(start+len);
if (f) { if (f->addr <= start) {
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]