Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Проектирование экзоскелета. Монография
.pdf
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) {
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
