📄 emit.c
字号:
} /* Recalculate No. of BBs needing Relocation after propagation of RELOC Flag*/ for(i=0; i<M->no_of_bbs; i++) { bb_entry *curr = &M->bb_entry_nodes[i]; if((curr->trans_bb_eip != NOT_YET_TRANSLATED) && (curr->flags & NEEDS_RELOC)) { ntrelocbbs++; ntrelocbytes += curr->trans_bb_end_eip - curr->trans_bb_eip; } } FILE *F = fopen("bbdetails", "w"); fprintf(F, "Process: %s\n\n\n", str); unsigned long neip = M->next_eip;#ifdef STATIC_PASS unsigned long mneip = M->mem_next_eip;#endif decode_t ds; /*WARNING: Sieve is the first thing in the BBcache as of now */ unsigned long sieve_bytes = M->bb_entry_nodes[0].trans_bb_eip - (unsigned long)M->bbCache; for(i=0; i<M->no_of_bbs; i++) { bb_entry *entry = &M->bb_entry_nodes[i]; fprintf(F, "#ID = %lu\n", i); if(entry->trans_bb_eip == NOT_YET_TRANSLATED) fprintf(F, "Not yet translated\n\n"); else { if(entry->sieve_header != NULL) fprintf(F, "HAS_SIEVE "); if (entry->flags & IS_HAND_CONSTRUCTED) fprintf(F, "HAND_CONSTRUCTED "); if (entry->flags & IS_START_OF_TRACE) fprintf(F, "STARTS_TRACE "); if (entry->flags & IS_END_OF_TRACE) fprintf(F, "ENDS_TRACE "); if (entry->flags & NEEDS_RELOC) fprintf(F, "NEEDS_RELOCATION "); fprintf(F, "\n"); fprintf(F, "Proc-Index = 0x%08lx ", entry->proc_entry); if(entry->trace_next != NULL) fprintf(F, "Trace_Next = %lu\n", ((((unsigned long)entry->trace_next) -((unsigned long)M->bb_entry_nodes)) /((unsigned long)sizeof(bb_entry)))); else fprintf(F, "\n"); fprintf(F, "-----------------------------------------------------------\n\n"); M->next_eip = entry->src_bb_eip;#ifdef STATIC_PASS if(update_mem_next_eip(M)) fprintf(F, "OUT");#endif int j; fprintf(F, "Guest Start = 0x%08lx, End = 0x%08lx, Size = %lu\n", entry->src_bb_eip, entry->src_bb_end_eip, entry->src_bb_end_eip - entry->src_bb_eip); for(j=0; j<entry->nInstr; j++) { do_decode(M, &ds);#ifdef PROFILE_BB_STATS_DISASM do_disasm(&ds, F);#endif } ginstrs += entry->nInstr; gbytes += entry->src_bb_end_eip - entry->src_bb_eip; fprintf(F, "No. Guest Instructions = %lu\n", entry->nInstr); fprintf(F, "-----------------------------------------------------------\n\n"); M->next_eip = entry->trans_bb_eip; unsigned long trans_instrs = 0; fprintf(F, "Trans Start = 0x%08lx, End = 0x%08lx, Size = %lu\n", entry->trans_bb_eip, entry->trans_bb_end_eip, entry->trans_bb_end_eip - entry->trans_bb_eip); while(M->next_eip < entry->trans_bb_end_eip) { do_decode(M, &ds);#ifdef PROFILE_BB_STATS_DISASM do_disasm(&ds, F);#endif trans_instrs++; } tinstrs += trans_instrs; tbytes += entry->trans_bb_end_eip - entry->trans_bb_eip; fprintf(F, "No. Translated Instructions = %lu\n", trans_instrs); fprintf(F, "===========================================================\n\n"); } } M->next_eip = neip; /* Restore the old value */#ifdef STATIC_PASS M->mem_next_eip = mneip;#endif /* Print the Summary */ fprintf(F, "No: of BBs = %lu\n", M->no_of_bbs); fprintf(F, "No: of Translated BBs = %lu\n", nactualbbs); fprintf(F, "Total No. of Guest Instrs = %lu\n", ginstrs); fprintf(F, "Total No. of Trans Instrs = %lu\n", tinstrs); fprintf(F, "Total No. of Guest Instr Bytes = %lu\n", gbytes); fprintf(F, "Total No. of Trans Instrs Bytes = %lu\n", tbytes); fprintf(F, "No. of Bytes used in BBCache = %lu [%0.3f%% of BBCache]\n", nactualbytes, PERC(nactualbytes, BBCACHE_SIZE)); fprintf(F, "No. of Bytes in sieve-hash-table = %lu\n", sieve_bytes); fprintf(F, "No. of Bytes ignoring sieve table = %lu [%0.3f%% of BBCache]\n", nactualbytes-sieve_bytes, PERC(nactualbytes-sieve_bytes, BBCACHE_SIZE)); fprintf(F, "No: of actual RELOC BBs = %lu\n", nrelocbbs); fprintf(F, "No: of RELOC BBs due to trace = %lu\n", ntrelocbbs); fprintf(F, "No: of actual RELOC BB bytes = %lu\n", nrelocbytes); fprintf(F, "No: of RELOC BB bytes due to trace = %lu\n", ntrelocbytes); fprintf(F, "% RELOC BBs = %0.3f\n", PERC(nrelocbbs, nactualbbs)); fprintf(F, "% Trace RELOC BBs = %0.3f\n", PERC(ntrelocbbs, nactualbbs)); fprintf(F, "% RELOC BB bytes = %0.3f\n", PERC(nrelocbytes, tbytes)); fprintf(F, "% Trace RELOC BB bytes = %0.3f\n", PERC(ntrelocbytes, tbytes)); fprintf(F, "LONGEST BB = %lu instrs [bb# %lu]\n", ilongest_bb_len, ilongest_bb); fprintf(F, "Average Length of BBs = %0.3lf instrs\n", iavg_bb_len); fprintf(F, "SD of BB Length = %0.3lf instrs\n", ibb_sd); fprintf(F, "LONGEST Trace Len = %lu bbs [Starting at bb# %lu]\n", longest_trace_len, longest_trace_start_bb); fprintf(F, "LONGEST Trace Len (instrs) = %lu\n", longest_trace_ilen); fprintf(F, "LONGEST Trace (above) bytes = %lu\n",longest_trace_bytes); fprintf(F, "Average Trace Length = %0.3lf bbs\n", avg_trace); fprintf(F, "Average Trace Length = %0.3lf instrs\n", avg_itrace); fprintf(F, "Average Trace Bytes = %0.3lf \n", avg_trbytes); fprintf(F, "SD Trace Length = %0.3lf bbs\n", sd_trace); fprintf(F, "SD Trace Bytes = %0.3lf \n", sd_trbytes); fprintf(F, "No. of Traces = %lu\n", ntraces); fclose(F); printf("No: of BBs = %lu\n", M->no_of_bbs); printf("No: of Translated BBs = %lu\n", nactualbbs); printf("Total No. of Guest Instrs = %lu\n", ginstrs); printf("Total No. of Trans Instrs = %lu\n", tinstrs); printf("Total No. of Guest Instr Bytes = %lu\n", gbytes); printf("Total No. of Trans Instrs Bytes = %lu\n", tbytes); printf("No. of Bytes used in BBCache = %lu [%0.3f%% of BBCache]\n", nactualbytes, PERC(nactualbytes, BBCACHE_SIZE)); printf("No. of Bytes in sieve-hash-table = %lu\n", sieve_bytes); printf("No. of Bytes ignoring sieve table = %lu [%0.3f%% of BBCache]\n", nactualbytes-sieve_bytes, PERC(nactualbytes-sieve_bytes, BBCACHE_SIZE)); printf("No: of actual RELOC BBs = %lu\n", nrelocbbs); printf("No: of RELOC BBs due to trace = %lu\n", ntrelocbbs); printf("No: of actual RELOC BB bytes = %lu\n", nrelocbytes); printf("No: of RELOC BB bytes due to trace = %lu\n", ntrelocbytes); printf("% RELOC BBs = %0.3f\n", PERC(nrelocbbs, nactualbbs)); printf("% Trace RELOC BBs = %0.3f\n", PERC(ntrelocbbs, nactualbbs)); printf("% RELOC BB bytes = %0.3f\n", PERC(nrelocbytes, tbytes)); printf("% Trace RELOC BB bytes = %0.3f\n", PERC(ntrelocbytes, tbytes)); printf("LONGEST BB = %lu instrs [bb# %lu]\n", ilongest_bb_len, ilongest_bb); printf("Average Length of BBs = %0.3lf instrs\n", iavg_bb_len); printf("SD of BB Length = %0.3lf instrs\n", ibb_sd); printf("LONGEST Trace Len = %lu bbs [Starting at bb# %lu]\n", longest_trace_len, longest_trace_start_bb); printf("LONGEST Trace Len (instrs) = %lu\n", longest_trace_ilen); printf("LONGEST Trace (above) bytes = %lu\n",longest_trace_bytes); printf("Average Trace Length = %0.3lf bbs\n", avg_trace); printf("Average Trace Length = %0.3lf instrs\n", avg_itrace); printf("Average Trace Bytes = %0.3lf \n", avg_trbytes); printf("SD Trace Length = %0.3lf bbs\n", sd_trace); printf("SD Trace Bytes = %0.3lf \n", sd_trbytes); printf("No. of Traces = %lu\n", ntraces); /* Dump longest Trace */ neip = M->next_eip; unsigned long max_tr_instrs = 0;#ifdef STATIC_PASS mneip = M->mem_next_eip;#endif F = fopen("longest_trace", "w"); fprintf(F, "Process: %s\n\n\n", str); fprintf(F, "LONGEST Trace Len = %lu [Starting at bb# %lu]\n", longest_trace_len, longest_trace_start_bb); bb_entry *curr = &M->bb_entry_nodes[longest_trace_start_bb]; unsigned long j; while((curr != NULL) && (curr->trans_bb_eip != NOT_YET_TRANSLATED)) { fprintf(F, "Guest Start = 0x%08lx, End = 0x%08lx, Size = %lu, nInstr = %lu\n", curr->src_bb_eip, curr->src_bb_end_eip, curr->src_bb_end_eip - curr->src_bb_eip, curr->nInstr); M->next_eip = curr->src_bb_eip;#ifdef STATIC_PASS if(update_mem_next_eip(M)) fprintf(F, "OUT");#endif for(j=0; j<curr->nInstr; j++) { do_decode(M, &ds); do_disasm(&ds, F); } max_tr_instrs += curr->nInstr; curr = curr->trace_next; fprintf(F, "\n\n"); } M->next_eip = neip;#ifdef STATIC_PASS M->mem_next_eip = mneip;#endif fprintf(F, "Total No of Instructions = %lu", max_tr_instrs); fclose(F); } #endif //if(debug_flags) { // DBG = fopen("vdbg.dbg", "w"); //}}#ifndef STATIC_PASS#if (defined(PROFILE) || \ defined(PROFILE_RET_MISS) || \ defined(PROFILE_BB_CNT) || \ defined(USE_STATIC_DUMP) || \ defined(PROFILE_BB_STATS) || \ defined(PROFILE_TRANSLATION))#define EXIT_HANDLING_NECESSARY#endif#endif#ifdef THREADED_XLATE machine_t* init_thread_trans(unsigned long program_start); void bb_setup_child_startup(machine_t *M) //[len = 22]{ // This code is similar to Userentry.s // It runs on the clild stack, cals init_thread_trans, // which allocates and initialized the bbCache for this thread. // Then jump into startup-slow-dispatch-bb in that bbCache // pushf already performed by caller. // pusha [len 1b] bb_emit_byte(M, 0x60u); // push $M->next_eip [len 5b] bb_emit_byte(M, 0x68u); bb_emit_w32(M, M->next_eip); // call init_therad_trans [len 5b] bb_emit_call(M, (unsigned char *)(&init_thread_trans)); // esp += 4; leal 4(%esp), %esp [len 7b] bb_emit_byte(M, 0x8du); bb_emit_byte(M, 0xA4u); /* 10 100 100 */ bb_emit_byte(M, 0x24u); /* 00 100 100 */ bb_emit_w32(M, 0x4u); // mov (%eax), %eax [len 2b] bb_emit_byte(M, 0x8bu); /* 8b /r */ bb_emit_byte(M, 0x00u); /* 00 000 000 */ // jmp *%eax [len 2b] bb_emit_byte(M, 0xffu); // ff /4 bb_emit_byte(M, 0xe0u); // 11 100 000}voidexit_unmapper(machine_t *M){ if(!M->ismmaped) return; DEBUG(thread_exit) { fprintf(DBG, "UNMAPPING -- exit()\n"); fflush(DBG); } munmap(M, sizeof(machine_t)); asm volatile ("int $0x80\n\t" : : "a" (__NR_exit) ); /* Not reached */} void execve_unmapper(machine_t *M, fixregs_t regs) { unsigned long retVal; unsigned long next_eip = M->next_eip; unsigned char *Maddr = (unsigned char *)&M; unsigned char *retAddr = Maddr - sizeof(void *); unsigned char *pastM = Maddr + sizeof(void *); DEBUG(thread_exit) { fprintf(DBG, "UNMAPPING -- execve()\n"); fflush(DBG); } munmap(M, sizeof(machine_t)); asm volatile ("pusha\n\t" "mov %2, %%ebx\n\t" "int $0x80\n\t" : "=a" (retVal) : "0" (__NR_execve), "m" (regs.ebx), "c" (regs.ecx), "d" (regs.edx), "S" (regs.esi), "D" (regs.edi) ); //panic("execve() failed\n"); /* If we reach here, execve() must have failed */ //assert(retVal != 0); // Now that we are here, execve() failed for whatever reason // but we *may* have removed the M state; now too late to // find out. So, start anew anyway ... asm volatile ("movl %%eax, %0\n\t" "push %1\n\t" "call init_thread_trans\n\t" "leal 4(%%esp), %%esp\n\t" "mov (%%eax), %%eax\n\t" "movl %%eax, %2\n\t" "popa\n\t" "mov %3, %%esp\n\t" "retl\n\t" : : "m" (regs.eax), "m" (next_eip), "m" (M), "m" (Maddr) ); panic("In function execve_unmapper, \"Unreachable\" code reached\n"); } #endif /* THREADED_XLATE */ static void maskAllSignals(machine_t *M) { //fprintf(stderr, "Masked\n"); sigprocmask(SIG_SETMASK, &allSignals, &M->syscall_sigset); }static void restoreSignals(machine_t *M){ //fprintf(stderr, "UnMasked\n"); sigprocmask(SIG_SETMASK, &M->syscall_sigset, NULL); }#ifdef SIGNALSvoidsignal_syscall_pre(machine_t *M, fixregs_t regs){ // I am yet to see this system call used. size_t signo = regs.ebx; k_sigaction sa; //maskAllSignals(M); sigprocmask(SIG_SETMASK, &allSignals, &M->syscall_sigset); if(regs.ecx == (unsigned long)NULL) { M->ptState->guest_saPtr = NULL; DEBUG(signal_registry) { fprintf(DBG, "PRE: SigNo = %ld, Signal %s {sa=NULL}\n", signo, sig_names[signo]); fflush(DBG); } return; } M->ptState->guest_saPtr = &M->ptState->sa_table[signo].aux; sa.sa_handler = (void *)regs.ecx; sa.sa_flags = SA_ONESHOT | SA_NOMASK; M->ptState->curr_signo = signo; if((sa.sa_handler != NULL) && (sa.sa_handler != SIG_IGN) && (sa.sa_handler != SIG_DFL)) { regs.ecx = (unsigned long) &masterSigHandler; } memcpy(&M->ptState->sa_table[signo].aux, &sa, sizeof(k_sigaction)); *(M->ptState->guestOld_shPtr) = (sighandler_t) regs.edx; M->ptState->curr_signo = signo; DEBUG(signal_registry) { fprintf(DBG, "Pre-SIGNAL SigNo = %ld, Signal %s\n", signo, sig_names[signo]); fflush(DBG); }}voidsignal_syscall_post(machine_t *M, fixregs_t regs){ // I am yet to see this system call used. int saved_errno = errno; size_t signo = M->ptState->curr_signo; int retVal = regs.eax; if(retVal == 0) { if(M->ptState->guestOld_shPtr != NULL) *M->ptState->guestOld_shPtr = (sighandler_t) M->ptState->sa_table[signo].old.sa_handler; if(M->ptState->guest_saPtr != NULL) { memcpy(&M->ptState->sa_table[signo].old, &M->ptState->sa_table[signo].new, sizeof(k_sigaction)); memcpy(&M->ptState->sa_table[signo].new, &M->ptState->sa_table[signo].aux, sizeof(k_sigaction)); } } DEBUG(signal_registry) { fprintf(DBG, "POST: SigNo = %ld, Signal %s : fn = %lx\n", signo, sig_names[signo], M->ptState->sa_table[signo].new.sa_handler); fflush(DBG); } errno = saved_errno; sigprocmask(SIG_SETMASK, &M->syscall_sigset, NULL); //restoreSignals(M);}/* Parameters to sigaction: %eax: syscall no. %ebx: signal no. %ecx: Curent Sigaction structure %edx: Old Sigaction structure */voidsigaction_syscall_pre(machine_t *M, fixregs_t regs){ size_t signo = regs.ebx; k_sigaction *sa = (k_sigaction *)regs.ecx; k_sigaction *old_sa = (k_sigaction *)regs.edx; //maskAllSignals(M); sigprocmask(SIG_SETMASK, &allSignals, &M->syscall_sigset); M->ptState->guestOld_saPtr = old_sa; M->ptState->curr_signo = signo; if(sa == NULL) { M->ptState->guest_saPtr = NULL; DEBUG(signal_registry) { fprintf(DBG, "PRE: SigNo = %ld, Signal %s {sa=NULL}\n", signo, sig_names[signo]); fflush(DBG); } return; } M->ptState->guest_saPtr = sa; memcpy(&M->ptState->sa_table[signo].aux, sa, sizeof(k_sigaction)); if((sa->sa_handler != NULL) && (sa->sa_handler != SIG_IGN) && (sa->sa_handler != SIG_DFL)) { sa->sa_handler = (void (*)(int)) &masterSigHandler; } DEBUG(signal_registry) { fprintf(DBG, "PRE: SigNo = %ld, Signal %s %s\n", signo, sig_names[signo], (sa->sa_flags & SA_ONESHOT)?" {oneshot}":""); fflush(DBG); } }voidsigaction_syscall_post(machine_t *M, fixregs_t regs){ int saved_errno = errno; size_t signo = M->ptState->curr_signo; int retVal = regs.eax; if(retVal == 0) { if(M->ptState->guestOld_saPtr != NULL) { memcpy(M->ptState->guestOld_saPtr, &M->ptState->sa_table[signo].old, sizeof(k_sigaction)); } if(M->ptState->guest_saPtr != NULL) { memcpy(&M->ptState->sa_table[signo].old, &M->ptState->sa_table[signo].new, sizeof(k_sigaction)); memcpy(&M->ptState->sa_table[signo].new, &M->ptState->sa_table[signo].aux, sizeof(k_sigaction)); } } DEBUG(signal_registry) { fprintf(DBG, "POST: SigNo = %ld, Signal %s : fn = %lx\n", signo, sig_names[signo], M->ptState->sa_table[signo].new.sa_handler); fflush(DBG); } errno = saved_errno; //restoreSignals(M); sigprocmask(SIG_SETMASK, &M->syscall_sigset, NULL);}/* Parameters: ebx: new stack ecx: old stack */voidsigaltstack_syscall_pre(machine_t *M, fixregs_t regs){}voidsigaltstack_syscall_post(machine_t *M, fixregs_t regs){} //static register unsigned long curr_esp asm("esp") __attribute_used__;voidsigreturn_syscall(machine_t *M, fixregs_t regs){ unsigned long esp = (unsigned long)&M; esp += sizeof(machine_t *) + sizeof(pushaf_t);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -