uint8_t gen_code(byte code[3], const struct token_inst* tk_inst) { uint8_t code_len; if (NULL == code) return 0; if (PRAGMA_BYTE == tk_inst->op_code) { code_len = 1; } else if (PRAGMA_WORD == tk_inst->op_code) { code_len = 2; } else { code_len = get_inst(tk_inst->op_code)->len; } if (PRAGMA_BYTE == tk_inst->op_code) { code_len = 1; code[0] = tk_inst->lo; } else if (PRAGMA_WORD == tk_inst->op_code) { code_len = 2; code[0] = tk_inst->lo; code[1] = tk_inst->hi; } else { code_len = get_inst(tk_inst->op_code)->len; code[0] = tk_inst->op_code; if (2 <= code_len) code[1] = tk_inst->lo; if (3 <= code_len) code[2] = tk_inst->hi; } return code_len; }
unsigned char is_label(char* token){ int short i = 1; unsigned char res = FALSE; if(isalpha(*token)){ while(i < (strlen(token))){ res = (!isalnum(token[i]) || i == MAX_NAME_LEN) ? FALSE : TRUE; if(res == FALSE){ // Breaks loop once an error is detected if(i == MAX_NAME_LEN){ error_count("ERROR: Label is too long:", token); } return res; } i++; } if(get_inst(token)){ // Labels cannot have instruction names res = FALSE; #ifdef debug printf("LABEL >>%s<< HAS INSTRUCTION NAME\n", token); #endif /* debug */ } if(get_dir(token)){ // Lables cannot have directive names res = FALSE; #ifdef debug printf("LABEL >>%s<< HAS DIRECTIVE NAME\n", token); #endif /* debug */ } } return res; }
static void add_label(Seq_T stream, int location_to_patch, int label_value) { Um_instruction inst = get_inst(stream, location_to_patch); unsigned k = Bitpack_getu(inst, 25, 0); inst = Bitpack_newu(inst, 25, 0, label_value + k); put_inst(stream, location_to_patch, inst); }
/* This function sorts the first token of the record. The first token can be an instruction, a directive or a label. Anything else results in an error, indicated here as type UNKNOWN. It gets called again when the first token is a LABEL to determine the type of the following token. */ struct firsttoken sort(char *token){ struct firsttoken result; struct symbol_entry* entry; result.instptr = NULL; result.dirptr = NULL; result.type = UNKNOWN; if(result.instptr = get_inst(token)){ //Check INST list result.type = INST; return result; } else if(result.dirptr = get_dir(token)){ //Check DIR list result.type = DIR; return result; } else if(is_label(token)){ //Check Label rules result.type = LABEL; if(entry = get_entry(token)){ if(entry->type == REGTYPE){ //Ensures that the "valid" label is result.type = UNKNOWN; //not a register. If it's a reg } //return UNKNOWN to show error. } return result; } else if(*token = ';'){ //For the cases in which the comment result.type = COMMENT; //starts further into the line } return result; //If none of the above return UNKNOWN }
static void format_jmp(const xed_inst_t *xi) { uint32_t dest; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); xed_reg_enum_t reg_id; #ifdef STATISTICS g_symbol_nums++; fprintf(stderr, "jmp at pc\t%x\n", g_pc); g_jmp_num++; #endif INST* inst = get_inst(g_pc); if(inst->type == TAIL){//jmp to plt #ifdef DEBUG fprintf(stdout, "TAIL:\t%p\n", inst); #endif sprintf(inst_buffer, "%s %s", "jmp", inst->api_call.fname); return; } if(operand_is_relbr(op_name, &dest)){ dest += g_pc + xed_decoded_inst_get_length(&xedd_g); sprintf(inst_buffer, "%s L_0x%x", "jmp", dest); }else{ fprintf(stderr, "error in format_jmp\n"); } }
static void format_direct_call(const xed_inst_t *xi) { uint32_t dest; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); xed_reg_enum_t reg_id; #ifdef STATISTICS fprintf(stderr, "call at pc\t%x\n", g_pc); g_symbol_nums++; g_call_num++; #endif INST* inst = get_inst(g_pc); if(operand_is_relbr(op_name, &dest)){ if(inst->api_call.fname){ if(inst->api_call.type == API_IMP) sprintf(inst_buffer, "call %s", inst->api_call.fname); else sprintf(inst_buffer, "call dword ptr %s", inst->api_call.fname); return; } dest += g_pc + xed_decoded_inst_get_length(&xedd_g); sprintf(inst_buffer, "call func_0x%x", dest); }else{ fprintf(stderr, "error in format_jmp\n"); } }
static int format_jcc(const xed_inst_t *xi) { uint32_t dest, next; char opcode[20], jmp_dst[20]; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); xed_reg_enum_t reg_id; strcpy(opcode, xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(&xedd_g))); INST* inst = get_inst(g_pc); if(operand_is_relbr(op_name, &dest)){ next = g_pc + xed_decoded_inst_get_length(&xedd_g); dest += next;//TODO: handle two branch #ifdef DEBUG fprintf(stdout, "format:%x\t%s\n", g_pc, g_inst_str); #endif #ifdef STATISTICS g_symbol_nums++; g_jcc_num++; #endif if(get_inst(dest)) sprintf(inst_buffer, "%s L_0x%x", opcode, dest); else{ sprintf(inst_buffer, "%s L_ERROR_0x%x", opcode, g_current_func->begin()->first); #ifdef STATISTICS g_check_nums += 1; fprintf(stderr, "check at pc\t%x\n", g_pc); #endif } if(get_inst(next)) memset(safety_guard, 0, sizeof(safety_guard)); else{ sprintf(safety_guard, "jmp L_ERROR_0x%x", g_current_func->begin()->first); #ifdef STATISTICS fprintf(stderr, "check at pc\t%x\n", g_pc); g_check_nums += 1; #endif } }else{ fprintf(stderr, "error in format_jcc\n"); } }
int has_effect(lua_State* L) { CombatGameInst* combatinst; if ((combatinst = dynamic_cast<CombatGameInst*>(get_inst()))) { lua_pushboolean(L, combatinst->effects().get(effect_from_lua(L, 1)) != NULL); } else { lua_pushnil(L); } return 1; }
int add_effect(lua_State* L) { CombatGameInst* combatinst; if ((combatinst = dynamic_cast<CombatGameInst*>(get_inst()))) { LuaValue effect = combatinst->effects().add(lua_get_gamestate(L), combatinst, effect_from_lua(L, 1), lua_tointeger(L, 2)); effect.push(L); } else { lua_pushnil(L); } return 1; }
int equip(lua_State* L) { CombatGameInst* combatinst; if ((combatinst = dynamic_cast<CombatGameInst*>(get_inst()))) { int args = lua_gettop(L); lua_pushstring(L, "name"); lua_gettable(L, 1); const char* itemname = lua_tostring(L, lua_gettop(L)); item_id item = get_item_by_name(itemname); int amnt = args >= 2 ? lua_tointeger(L, 2) : 1; combatinst->equip(item, amnt); lua_pop(L, 1); } return 0; }
int do_unaligned_access(unsigned long addr, struct pt_regs *regs) { unsigned long inst; int ret = -EFAULT; mm_segment_t seg = get_fs(); inst = get_inst(regs->ipc); DEBUG((unalign_access_debug > 0), 1, "Faulting addr: 0x%08lx, pc: 0x%08lx [inst: 0x%08lx ]\n", addr, regs->ipc, inst); set_fs(USER_DS); if (inst & NDS32_16BIT_INSTRUCTION) ret = do_16((inst >> 16) & 0xffff, regs); else
static void format_lea(const xed_inst_t *xi) { char r_str[50]; INST *inst = get_inst(g_pc); switch(inst->type){ case LEA_8: fprintf(stderr, "error in format_lea: lea_8\n"); exit(0); case LEA_16: fprintf(stderr, "error in format_lea: lea_16\n"); exit(0); case LEA_32: sprintf(r_str, "dword ptr"); break; } #ifdef WINDOWS_FORMAT strcpy(inst_buffer, replace(g_inst_str, "ptr", r_str)); #else format_reg(inst_buffer, g_inst_str); #endif }
CombatGameInst* get_combat_inst() { CombatGameInst* combat_inst = dynamic_cast<CombatGameInst*>(get_inst()); return combat_inst; }
static void Instrument_CALL(const xed_inst_t* xi) { #ifdef DEBUG fprintf(stdout, "txt:instrument_call\n"); #endif xed_reg_enum_t reg_id; unsigned int dest = 0, taint = 0; uint32_t buf; char *fname; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); API_TYPE type; INST *inst; if(operand_is_mem4(op_name, &dest, 0)){ int mem_idx = op_name == XED_OPERAND_MEM1 ? 1 : 0; xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd_g, mem_idx); PEMU_read_mem(dest, 4, &buf); dest = buf; if(taint = t_get_reg_taint(base_regid)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call1\n"); #endif if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } }else if(taint = t_get_mem_taint(dest)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call2\n"); #endif if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } } return; }else if(operand_is_reg(op_name, ®_id)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call3\n"); #endif if(taint = t_get_reg_taint(reg_id)){ insert_pc_addr(taint, 2); dest = PEMU_get_reg(reg_id); if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } } return; }else if(operand_is_relbr(op_name, &dest)){ dest += (g_pc + xed_decoded_inst_get_length(&xedd_g)); if(type = is_api_call(dest, &fname)){ #ifdef DEBUG fprintf(stdout, "is_api_call\t%x\t%x\n", dest, type); #endif goto REST; } return; } API_CALL: inst = get_inst(taint); // api_copy(&inst->api_call, get_api_call(dest)); REST: #ifdef DEBUG fprintf(stdout, "taint:\t%x\t%x\n", taint, dest); #endif t_set_reg_taint(XED_REG_EAX, 0); handle_api_issues(get_api_call(dest), 0); }
void rep_process_signal(struct context *ctx) { struct trace* trace = &(ctx->trace); int tid = ctx->child_tid; int sig = -trace->stop_reason; /* if the there is still a signal pending here, two signals in a row must be delivered?\n */ assert(ctx->child_sig == 0); switch (sig) { /* set the eax and edx register to the recorded values */ case -SIG_SEGV_RDTSC: { struct user_regs_struct regs; int size; /* goto the event */ goto_next_event(ctx); /* make sure we are there */ assert(WSTOPSIG(ctx->status) == SIGSEGV); char* inst = get_inst(tid, 0, &size); assert(strncmp(inst,"rdtsc",5) == 0); read_child_registers(tid, ®s); regs.eax = trace->recorded_regs.eax; regs.edx = trace->recorded_regs.edx; regs.eip += size; write_child_registers(tid, ®s); sys_free((void**) &inst); compare_register_files("rdtsv_now", ®s, "rdsc_rec", &ctx->trace.recorded_regs, 1, 1); /* this signal should not be recognized by the application */ ctx->child_sig = 0; break; } case -USR_SCHED: { assert(trace->rbc_up > 0); /* if the current architecture over-counts the event in question, * substract the overcount here */ reset_hpc(ctx, trace->rbc_up - SKID_SIZE); goto_next_event(ctx); /* make sure that the signal came from hpc */ if (fcntl(ctx->hpc->rbc_down.fd, F_GETOWN) == ctx->child_tid) { /* this signal should not be recognized by the application */ ctx->child_sig = 0; stop_hpc_down(ctx); compensate_branch_count(ctx, sig); stop_hpc(ctx); } else { fprintf(stderr, "internal error: next event should be: %d but it is: %d -- bailing out\n", -USR_SCHED, ctx->event); sys_exit(); } break; } case SIGIO: case SIGCHLD: { /* synchronous signal (signal received in a system call) */ if (trace->rbc_up == 0) { ctx->replay_sig = sig; return; } // setup and start replay counters reset_hpc(ctx, trace->rbc_up - SKID_SIZE); /* single-step if the number of instructions to the next event is "small" */ if (trace->rbc_up <= 10000) { stop_hpc_down(ctx); compensate_branch_count(ctx, sig); stop_hpc(ctx); } else { printf("large count\n"); sys_ptrace_syscall(tid); sys_waitpid(tid, &ctx->status); // make sure we ere interrupted by ptrace assert(WSTOPSIG(ctx->status) == SIGIO); /* reset the penig sig, since it did not occur in the original execution */ ctx->child_sig = 0; ctx->status = 0; //DO NOT FORGET TO STOP HPC!!! compensate_branch_count(ctx, sig); stop_hpc(ctx); stop_hpc_down(ctx); } break; } case SIGSEGV: { /* synchronous signal (signal received in a system call) */ if (trace->rbc_up == 0 && trace->page_faults == 0) { ctx->replay_sig = sig; return; } sys_ptrace_syscall(ctx->child_tid); sys_waitpid(ctx->child_tid, &ctx->status); assert(WSTOPSIG(ctx->status) == SIGSEGV); struct user_regs_struct regs; read_child_registers(ctx->child_tid, ®s); assert(compare_register_files("now", ®s, "rec", &ctx->trace.recorded_regs, 1, 1) == 0); /* deliver the signal */ singlestep(ctx, SIGSEGV, 0x57f); break; } default: printf("unknown signal %d -- bailing out\n", sig); sys_exit(); break; } }