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

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

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
201
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;
202
}
static inline int issuit(const char c) { if (isprint(c)) return 1; if (/*c=='\n' || */ c=='\t') return 1; 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); }
203
/**************************** * 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; }
}
/******************* * 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;
204
}
/************************ * 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;
}
205
/**************************************************** * Handle int $0x80 calls - no matter why and where * ****************************************************/
static inline void want_ret(void) { current->syscall=r.eax; memcpy(¤t->pr,&r,sizeof(r)); }
/******************** * "Before" handler * ********************/
static void handle_syscall(void) { char buf[MAXFNAME]; unsigned int addr;
if (current->nest>=-1) current->syscalls++;
switch (r.eax) {
case __NR_clone:
debug("******************************************************* ********\n"
"* This application uses clone(). This is probably a sign of *\n" "* multi-threaded application. Multi-threading involves shared *\n" "* memory segments, file descriptors and such, and I am not *\n" "* able to handle it properly for now. Sorry... *\n"
206
"************************************************************* **\n");
fatal("clone() is not supported",0);
break;
case __NR_fork: #ifdef __NR_vfork case __NR_vfork: #endif /* __NR_vfork */
if (T_forks) trace_fork(); else { remove_traps(); want_ret(); } break;
case __NR_exit:
indent(0); debug("%sSYS exit (%d) = ???\n",in_libc?"[L] ":"", (int)r.ebx);
while (--current->nest>= -1 ) { indent(0); debug("...function never returned (program exited before).\n"); if (current->nest<0 || current->isfnct[current->nest]) { dump_memchg(0); if (current->fntop) current->fntop--; } if (T_dostep) break_nestdown();
207
}
break;
case __NR_execve:
indent(0);
get_string_from_child(r.ebx,buf,MAXFNAME);
RD();
debug("%sSYS execve (%x \"%s\", 0x%x, 0x%x) = ",in_libc?"[L] ":"", Xv(r.ebx),buf,Xv(r.ecx),Xv(r.edx));
DD();
current->syscall=__NR_execve; break;
case __NR_sigaction: #ifdef __NR_rt_sigaction case __NR_rt_sigaction: #endif /* __NR_rt_sigaction */
// Modify address in memory structure. addr=ptrace(PTRACE_PEEKDATA,pid,r.ecx,0);
if (!addr) break;
if ((addr >> 24) == CODESEG) ptrace(PTRACE_POKEDATA,pid,r.ecx,addr-1); else break;
208
goto aftersig;
case __NR_signal:
// Simply adjust address in register. addr=r.ecx;
if (!addr) break; if ((addr >> 24) == CODESEG || INLIBC(addr)) r.ecx--; else break;
ptrace(PTRACE_SETREGS,pid,0,&r); r.ecx++; // So __NR_signal handler won't have to do anything.
aftersig:
// Inject int3 into code. if (addr) if ((addr >> 24) == CODESEG || INLIBC(addr)) { unsigned int chg,c2; chg=ptrace(PTRACE_PEEKDATA,pid,addr-1,0); if ((current->signals < r.ebx) && (r.ebx < MAXSIG)) current->signals=r.ebx;
if (((chg & 0xff) != 0x90) && ((chg & 0xff) != 0xc3) && ((chg & 0xff) !=
0xcc)) {
c2=ptrace(PTRACE_PEEKDATA,pid,addr-3,0); if ((c2 & 0xffffff) != 0x00768d) // Stupid gcc -O9 lea debug("* WARNING: Handler for sig %d (%x) w/o leading NOP or RET,
problems!\n",(int)r.ebx,addr);
}
209
if ((chg & 0xff) == 0xc3) set_withret(r.ebx,1); else if ((chg & 0xff) == 0x90) set_withret(r.ebx,0); chg = ( chg & 0xffffff00 ) + 0xcc; /* cc: int3 */ ptrace(PTRACE_POKEDATA,pid,addr-1,chg);
}
default: want_ret();
}
if (T_dostep && current) { fflush(0); break_syscall(r.eax); }
}
/************************ * Add item to fd table * ************************/
static void add_filedes(const int fd,const char* fname,char* who,int
p) {
char tmpbuf[MAXDESCR];
if (!current->fd) { current->fd=malloc(TABINC*sizeof(struct fenris_fd)); current->fdtop=TABINC;
210
}
while (current->fdtop<=fd) { current->fdtop+=TABINC; current->fd=realloc(current->fd,current->fdtop*sizeof(struct
fenris_fd));
}
(*current->fd)[fd].special=0; (*current->fd)[fd].name=strdup(fname);
snprintf(tmpbuf,MAXDESCR,"opened in %s",who);
(*current->fd)[fd].descr=strdup(tmpbuf); (*current->fd)[fd].p=p;
if (current->nest>=-1 && !T_nodesc) { indent(0); debug("@ created fd %d (%s)\n",fd,fname); }
}
/*********************** * Add unknown filedes * ***********************/
static void unknown_filedes(const int fd,const char* fname) {
char tmpbuf[MAXDESCR];
if (!current->fd) {
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]