Skip to content

Commit

Permalink
Get jz working
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 13, 2018
1 parent fb27d93 commit c5f3627
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 25 deletions.
32 changes: 16 additions & 16 deletions emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,35 +132,35 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0x80: TRACEI("jo rel\t");
READIMM; J_REL(O, imm); break;
case 0x81: TRACEI("jno rel\t");
READIMM; J_REL(!O, imm); break;
READIMM; JN_REL(O, imm); break;
case 0x82: TRACEI("jb rel\t");
READIMM; J_REL(B, imm); break;
case 0x83: TRACEI("jnb rel\t");
READIMM; J_REL(!B, imm); break;
READIMM; JN_REL(B, imm); break;
case 0x84: TRACEI("je rel\t");
READIMM; J_REL(E, imm); break;
case 0x85: TRACEI("jne rel\t");
READIMM; J_REL(!E, imm); break;
READIMM; JN_REL(E, imm); break;
case 0x86: TRACEI("jbe rel\t");
READIMM; J_REL(BE, imm); break;
case 0x87: TRACEI("ja rel\t");
READIMM; J_REL(!BE, imm); break;
READIMM; JN_REL(BE, imm); break;
case 0x88: TRACEI("js rel\t");
READIMM; J_REL(S, imm); break;
case 0x89: TRACEI("jns rel\t");
READIMM; J_REL(!S, imm); break;
READIMM; JN_REL(S, imm); break;
case 0x8a: TRACEI("jp rel\t");
READIMM; J_REL(P, imm); break;
case 0x8b: TRACEI("jnp rel\t");
READIMM; J_REL(!P, imm); break;
READIMM; JN_REL(P, imm); break;
case 0x8c: TRACEI("jl rel\t");
READIMM; J_REL(L, imm); break;
case 0x8d: TRACEI("jnl rel\t");
READIMM; J_REL(!L, imm); break;
READIMM; JN_REL(L, imm); break;
case 0x8e: TRACEI("jle rel\t");
READIMM; J_REL(LE, imm); break;
case 0x8f: TRACEI("jnle rel\t");
READIMM; J_REL(!LE, imm); break;
READIMM; JN_REL(LE, imm); break;

case 0x90: TRACEI("seto\t");
READMODRM; SET(O, modrm_val); break;
Expand Down Expand Up @@ -359,35 +359,35 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0x70: TRACEI("jo rel8\t");
READIMM8; J_REL(O, imm); break;
case 0x71: TRACEI("jno rel8\t");
READIMM8; J_REL(!O, imm); break;
READIMM8; JN_REL(O, imm); break;
case 0x72: TRACEI("jb rel8\t");
READIMM8; J_REL(B, imm); break;
case 0x73: TRACEI("jnb rel8\t");
READIMM8; J_REL(!B, imm); break;
READIMM8; JN_REL(B, imm); break;
case 0x74: TRACEI("je rel8\t");
READIMM8; J_REL(E, imm); break;
case 0x75: TRACEI("jne rel8\t");
READIMM8; J_REL(!E, imm); break;
READIMM8; JN_REL(E, imm); break;
case 0x76: TRACEI("jbe rel8\t");
READIMM8; J_REL(BE, imm); break;
case 0x77: TRACEI("ja rel8\t");
READIMM8; J_REL(!BE, imm); break;
READIMM8; JN_REL(BE, imm); break;
case 0x78: TRACEI("js rel8\t");
READIMM8; J_REL(S, imm); break;
case 0x79: TRACEI("jns rel8\t");
READIMM8; J_REL(!S, imm); break;
READIMM8; JN_REL(S, imm); break;
case 0x7a: TRACEI("jp rel8\t");
READIMM8; J_REL(P, imm); break;
case 0x7b: TRACEI("jnp rel8\t");
READIMM8; J_REL(!P, imm); break;
READIMM8; JN_REL(P, imm); break;
case 0x7c: TRACEI("jl rel8\t");
READIMM8; J_REL(L, imm); break;
case 0x7d: TRACEI("jnl rel8\t");
READIMM8; J_REL(!L, imm); break;
READIMM8; JN_REL(L, imm); break;
case 0x7e: TRACEI("jle rel8\t");
READIMM8; J_REL(LE, imm); break;
case 0x7f: TRACEI("jnle rel8\t");
READIMM8; J_REL(!LE, imm); break;
READIMM8; JN_REL(LE, imm); break;

