unsigned char * get_request_proxy(size_t * len) { mute(); unsigned char * ret = get_request(len); unmute(); stack_ptr("get_request"); StoreBuf(&ret); readenv(ret, len, "request"); return ret; }
unsigned char * get_shared_key_proxy(size_t * len) { mute(); unsigned char * ret = get_shared_key(len); unmute(); stack_ptr("get_key"); StoreBuf(&ret); readenv(ret, len, "keyAB"); return ret; }
unsigned char * get_payload_proxy(size_t * len) { mute(); unsigned char * ret = get_payload(len); unmute(); // CR: use getenv stack_ptr("get_payload"); StoreBuf(&ret); readenv(ret, len, "payload"); return ret; }
int cpu_adjust(cpu_core_t *this_cpu, cpu_trap_t *tp, struct pt_regs *regs) { uchar_t *pc = tp->ct_instr_buf; greg_t *sp; pc = cpu_skip_prefix(pc); /* Just some debug to watch flag changes... if ((regs->r_rfl & X86_EFLAGS_IF) != (tp->ct_eflags & X86_EFLAGS_IF)) { printk("flag change: %p: %02x : %02x %02x %02x %lx %lx\n", tp->ct_orig_pc0, tp->ct_orig_pc0[0], *pc, tp->ct_orig_pc0[1], tp->ct_orig_pc0[2], regs->r_rfl, tp->ct_eflags); } */ /***********************************************/ /* For some instructions, we need to be */ /* careful of the IF/TF flags. So, do these */ /* first. */ /***********************************************/ switch (*pc) { case 0x9c: // pushfl /***********************************************/ /* If we push flags, we have two copies on */ /* the stack - the one for the instruction, */ /* and the one for pt_regs we pushed on the */ /* stack as part of the trap handler. */ /* Update the invokers flags, since ours */ /* are useless at this point (or, that they */ /* need to agree). */ /* We just pushed the flags, but those */ /* flags would contain the TF bit set, so */ /* we must turn that off. Also, dont touch */ /* the IF bit - that stays as whatever the */ /* original code had it. If we attempt to */ /* execute the switch-statement below, then */ /* we would turn off IF, and hit the */ /* infamous "BUG_ON/WARN_ONCE" errors */ /* complaining that a caller may sleep */ /* because interrupts are disabled. */ /***********************************************/ {greg_t *fl = (greg_t *) regs->r_sp; regs->r_rfl &= ~X86_EFLAGS_TF; /***********************************************/ /* Put back the original flags at the point */ /* we were going to breakpoint. */ /***********************************************/ *fl = tp->ct_eflags; regs->r_pc = (greg_t) tp->ct_orig_pc; return FALSE; } case 0x9d: // popf /***********************************************/ /* Very rare - a "subroutine" starting by */ /* popping the flags. e.g. "not_same". */ /* Really limited to just assembler/trap */ /* handler code. Believe whatever this */ /* instruction has done to the flags. */ /***********************************************/ regs->r_pc = (greg_t) tp->ct_orig_pc; return FALSE; case 0xcf: { //iret // greg_t *flp = (greg_t *) (®s->r_rfl + 3 * sizeof(greg_t)); //dtrace_printf("iret rfl=%p\n", regs->r_rfl); regs->r_rfl = (regs->r_rfl & ~(X86_EFLAGS_TF)); // *flp = (*flp & ~X86_EFLAGS_IF) | X86_EFLAGS_TF; return FALSE; } } /***********************************************/ /* Put back the IF flag the way it was */ /* before we turned off interrupts for the */ /* single step. Also, turn off the TF flag */ /* because we will have finished single */ /* stepping. */ /***********************************************/ regs->r_rfl = (regs->r_rfl & ~(X86_EFLAGS_TF|X86_EFLAGS_IF)) | (tp->ct_eflags & (X86_EFLAGS_IF)); #define SEE_ABOVE(opcode, text) #define SEE_BELOW(opcode, text) switch (*pc) { case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: /***********************************************/ /* These can happen for instr provider. */ /* If the instruction pointer isnt the */ /* 'next' instruction then a branch was */ /* taken, so handle the destination */ /* relative jump. */ /***********************************************/ if ((uchar_t *) regs->r_pc != tp->ct_instr_buf + 2) regs->r_pc = (greg_t) tp->ct_orig_pc + (char) tp->ct_instr_buf[1]; else regs->r_pc = (greg_t) tp->ct_orig_pc; break; SEE_ABOVE(0x9c, pushfl) case 0xc2: //ret imm16 case 0xc3: //ret case 0xca: //lret nn case 0xcb: //lret case 0xcd: //int $n -- hope we dont do this in kernel space. case 0xce: //into -- hope we dont do this in kernel space. break; SEE_ABOVE(0x9c, iret); case 0xe0: // LOOP rel8 - jump if count != 0 regs->r_pc = (greg_t) tp->ct_orig_pc; if (regs->r_rcx) { regs->r_pc += (char) pc[1]; return FALSE; } regs->r_rfl |= X86_EFLAGS_TF; return TRUE; case 0xe1: // LOOPZ rel8 - jump if count != 0 AND ZF=1 regs->r_pc = (greg_t) tp->ct_orig_pc; if (regs->r_rcx && regs->r_rfl & X86_EFLAGS_ZF) { regs->r_pc += (char) pc[1]; return FALSE; } regs->r_rfl |= X86_EFLAGS_TF; return TRUE; case 0xe2: // LOOPZ rel8 - jump if count != 0 AND ZF=0 regs->r_pc = (greg_t) tp->ct_orig_pc; if (regs->r_rcx && !(regs->r_rfl & X86_EFLAGS_ZF)) { regs->r_pc += (char) pc[1]; return FALSE; } regs->r_rfl |= X86_EFLAGS_TF; return TRUE; case 0xe3: // JRCXZ rel8 - jump if RCX == 0 regs->r_pc = (greg_t) tp->ct_orig_pc; if (regs->r_rcx == 0) { regs->r_pc += (char) pc[1]; return FALSE; } regs->r_rfl |= X86_EFLAGS_TF; return TRUE; SEE_BELOW(0xe4, in); SEE_BELOW(0xe5, in); SEE_BELOW(0xe6, out); SEE_BELOW(0xe7, out); case 0xe8: // CALLR nn32 call relative sp = (greg_t *) stack_ptr(regs); sp[0] = (greg_t) tp->ct_orig_pc; regs->r_pc = (long) tp->ct_orig_pc + *(s32 *) (tp->ct_orig_pc - 4); //printk("PC now %p\n", regs->r_pc); break; case 0xe9: // 0xe9 nn32 jmp relative regs->r_pc = (greg_t) tp->ct_orig_pc + *(s32 *) (tp->ct_instr_buf + 1); break; case 0xea: // 0xea jmp abs break; case 0xeb: // 0xeb nn jmp relative regs->r_pc = (greg_t) tp->ct_orig_pc + *(char *) (tp->ct_instr_buf + 1); break; case 0xf2: // REPZ -- need to keep going if ((regs->r_rfl & X86_EFLAGS_ZF) == 0 && regs->r_rcx) { regs->r_pc = (greg_t) tp->ct_instr_buf; regs->r_rfl |= X86_EFLAGS_TF; return TRUE; } else { regs->r_pc = (greg_t) tp->ct_orig_pc; } break; case 0xf3: // REPNZ -- need to keep going if (regs->r_rfl & X86_EFLAGS_ZF && regs->r_rcx) { regs->r_pc = (greg_t) tp->ct_instr_buf; regs->r_rfl |= X86_EFLAGS_TF; return TRUE; } else { regs->r_pc = (greg_t) tp->ct_orig_pc; } break; case 0xfa: // CLI /***********************************************/ /* Notreached - we emulate this in */ /* cpu_copy_instr because we panic if we */ /* single step. Not sure why - but */ /* emulation is better anyhow. */ /***********************************************/ regs->r_rfl &= ~X86_EFLAGS_IF; regs->r_pc = (greg_t) tp->ct_orig_pc; break; case 0xfb: // STI /***********************************************/ /* Notreached - we emulate this in */ /* cpu_copy_instr because we panic if we */ /* single step. Not sure why - but */ /* emulation is better anyhow. */ /***********************************************/ regs->r_rfl |= X86_EFLAGS_IF; regs->r_pc = (greg_t) tp->ct_orig_pc; break; SEE_BELOW(0xfc, cld); SEE_BELOW(0xfd, std); case 0xff: /***********************************************/ /* If we execute a CALL instruction, we */ /* need to push the original PC return */ /* address, not our buffers! */ /***********************************************/ switch (pc[1] & 0xf0) { case 0x10: // call/lcall *(%reg) case 0x50: // call/lcall *nn(%reg) case 0x90: // call/lcall *nn32(%reg) case 0xd0: // call/lcall *%reg {greg_t *sp = (greg_t *) stack_ptr(regs); *sp = (greg_t) tp->ct_orig_pc; break; } case 0x20: // jmp/ljmp *(%reg) case 0x60: // jmp/ljmp *nnn(%reg) case 0xa0: // jmp/ljmp *nnn(%reg) case 0xe0: // jmp/ljmp *%reg break; default: goto DEFAULT; } break; default: DEFAULT: ; regs->r_pc = (greg_t) tp->ct_orig_pc; //regs->r_rfl = (regs->r_rfl & ~(X86_EFLAGS_TF|X86_EFLAGS_IF)) | (this_cpu->cpuc_eflags & (X86_EFLAGS_IF)); break; } return FALSE; }