void dump_scopetable_entry (struct MemoryCache *mc, struct process *p, int i, address a) { bool b; struct my_SCOPETABLE_ENTRY e; b=MC_ReadBuffer (mc, a, sizeof(struct my_SCOPETABLE_ENTRY), (BYTE*)&e); if (b==false) { L ("%s() cannot read scopetable entry\n", __FUNCTION__); return; }; strbuf sb2=STRBUF_INIT; process_get_sym (p, e.handler, true /* add_module_name */, true /* add_offset */, &sb2); if (e.filter) { strbuf sb1=STRBUF_INIT; process_get_sym (p, e.filter, true /* add_module_name */, true /* add_offset */, &sb1); L ("scopetable entry[%d]. previous try level=%d, filter=0x" PRI_ADR_HEX " (%s) handler=0x" PRI_ADR_HEX " (%s)\n", i, e.previousTryLevel, e.filter, sb1.buf, e.handler, sb2.buf); strbuf_deinit(&sb1); } else L ("scopetable entry[%d]. previous try level=%d, finally=0x" PRI_ADR_HEX " (%s)\n", i, e.previousTryLevel, e.handler, sb2.buf); strbuf_deinit(&sb2); };
void dump_buf_as_array_of_strings(MemoryCache *mc, address a, size_t size) { strbuf sb=STRBUF_INIT; BYTE *buf=DMALLOC (BYTE, size, "BYTE*"); if (MC_ReadBuffer (mc, a, size, buf)==false) goto exit; for (unsigned i=0; i<size; i+=sizeof(REG)) { address a2=*(REG*)&buf[i]; if (MC_get_any_string(mc, a2, &sb)) { L ("0x" PRI_ADR_HEX "+0x%x: ptr to %s\n", a, i, sb.buf); strbuf_reinit(&sb, 0); }; }; exit: DFREE (buf); strbuf_deinit(&sb); };
Da_emulate_result Da_emulate(Da* d, CONTEXT * ctx, MemoryCache *mem, bool emulate_FS_accesses, address FS) { #ifdef _WIN64 return DA_NOT_EMULATED; #endif //bool SF=IS_SET(ctx->EFlags, FLAG_SF); //bool OF=IS_SET(ctx->EFlags, FLAG_OF); //bool ZF=IS_SET(ctx->EFlags, FLAG_ZF); bool CF=IS_SET(ctx->EFlags, FLAG_CF); bool b; if (x86_emu_debug) { // FIXME: write to log also? L ("%s() begin: [", __func__); Da_DumpString(&cur_fds, d); L ("]\n"); }; if ((emulate_FS_accesses==false && IS_SET(d->prefix_codes, PREFIX_FS)) || (IS_SET(d->prefix_codes, PREFIX_SS) || IS_SET(d->prefix_codes, PREFIX_GS))) { if (x86_emu_debug) L ("%s() skipping (data selector prefix present) at 0x" PRI_ADR_HEX "\n", __func__, CONTEXT_get_PC(ctx)); return DA_EMULATED_CANNOT_READ_MEMORY; }; switch (d->ins_code) { case I_CDQ: { uint32_t a=CONTEXT_get_Accum (ctx)&0xFFFFFFFF; CONTEXT_set_xDX (ctx, (a&0x80000000) ? 0xFFFFFFFF : 0); goto add_to_PC_and_return_OK; }; break; case I_PUSH: { address rt_adr; obj v; b=Da_op_get_value_of_op (&d->op[0], &rt_adr, ctx, mem, __FILE__, __LINE__, &v, d->prefix_codes, FS); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't read memory\n", __func__); return DA_EMULATED_CANNOT_READ_MEMORY; }; b=DO_PUSH (ctx, mem, obj_get_as_REG(&v)); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; break; case I_PUSHFD: if (DO_PUSH (ctx, mem, ctx->EFlags | FLAG_TF)==false) { if (x86_emu_debug) L ("%s() I_PUSHFD: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; break; case I_POP: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj v; obj_tetrabyte2 (val, &v); Da_op_set_value_of_op (&d->op[0], &v, ctx, mem, d->prefix_codes, FS); goto add_to_PC_and_return_OK; }; break; case I_POPFD: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; ctx->EFlags=val; goto add_to_PC_and_return_OK; }; break; case I_LEAVE: { //ESP <- EBP //POP EBP REG val; CONTEXT_set_SP(ctx, CONTEXT_get_BP(ctx)); if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; // FIXME: а надо еще SP назад возвращать! CONTEXT_set_BP(ctx, val); goto add_to_PC_and_return_OK; }; break; case I_REP_STOSB: case I_REP_STOSW: case I_REP_STOSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; if (d->ins_code==I_REP_STOSB) BUF_SIZE=CONTEXT_get_xCX (ctx); else if (d->ins_code==I_REP_STOSW) BUF_SIZE=CONTEXT_get_xCX (ctx)*2; else if (d->ins_code==I_REP_STOSD) BUF_SIZE=CONTEXT_get_xCX (ctx)*4; buf=DMALLOC(BYTE, BUF_SIZE, "buf"); if (d->ins_code==I_REP_STOSB) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! buf[i]=CONTEXT_get_Accum(ctx)&0xFF; } else if (d->ins_code==I_REP_STOSW) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((WORD*)buf)[i]=CONTEXT_get_Accum(ctx)&0xFFFF; } else if (d->ins_code==I_REP_STOSD) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((DWORD*)buf)[i]=(DWORD)(CONTEXT_get_Accum(ctx)&0xFFFFFFFF); } else { oassert(0); }; if (MC_WriteBuffer (mem, CONTEXT_get_xDI (ctx), BUF_SIZE, buf)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; DFREE(buf); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); CONTEXT_set_xCX (ctx, 0); goto add_to_PC_and_return_OK; }; break; case I_REP_MOVSB: case I_REP_MOVSW: case I_REP_MOVSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; SIZE_T sizeof_element; if (d->ins_code==I_REP_MOVSB) sizeof_element=1; else if (d->ins_code==I_REP_MOVSW) sizeof_element=2; else if (d->ins_code==I_REP_MOVSD) sizeof_element=4; else { oassert(0); }; BUF_SIZE=CONTEXT_get_xCX(ctx)*sizeof_element; //printf ("%s() BUF_SIZE=0x%x\n", __func__, BUF_SIZE); //printf ("%s() (before) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (before) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); buf=DMALLOC(BYTE, BUF_SIZE, "buf"); address blk_src=CONTEXT_get_xSI(ctx); address blk_dst=CONTEXT_get_xDI(ctx); if (DF) { blk_src-=BUF_SIZE; // +sizeof_element; blk_dst-=BUF_SIZE; // +sizeof_element; }; if (MC_ReadBuffer (mem, blk_src, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_READ_MEMORY; }; if (MC_WriteBuffer (mem, blk_dst, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; DFREE(buf); if (DF==false) { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) + BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); } else { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) - BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) - BUF_SIZE); }; CONTEXT_set_xCX (ctx, 0); //printf ("%s() (after) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (after) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); goto add_to_PC_and_return_OK; }; case I_STD: SET_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_CLD: REMOVE_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_RETN: { WORD ret_arg=0; if (d->ops_total==1) { oassert (d->op[0].type==DA_OP_TYPE_VALUE); ret_arg=obj_get_as_wyde(&d->op[0].val._v); // RETN arg is 16-bit }; address newPC; if (DO_POP(ctx, mem, &newPC)==false) return DA_EMULATED_CANNOT_READ_MEMORY; CONTEXT_set_SP(ctx, CONTEXT_get_SP(ctx)+ret_arg); CONTEXT_set_PC(ctx, newPC); return DA_EMULATED_OK; }; break; case I_ADD: case I_ADC: case I_INC: { //L (__FUNCTION__ "() I_ADD/I_INC begin: [%s]\n", ToString().c_str()); obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_ADD || d->ins_code==I_ADC) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; } else { // INC case // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); }; obj res_sum; obj_add (&rt1, &rt2, &res_sum); if (d->ins_code==I_ADC && CF) obj_increment(&res_sum); set_PF (ctx, &res_sum); set_SF (ctx, &res_sum); set_ZF (ctx, &res_sum); set_AF (ctx, &rt1, &rt2, &res_sum); if (d->ins_code==I_ADD || d->ins_code==I_ADC) set_or_clear_flag (ctx, FLAG_CF, obj_compare (&res_sum, &rt1)==-1); // res_sum < rt1 octabyte tmp=((zero_extend_to_REG(&rt1) ^ zero_extend_to_REG(&rt2) ^ get_sign_bit (d->op[0].value_width_in_bits)) & (zero_extend_to_REG(&res_sum) ^ zero_extend_to_REG(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); b=Da_op_set_value_of_op (&d->op[0], &res_sum, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_NOT: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NOT(&rt1, &res); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_NEG: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NEG(&rt1, &res); set_or_clear_flag (ctx, FLAG_CF, obj_is_zero(&rt1)==false); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_or_clear_flag (ctx, FLAG_AF, (0 ^ obj_get_4th_bit(&rt1)) ^ obj_get_4th_bit(&res)); REMOVE_BIT (ctx->EFlags, FLAG_OF); //SET_BIT (ctx->EFlags, FLAG_AF); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_OR: case I_XOR: case I_AND: case I_TEST: { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); obj rt1, rt2, res; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; switch (d->ins_code) { case I_OR: obj_OR(&rt1, &rt2, &res); break; case I_XOR: obj_XOR(&rt1, &rt2, &res); break; case I_TEST: case I_AND: obj_AND(&rt1, &rt2, &res); break; default: oassert(0); break; }; set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); REMOVE_BIT (ctx->EFlags, FLAG_AF); REMOVE_BIT (ctx->EFlags, FLAG_CF); REMOVE_BIT (ctx->EFlags, FLAG_OF); if (d->ins_code==I_TEST) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_DEC: case I_SUB: case I_SBB: case I_CMP: { if (d->ins_code==I_SUB || d->ins_code==I_SBB || d->ins_code==I_CMP) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); }; obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_DEC) { // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); } else { b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; }; obj res; obj_subtract (&rt1, &rt2, &res); if (d->ins_code==I_SBB && CF) obj_decrement (&res); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_AF (ctx, &rt1, &rt2, &res); if (d->ins_code==I_SBB) { int tmp=(obj_compare (&rt1, &res)==-1 /* rt1<res */) || (CF && obj_get_as_tetrabyte(&rt2)==0xffffffff); set_or_clear_flag (ctx, FLAG_CF, tmp); } else { if (d->ins_code!=I_DEC) // DEC leave CF flag unaffected set_or_clear_flag (ctx, FLAG_CF, obj_compare (&rt1, &rt2)==-1); /* rt1<rt2 */ }; octabyte tmp=((zero_extend_to_octabyte(&rt1) ^ zero_extend_to_octabyte(&rt2)) & (zero_extend_to_octabyte(&res) ^ zero_extend_to_octabyte(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); if (d->ins_code==I_CMP) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_XCHG: { REG op1_adr, op2_adr; obj op1; b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (Da_op_set_value_of_op (&d->op[0], &op2, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; if (Da_op_set_value_of_op (&d->op[1], &op1, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_MOV: case I_MOVDQA: case I_MOVDQU: return Da_emulate_MOV_op1_op2(d, ctx, mem, d->prefix_codes, FS); case I_MOVZX: case I_MOVSX: { address rt_adr; obj op2; bool b=Da_op_get_value_of_op(&d->op[1], &rt_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf (__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't read src (2nd) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; obj to_be_stored_v; if (d->ins_code==I_MOVZX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_zero_extend (&op2, op1_type_will_be, &to_be_stored_v); } else if (d->ins_code==I_MOVSX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_sign_extend (&op2, op1_type_will_be, &to_be_stored_v); } else { oassert (0); }; b=Da_op_set_value_of_op (&d->op[0], &to_be_stored_v, ctx, mem, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf(__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't write dst (1st) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; case I_NOP: goto add_to_PC_and_return_OK; case I_LEA: { address a=(address)Da_op_calc_adr_of_op(&d->op[1], ctx, mem, d->prefix_codes, FS); obj val; obj_tetrabyte2(a, &val); b=Da_op_set_value_of_op (&d->op[0], &val, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; case I_SAR: case I_SHR: case I_SHL: { // http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH06/CH06-3.html REG op1_adr, op2_adr; obj op1; bool b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; // should be read anyway! obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; #ifdef _WIN64 obj_AND_with (&op2, 0x3F); #else obj_AND_with (&op2, 0x1F); #endif if (obj_is_zero(&op2)==false) { unsigned new_CF; if (d->ins_code==I_SHR || d->ins_code==I_SAR) new_CF=(zero_extend_to_octabyte(&op1) >> (obj_get_as_byte (&op2) - 1)) & 1; else // SHL new_CF=(zero_extend_to_octabyte(&op1) >> (obj_width_in_bits(&op1) - obj_get_as_byte (&op2))) & 1; obj new_op1; if (d->ins_code==I_SHR) { REG new_v=zero_extend_to_REG(&op1) >> obj_get_as_byte (&op2); obj_REG2_and_set_type(op1.t, new_v, 0, &new_op1); } else if (d->ins_code==I_SAR)
// returns address of next SEH frame address dump_SEH_frame (fds* s, struct process* p, struct thread* t, struct MemoryCache *mc, address a) { struct my_EXCEPTION_REGISTRATION current_SEH_frame; bool b; b=MC_ReadBuffer (mc, a, sizeof(struct my_EXCEPTION_REGISTRATION), (BYTE*)¤t_SEH_frame); if (b==false) { L ("%s() cannot read current SEH frame\n", __FUNCTION__); return REG_MAX; }; strbuf sb=STRBUF_INIT; process_get_sym (p, current_SEH_frame.handler, true /* add_module_name */, true /* add_offset */, &sb); L ("* SEH frame at 0x" PRI_ADR_HEX " prev=0x" PRI_ADR_HEX " handler=0x" PRI_ADR_HEX " (%s)\n", a, current_SEH_frame.prev, current_SEH_frame.handler, sb.buf); bool SEH3=false, SEH4=false; if (string_is_ends_with (sb.buf, "except_handler3")) SEH3=true; REG security_cookie; bool security_cookie_known=false; if (string_is_ends_with (sb.buf, "except_handler4")) { SEH4=true; struct module *m=find_module_for_address(p, current_SEH_frame.handler); if (m->security_cookie_adr_known) { b=MC_ReadREG (mc, m->security_cookie_adr, &security_cookie); if (b==false) L ("%s() can't read security_cookie at 0x" PRI_ADR_HEX " for %s\n", __FUNCTION__, m->security_cookie_adr, get_module_name (m)); else security_cookie_known=true; } else { L ("SEH4 frame is here, but address of security_cookie is not known\n"); L ("Try to place .PDB or .MAP file here with this symbol in it\n"); }; }; if (SEH3==false && SEH4==false) goto exit; struct my_VC_EXCEPTION_REGISTRATION_RECORD current_SEH3_frame; b=MC_ReadBuffer (mc, a, sizeof(struct my_VC_EXCEPTION_REGISTRATION_RECORD), (BYTE*)¤t_SEH3_frame); if (b==false) { L ("%s() cannot read current SEH3/4 frame\n", __FUNCTION__); return REG_MAX; }; int previous_trylevel=current_SEH3_frame.previous_trylevel; L ("SEH%d frame. previous trylevel=%d\n", SEH3 ? 3 : 4, previous_trylevel); address scopetable_address=current_SEH3_frame.scopetable; if (SEH4 && security_cookie_known) { scopetable_address^=security_cookie; struct my_EH4_SCOPETABLE_HEADER EH4_header; b=MC_ReadBuffer (mc, scopetable_address, sizeof(struct my_EH4_SCOPETABLE_HEADER), (BYTE*)&EH4_header); if (b==false) { L ("%s() cannot read current SEH4 frame header. scopetable_address=0x" PRI_ADR_HEX "\n", __FUNCTION__, scopetable_address); return REG_MAX; }; L ("SEH4 header:\tGSCookieOffset=0x%x GSCookieXOROffset=0x%x\n", EH4_header.GSCookieOffset, EH4_header.GSCookieXOROffset); L ("\t\tEHCookieOffset=0x%x EHCookieXOROffset=0x%x\n", EH4_header.EHCookieOffset, EH4_header.EHCookieXOROffset); unsigned adr_of_EBP=a + ((byte*)¤t_SEH3_frame.EBP - (byte*)¤t_SEH3_frame.prev); if (EH4_header.EHCookieOffset!=-2) check_SEH4_cookie (mc, adr_of_EBP, EH4_header.EHCookieOffset, EH4_header.EHCookieXOROffset, security_cookie, "EH"); if (EH4_header.GSCookieOffset!=-2) check_SEH4_cookie (mc, adr_of_EBP, EH4_header.GSCookieOffset, EH4_header.GSCookieXOROffset, security_cookie, "GS"); scopetable_address+=sizeof(struct my_EH4_SCOPETABLE_HEADER); }; if (previous_trylevel>=0 && (SEH3 || (SEH4 && security_cookie_known))) dump_scopetable(mc, p, scopetable_address, previous_trylevel+1); exit: strbuf_deinit (&sb); return current_SEH_frame.prev; };
bool Da_op_get_value_of_op (struct Da_op *op, address * rt_adr, const CONTEXT * ctx, struct MemoryCache *mem, const char *fname, unsigned fileline, obj *result, unsigned ins_prefixes, address FS) { bool b; if (op->type==DA_OP_TYPE_REGISTER) { oassert (op->reg != R_ABSENT); // get from ctx X86_register_get_value (op->reg, ctx, result); return true; }; if (op->type==DA_OP_TYPE_VALUE) { obj_copy2 (result, &op->val._v); return true; }; if (op->type==DA_OP_TYPE_VALUE_IN_MEMORY) { *rt_adr=(REG)Da_op_calc_adr_of_op (op, ctx, mem, ins_prefixes, FS); //if ((*rt_adr)&(~0x7fffff0f000) == 0x7fffffd0000+2) if(0) { printf ("%s() line %d adr=0x"PRI_REG_HEX"\n", __FUNCTION__, __LINE__, *rt_adr); }; switch (op->value_width_in_bits) { case 8: { BYTE out; b=MC_ReadByte (mem, *rt_adr, &out); if (b) { obj_byte2((uint8_t)out, result); return true; } else return false; }; case 16: { WORD out; b=MC_ReadWyde (mem, *rt_adr, &out); if (b) { obj_wyde2((uint16_t)out, result); return true; } else return false; }; case 32: { DWORD out; b=MC_ReadTetrabyte (mem, *rt_adr, &out); if (b) { obj_tetra2((uint32_t)out, result); return true; } else return false; }; case 64: { DWORD64 out; b=MC_ReadOctabyte (mem, *rt_adr, &out); if (b) { obj_octa2((uint64_t)out, result); return true; } else return false; }; case 128: { M128A xmm; if (MC_ReadBuffer (mem, *rt_adr, sizeof (M128A), (BYTE*)&xmm)==false) return false; obj_xmm2 ((uint8_t*)&xmm, result); return true; }; default: oassert(!"unknown value_width_in_bits"); fatal_error(); break; }; oassert(0); }; #if 0 L ("%s(): type=%d!\n", __FUNCTION__, type); #endif oassert(0); // should not be here fatal_error(); };