static int cmd_x(char *args){ if(args==NULL)return 0; char *args1 =strtok(args," ");///safety int n; sscanf(args1,"%d",&n);///TODO confirm: try to use args here! char *args2=strtok(NULL," "); if(args2==NULL){ args2=args1; n=1; } bool success=true; unsigned int addr = expr_cmd_x(args2 , &success); if(!success){ printf("Invalid expression.\n"); return 0; } //output int i=0; if(addr+n-1 >= (1<<(10+10+3+(27-10-10-3)))){ printf("Physical address 0x%x is outside of the physical memory!\n" , addr); return 0; } printf("0x%x <addr>:\t0x%x\t",addr,swaddr_read(addr,1)); for(i=1;i<n;i++){ if(i%8==0&&i!=0){ printf("\n0x%x <addr+%d>:\t",addr+i,i); } printf("0x%x\t",swaddr_read(addr+i,1)); } printf("\n"); return 0; }
static int cmd_x( char * args ){ char * _num_ = strtok(args, " "); int num = atoi( _num_ ); if( num == 0 ){ printf("Error!\n"); return -1; } char * expr = _num_ + strlen( _num_ ) + 1; int addr; sscanf( expr, "%x", &addr ); printf("0x%08x:\t", addr ); int i = 0; for( ; i < num; i ++ ){ printf("0x"); printf("%02x", swaddr_read(addr + 3, 1) ); printf("%02x", swaddr_read(addr + 2, 1) ); printf("%02x", swaddr_read(addr + 1, 1) ); printf("%02x", swaddr_read(addr , 1) ); printf("\t"); addr += 4; } printf("\n"); return 1; }
static int cmd_bt(char *args) { int i; uint32_t temp_ebp = cpu.ebp; PartOfStackFrame temp; temp.ret_addr = 0; while(temp_ebp != 0) { printf("ebp:%08x\n", temp_ebp); temp.prev_ebp = swaddr_read(temp_ebp, 4); temp.cur_addr = temp.ret_addr? temp.ret_addr: cpu.eip; for(i = 0; i < nr_symtab_entry; i++) { if(temp.cur_addr >= symtab[i].st_value && temp.cur_addr < symtab[i].st_value + symtab[i].st_size) { strcpy(temp.name, (char *)&strtab[symtab[i].st_name]); temp.begin_addr = symtab[i].st_value; } } temp.ret_addr = swaddr_read(temp_ebp + 4, 4); for(i = 0; i < 4; i++) { temp.args[i] = swaddr_read(temp_ebp + 8 + 4*i, 4); } temp_ebp = temp.prev_ebp; printf("0x%08x\t%s(%d, %d, %d, %d)\n", temp.begin_addr, temp.name, temp.args[0], temp.args[1], temp.args[2], temp.args[3]); } return 0; }
void print_bin_instr(swaddr_t eip, int len) { printf("%8x: ", eip); for(int i = 0; i < len; i ++) printf("%02x ", swaddr_read(eip + i, 1)); printf("%*.s", 50 - (12 + 3 * len), ""); }
int read_ModR_M(swaddr_t eip, Operand *rm, Operand *reg) { ModR_M m; m.val = instr_fetch(eip, 1); // Log("m.val = %02x", m.val); reg->type = OP_TYPE_REG; reg->reg = m.reg; if(m.mod == 3) { rm->type = OP_TYPE_REG; rm->reg = m.R_M; switch(rm->size) { case 1: rm->val = reg_b(m.R_M); break; case 2: rm->val = reg_w(m.R_M); break; case 4: rm->val = reg_l(m.R_M); break; default: assert(0); } #ifdef DEBUG switch(rm->size) { case 1: sprintf(rm->str, "%%%s", regsb[m.R_M]); break; case 2: sprintf(rm->str, "%%%s", regsw[m.R_M]); break; case 4: sprintf(rm->str, "%%%s", regsl[m.R_M]); break; } #endif return 1; } else { int instr_len = load_addr(eip, &m, rm); rm->val = swaddr_read(rm->addr, rm->size, R_DS); //TODO DS or SS return instr_len; } }
uint32_t eval(int p, int q, bool *success) { if(p > q) { printf("Bad expression!\n"); *success = false; return 0; } else if(p == q) { uint32_t val; if(tokens[p].type == DINT) sscanf(tokens[p].str, "%d", &val); else if(tokens[p].type == HINT) sscanf(tokens[p].str, "%x", &val); else if(tokens[p].type == REG) val = get_register(tokens[p].str); else if(tokens[p].type == VAR) { Exp_flag = 1; val = find_var(tokens[p].str); if(val == -1) { printf("No var matched!\n"); *success = false; return 0; } } else { printf("No number matched!\n"); *success = false; return 0; } return val; } else if(check_parentheses(p, q, success) == true) { return eval(p + 1, q - 1, success); } else if(*success == true) { int op = find_dominant_operator(p, q); //printf("%d\n", op); int op_type = tokens[op].type; uint32_t val1, val2; if(op_type == NOT || op_type == DEREF) { val1 = eval(op+1, q, success); val2 = eval(op+1, q, success); } else { val1 = eval(p, op-1, success); val2 = eval(op+1, q, success); } switch(op_type) { case '+': return val1 + val2; case '-': return val1 - val2; case '*': return val1 * val2; case '/': return val1 / val2; case EQ: return val1 == val2; case UEQ: return val1 != val2; case AND: return val1 && val2; case OR: return val1 || val2; case NOT: return !val2; case DEREF: return swaddr_read(val2, 4,R_DS); default: *success = false; printf("Cannot evaluate expression!\n"); return 0; } } else { return 0; } }
static int cmd_bt(){ PartOfStackFrame frame[32]; //printf(" 0x%08x \n", cpu.eip); int i = 0; uint32_t ebp = cpu.ebp, eip = cpu.eip; while( ebp != 0 && eip != 0 && i <32 ){ char * func = get_eipFunc(eip); //printf("%s\n", func); printf("#%d 0x%08x in %s ()\n", i, eip, func); frame[i].prev_ebp = swaddr_read(ebp, 4); frame[i].ret_addr = swaddr_read(ebp + 4, 4); ebp = frame[i].prev_ebp; eip = frame[i].ret_addr; i++; } return 0; }
uint32_t swaddr_read_safe(swaddr_t addr , size_t len){ if(addr >= 1<<27){ info_register_overflow_flag = true; return -1; } info_register_overflow_flag = false; return swaddr_read(addr , len); }
void cpu_exec(volatile uint32_t n) { volatile uint32_t n_temp = n; setjmp(jbuf); for(; n > 0; n --) { swaddr_t eip_temp = cpu.eip; BP* current; /*如果触发断点成功且eip-1恰好是int3指令*/ if(isBreak == true && swaddr_read(cpu.eip-1,1) == INT3_CODE) { cpu.eip--; current = ret_head();//返回组织使用中断点的head指针 while(current -> addr != cpu.eip)//找存放相应内存地址的断点结构 current = current -> next; swaddr_write(cpu.eip,1,current -> sav_istr);//临时恢复原来的指令 eip_temp--; } int instr_len = exec(cpu.eip); /*刚执行完恢复的指令要马上设置回断点,使其能反复触发*/ if(isBreak == true && swaddr_read(eip_temp,1) != INT3_CODE)//刚触发断点但断点的位置刚被恢复为原指令 { swaddr_write(eip_temp,1,INT3_CODE); isBreak = false;//告别刚刚触发的那个断点,初始化isBreak,否则执行下一条正常指令也会进入这个判断 } if(!isChange()) isBreak = true; cpu.eip += instr_len; if(n_temp != -1 || (enable_debug && !quiet)) { print_bin_instr(eip_temp, instr_len); puts(assembly); } if(nemu_state == INT) { printf("\n\nUser interrupt\n"); return; } else if(isBreak == true) { return; }//如果因触发断点而停止,回到主循环等待下一条指令 else if(nemu_state == END) { return; } } }
void reset_b() { BP *p=head; while(p!=NULL) { if(p->type == 'b') { if(swaddr_read(p->address,1) != 0) if(swaddr_read(p->address,1) !=0xcc) { p->content = swaddr_read(p->address,1); swaddr_write(p->address,1,0xcc); } } p = p->next; } }
BP* add_bp_pool(uint32_t add){ test(add > 0, "address: 0x%x\n", add); /* FIXME: how to test the correctness of address */ BP* this = alloc_bp(); this->bp_addr = add; this->enabled = true; this->NO = count_of_bp++; this->content = (uint8_t)swaddr_read(add, INT3_CODE_SIZE); return this; }
void enable_all_bp() { BP* current = head; while (current != NULL) { if (current->expr[0] == '\0') { Log("addr = %x, value = %x", current->addr, current->value); current->value = swaddr_read(current->addr, 1); swaddr_write(current->addr, 1, INT3_CODE); } current = current->next; } }
/*设置断点*/ void set_b(unsigned x) { BP* newb = new_bp();//从free中找到一个新的可使用的断点 if(newb == NULL) { assert(0);}//free为空 newb -> b_or_w = true; newb -> addr = x;//储存内存地址 newb -> sav_istr = swaddr_read(x,1);//储存原指令 swaddr_write(x,1,INT3_CODE); newb -> enb = true;//enable newb -> isUsed = true; printf("Breakpoint %d at 0x%x\n",(newb -> NO)+1,x); }
void print_frame_list() { int count=0; psf.prev_ebp=cpu.ebp; psf.ret_addr=cpu.eip; while(psf.prev_ebp!=0)//已處理,判斷eip是否等於0x100000,不是就可以執行 { printf("#%d ",count); count++; in_which_func(psf.ret_addr); psf.ret_addr=swaddr_read(psf.prev_ebp+4,4,2); psf.args[0]=swaddr_read(psf.prev_ebp+4,4,2); psf.args[1]=swaddr_read(psf.prev_ebp+8,4,2); psf.args[2]=swaddr_read(psf.prev_ebp+12,4,2); psf.args[3]=swaddr_read(psf.prev_ebp+16,4,2); psf.prev_ebp=swaddr_read(psf.prev_ebp,4,2); printf("ret_addr\t0x%2x\n",psf.ret_addr); printf("0x%2x\t",psf.args[0]); printf("0x%2x\n",psf.args[1]); printf("0x%2x\t",psf.args[2]); printf("0x%2x\n",psf.args[3]); } }
static int cmd_bt(char *args) { swaddr_t addr = cpu.eip; uint32_t ebp = cpu.ebp; char fun_name[32]; int i, flag, cnt = 0; while(ebp) { flag = 0; get_func_name(fun_name, addr, &flag); if(!flag) { printf("the program haven't start yet.\n"); return 0; } printf("#%d\t0x%x\tin %s()\n", cnt++, addr, fun_name); if(strcmp(fun_name, "main") != 0) addr = swaddr_read(ebp + 4, 4, SR_SS); for(i = 0; i < 4; i ++) { printf("\t0x%08x", swaddr_read(ebp + ((i + 2) << 2), 4, SR_SS)); } printf("\n"); ebp = swaddr_read(ebp, 4, SR_SS); } return 0; }
static int cmd_bt(char *args){ if(args != NULL) printf("(there is no need to input any arguments)\n"); uint32_t tmp = cpu.ebp; uint32_t addr = cpu.eip; char name[32]; int i = 0, j; while(get_fun(addr, name)){ name[31] = '\0'; printf("#%02d %08x in %s(",i++, addr, name); for(j = 2; j < 6; ++j){ if(tmp + j * 4 > 0 && tmp + j * 4 < 0x8000000) printf("%d, ", swaddr_read(tmp + j*4, 4, R_SS)); } if(tmp + j * 4 > 0 && tmp + j * 4 < 0x8000000) printf("%d", swaddr_read(tmp + j * 4, 4, R_SS)); printf(")\n"); addr = swaddr_read(tmp + 4, 4, R_SS); tmp = swaddr_read(tmp, 4, R_SS); } return 0; }
static int cmd_bt(char *args) { swaddr_t prev_ebp=cpu.ebp; swaddr_t ret_addr=swaddr_read(prev_ebp+4, 4, R_SS); //printf("prev_ebp:%x, addr:%x\n",prev_ebp,ret_addr); int count=1; int n=4; char* NowName=fun_name(cpu.eip); if (NowName!=NULL) printf("#0 0x%x in %s(",ret_addr+1,NowName); swaddr_t var_addr=prev_ebp+8; while (n>0) { printf("%d,",swaddr_read(var_addr, 4, R_SS)); var_addr+=4; n--; } printf("\b)\n"); while (prev_ebp!=0){ prev_ebp=swaddr_read(prev_ebp, 4, R_SS); //ret_addr=swaddr_read(prev_ebp+4,4); if (prev_ebp==0) break; printf("#%d 0x%x in ",count++,ret_addr+1); char* FunName=fun_name(ret_addr); if (FunName!=NULL) printf("%s(",FunName); var_addr=prev_ebp+8; n=5; while (n>0) { printf("%d,",swaddr_read(var_addr, 4, R_SS)); var_addr+=4; n--; } printf("\b)\n"); //prev_ebp=swaddr_read(prev_ebp,4); ret_addr=swaddr_read(prev_ebp+4, 4, R_SS); } return 0; }
void watchpoint_start(swaddr_t n){ int m; BP* temp; BP* p; m=swaddr_read(n,1); new_bp(); temp=head; p=head; assert(head!=NULL); while(temp->next!=NULL) temp=temp->next; temp->instr=m; temp->address=n; temp->type=false; head=p; watchpoint_continue(n); }
void breakpoint_preset(){ BP* temp=head; if(head==NULL) return; if(head->type==true){ while(temp!=NULL){ swaddr_write(temp->address,1,0xcc); temp=temp->next; } } else{ while(temp!=NULL){ if(swaddr_read(temp->address,4)!=temp->instr) swaddr_write(temp->address,1,0xcc); temp=temp->next; } } }
static int cmd_x(char *args) { int i; uint32_t j = 0, n = 0, m = 0; bool flag = true; while(args[j]!=' ') { j++; } n = atoi(args); m = expr(args + j + 1, &flag); if(!flag) { printf("not a correct expression.\n"); return 0; } for(i = 0; i < 4 * n; i += 4) { if((i & 15) == 0) printf("\n0x%08x:", m + i); printf(" 0x%08x", swaddr_read(m + i, 4, SR_DS)); } printf("\n"); return 0; }
static int cmd_x(char*args){ char* arg1=strtok(NULL," "); char* arg2=strtok(NULL," "); size_t number1; bool success; size_t number2=expr(arg2,&success); int i; unsigned char*me=NULL; uint32_t data; number1=atoi(arg1); for(i=0;i<number1;i++) { data=swaddr_read(number2,4,R_DS); me=(unsigned char*)(&data); printf("%0x:%02x %02x %02x %02x\n",number2,*me,*(me+1),*(me+2),*(me+3)); number2+=4; } return 0; }
bool check_wp(swaddr_t addr){ if (head==NULL) return false; bool ret=false; bool success=true; uint32_t value; WP *temp; for (temp=head;temp!=free_;temp=temp->next) { value=expr(temp->expr,&success); if (success==true){ if (value!=temp->value) { temp->addr=swaddr_read(addr,1); swaddr_write(addr, 1, 0xcc); temp->stop=true; ret=true; printf("Hit watchpoint: %s\n",temp->expr); } } } return ret; }
/* add new breakpoint in the rear position */ void add_bp(swaddr_t addr) { BP* temp = new_bp(); /* add to the rear */ if (head == NULL) { head = temp; } else { /* travel to the rear */ BP* rear = head; while (rear->next != NULL) rear = rear->next; rear->next = temp; } /* init */ temp->next = NULL; temp->addr = addr; temp->value = swaddr_read(addr, 1); swaddr_write(addr, 1, INT3_CODE); assert(temp->expr[0] == '\0'); }
static int cmd_x(char *args) { size_t ins = 0; swaddr_t addr; while (args && *args && *args == ' ') args++; for (; args && *args && isdigit(*args); args++) { ins = ins * 10 + *args - '0'; } while (args && *args && *args == ' ') args++; if (!args || !*args) { printf("invalid arguments\n"); return 0; } bool success = false; addr = expr(args, &success); if (!success) return 0; while (ins--) { printf("%#x:\t0x%08x\n", addr, swaddr_read(addr, 4, sreg_index(ds))); addr += 4; } return 0; }
static int cmd_x(char *args) { char *arg = strtok(NULL," "); if(arg==NULL) { printf("%s\n","Instruction is not right!"); return 0; } int c=atoi(arg); arg = strtok(NULL," "); int addr=strtod(arg,NULL); printf("addr is %d\n",addr); int i=0; for(;i<c;i++) { uint32_t value=swaddr_read(addr+4*i,4,3); printf("%08x\n",value); } return 0; }
static int cmd_x(char *args) { if (args==NULL){ printf("Arguement required.\n"); return 0; } char *num=strtok(args," "); int n=atoi(num); char *addr=num+strlen(num)+1; //printf("****%s\n",addr); int addr_int; sscanf(addr,"%x",&addr_int); while (n>0) { printf("%x\t",swaddr_read(addr_int, 4, R_DS)); addr_int+=4; //printf("****%d\n",addr_int); n--; } printf("\n"); return 0; }
static int cmd_print_mem(char *args) { char *p; uint32_t i,value,number; bool bb; if (args==NULL) { return 1; } p=strtok(args," "); if (p) { number=atoi(p); p=strtok(NULL," "); if (p) { value=expr(p,&bb);value=(value/4)*4; for(i=0;i<number;i=i+1) { printf(" Mem[%08X]=[%08X]\n",value+4*i,swaddr_read(value+4*i,4)); } } } return 0; }
static void do_ret() { cpu.eip = swaddr_read(cpu.esp, 4); cpu.esp += 4; print_asm("ret"); }
int eval(int p,int q) { int val=0; int j; if(p>q) assert(0); else if(p==q) { char *rec=NULL; char temp[5]; switch(tokens[p].type) { case NUM: return atoi(tokens[p].str);break; case HEX: return strtoll(tokens[p].str,&rec,16);break; case REG: strcpy(temp,tokens[p].str); if(!strcmp(temp,"$eax"))return cpu.eax; else if(!strcmp(temp,"$ecx")) return cpu.ecx; else if(!strcmp(temp,"$edx")) return cpu.edx; else if(!strcmp(temp,"$ebx")) return cpu.ebx; else if(!strcmp(temp,"$esp")) return cpu.esp; else if(!strcmp(temp,"$eip")) return cpu.eip; else if(!strcmp(temp,"$edi")) return cpu.edi; else if(!strcmp(temp,"$esi")) return cpu.esi; else if(!strcmp(temp,"$ebp")) return cpu.ebp; else if(!strcmp(temp,"$al")) return reg_w(R_AX); else if(!strcmp(temp,"$ah")) return reg_w(R_AH); else if(!strcmp(temp,"$bl")) return reg_w(R_BL); else if(!strcmp(temp,"bh")) return reg_w(R_BH); else if(!strcmp(temp,"cl")) return reg_w(R_CL); else if(!strcmp(temp,"ch")) return reg_w(R_CH); else if(!strcmp(temp,"$dl")) return reg_w(R_DL); else if(!strcmp(temp,"$dh")) return reg_w(R_DH); else if(!strcmp(temp,"$eflags")) return cpu.EFLAGS; else if(!strcmp(temp,"$es")) return cpu.es; else if(!strcmp(temp,"$cs")) return cpu.cs; else if(!strcmp(temp,"$ss")) return cpu.ss; else if(!strcmp(temp,"$ds")) return cpu.ds; case TOK: for(j = 0;j < nr_symtab_entry ; j++) { //if(symtab[j].st_info == 0x11) //{ if(!strcmp (&strtab[symtab[j].st_name] , tokens[p].str)) return symtab[j].st_value; //} //else if(symtab[j].st_info == 0x12) //{ // if(!strcmp (&strtab[symtab[j].st_name] , tokens[p].str)) // return symtab[j].st_value; // } } } } else if(check_parentheses(p,q)==true) return eval(p+1,q-1); else { int val1=0; int val2=0; int op=dominate_operate(p,q); if(tokens[op].type==NEG) { if(op!=0) { op--; val1=eval(p,op-1); val2=-eval(op+2,q); } else { val=-eval(op+1,q); } } else if(tokens[op].type==POINTER) { if(op!=0) { op--; val1=eval(p,op-1); val2=swaddr_read(eval(op+2,q),4); } else val=swaddr_read(eval(op+1,q),4); } else if(tokens[op].type==NOT) { if(op!=0) { op--; val1=eval(p,op-1); val2=!eval(op+2,q); } else val=!eval(op+1,q); } else if(tokens[op].type==BIT_NOT) { if(op!=0) { op--; val1=eval(p,op-1); val2=~eval(op+2,q); } else val=~eval(op+1,q); } else { val1=eval(p,op-1); val2=eval(op+1,q); switch(tokens[op].type) { case ADD: val= val1+val2; break; case SUB: val= val1-val2; break; case MUL: val= val1*val2; break; case DIV: if(val2==0) assert(0); else val= val1/val2; break; case RSHIFT: val= val1>>val2; break; case LSHIFT: val= val1<<val2; break; case LS: val= val1<val2; break; case GT: val= val1>val2; break; case GE: val= val1>=val2; break; case LE: val= val1<=val2; break; case NE: val= val1!=val2; break; case EQ: val= val1== val2; break; case BIT_AND: val= val1&val2; break; case BIT_XOR: val= val1^val2; break; case BIT_OR: val= val1|val2; break; case AND: val= val1&&val2; break; case OR: val= val1||val2; break; } } } return val; }
int eval( int p, int q ){ bool legal = true; if( p > q ){ printf("160 Bad expression!\n"); assert(0); } else if( p == q ){ /* Single token. * For now this token should be a number * Return the value of the number */ int val = -256; int i; char * reg_name[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; switch ( tokens[p].type ){ case HEX: sscanf( tokens[p].str, "%x", &val ); break; case DEC: sscanf( tokens[p].str, "%d", &val ); break; case REG: for( i = 0; i < 8; i ++ ){ if( strcmp( tokens[p].str, reg_name[i] ) == 0 ){ val = cpu.gpr[i]._32; break; } } break; case SYM: val = tokens[p].addr; break; default: assert(0); } return val; } else if( check_parentheses( p, q, &legal ) == true ){ /* The expression is surrounded by a matched pair of parentheses * If that is the case, just throw away the paretheneses */ return eval( p + 1, q - 1 ); } else{ /* We should do more things here */ if( legal == false ) { printf("193 Bad expression!\n"); assert(0); } /*===============================================*/ int prior_arr[32]; // find maximum in it int locate[32]; int i, j, num; for( i = q, num = 0; i >= p; i -- ){ if( prior[ tokens[i].type ] > -3 ){ if( tokens[i].type == RPA ){ for( j = i - 1; check_parentheses( j, i, &legal ) == false; j -- ); i = j; } else{ prior_arr[num] = prior[ tokens[i].type ]; locate[num] = i; num ++; } } } for( i = 0, j = 0; i < num; i ++ ){ j = ( prior_arr[i] > prior_arr[j] ) ? i : j; } int op = locate[j]; /*===============================================*/ int val2 = eval( op + 1, q ); switch( tokens[op].type ){ case ADD: return eval( p, op - 1 ) + val2; break; case SUB: return eval( p, op - 1 ) - val2; break; case MUL: return eval( p, op - 1 ) * val2; break; case DIV: return eval( p, op - 1 ) / val2; break; case EQ: return (eval( p, op - 1 ) == val2); break; case NEQ: return (eval( p, op - 1 ) != val2); break; case AND: return (eval( p, op - 1 ) && val2); break; case OR: return (eval( p, op - 1 ) || val2); break; /*===============================================*/ case NOT: return !(val2); break; case NEG: return -1 * val2; break; case PTR: return swaddr_read( val2, 4 ); break; default: assert(0); } } }