#define GRP1(src, dst,z) \
switch (modrm.opcode) { \
Expand Down
31 changes: 27 additions & 4 deletions emu/gadgets-x86/control.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,36 @@
movl 8(%_ip), %_tmp
movl %_tmp, (%_addrq)
movl (%_ip), %_eip
movl $-1, %_tmp
jmp jit_exit
jmp jit_ret

.gadget ret
movl %_esp, %_addr
addl $4, %_esp
read_prep
movl (%_addrq), %_eip
movl $-1, %_tmp
jmp jit_exit
jmp jit_ret

#define COND_LIST o,c,z,cz,s,p,sxo,sxoz
.irp cond, z
.gadget jmp_\cond
# please tell me if you know a better way
.ifc \cond,o
.else; .ifc \cond,c
.else; .ifc \cond,z
testl $-1, CPU_res(%_cpu)
jz 1f
.else; .ifc \cond,cz
.else; .ifc \cond,s
.else; .ifc \cond,p
.else; .ifc \cond,sxo
.else; .ifc \cond,sxoz
.endif; .endif; .endif; .endif; .endif; .endif; .endif; .endif
movl 8(%_ip), %_eip
jmp jit_ret
1:
movl (%_ip), %_eip
jmp jit_ret
.endr

.section .rodata
.gadget_array_list jmp, COND_LIST
8 changes: 6 additions & 2 deletions emu/gadgets-x86/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ jit_enter:
# TODO more of those
gret

.global jit_ret
jit_ret:
movl $-1, %_tmp
jmp jit_exit

.global jit_exit
jit_exit:
movl %eax, CPU_eax(%_cpu)
Expand All @@ -48,6 +53,5 @@ jit_exit:
jmp jit_exit

.gadget exit
movl $-1, %_tmp
movl (%_ip), %_eip
jmp jit_exit
jmp jit_ret
17 changes: 14 additions & 3 deletions emu/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ enum arg {
arg_reg32 = arg_eax, arg_reg16 = arg_ax,
};

// sync with COND_LIST in control.S
enum cond {
cond_O, cond_B, cond_E, cond_BE, cond_S, cond_P, cond_L, cond_LE,
cond_cnt,
};

// there are many
typedef void (*gadget_t)();
void gadget_interrupt();
void gadget_exit();
void gadget_push();
void gadget_call();
void gadget_ret();
void gadget_add_imm();
void gadget_sub_imm();
extern gadget_t load_gadgets[arg_cnt];
Expand All @@ -32,13 +36,19 @@ extern gadget_t and_gadgets[arg_cnt];
extern gadget_t sub_gadgets[arg_cnt];
extern gadget_t xor_gadgets[arg_cnt];

void gadget_call();
void gadget_ret();
extern gadget_t jmp_gadgets[cond_cnt];

extern gadget_t addr_gadgets[reg_cnt];
extern gadget_t si_gadgets[reg_cnt * 3];

#define GEN(thing) gen(state, (unsigned long) (thing))
#define g(g) GEN(gadget_##g)
#define gg(g, a) do { GEN(gadget_##g); GEN(a); } while (0)
#define ggg(g, a, b) do { GEN(gadget_##g); GEN(a); GEN(b); } while (0)
#define gag(g, i, a) do { GEN(g##_gadgets[i]); GEN(a); } while (0)
#define gagg(g, i, a, b) do { GEN(g##_gadgets[i]); GEN(a); GEN(b); } while (0)
#define gg_here(g, a) ggg(g, a, state->ip)
#define UNDEFINED do { gg_here(interrupt, INT_UNDEFINED); return; } while (0)

Expand Down Expand Up @@ -123,7 +133,8 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
#define JMP(loc) UNDEFINED
#define JMP_REL(off) UNDEFINED
#define JCXZ_REL(off) UNDEFINED
#define J_REL(cc, off) UNDEFINED
#define J_REL(cc, off) gagg(jmp, cond_##cc, state->ip + off, state->ip)
#define JN_REL(cc, off) gagg(jmp, cond_##cc, state->ip, state->ip + off)
#define CALL(loc) UNDEFINED
#define CALL_REL(off) gg_here(call, state->ip + off)
#define SET(cc, dst) UNDEFINED
Expand Down
4 changes: 4 additions & 0 deletions emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
if (cond) { \
cpu->eip += get(offset,); FIX_EIP; \
}
#define JN_REL(cond, offset) \
if (!cond) { \
cpu->eip += get(offset,); FIX_EIP; \
}
#define JCXZ_REL(offset) J_REL(cpu->ocx == 0, offset)

#define RET_NEAR() POP(eip); FIX_EIP
Expand Down

0 comments on commit c5f3627

Please sign in to comment.