Skip to content

Commit

Permalink
Make operation sizes great again
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 22, 2018
1 parent bc0c9d8 commit 3c0c9f8
Show file tree
Hide file tree
Showing 9 changed files with 762 additions and 853 deletions.
474 changes: 228 additions & 246 deletions emu/decode.h

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions emu/gadgets-x86/control.S
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,4 @@
jmp jit_ret
.endr

.section .rodata
.gadget_array_list jmp, COND_LIST
.gadget_array jmp, COND_LIST
52 changes: 23 additions & 29 deletions emu/gadgets-x86/gadgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# register assignments
#define _esp r8d
#define _sp r8w
#define _ip r9
#define _eip r9d
#define _tmp r10d
Expand All @@ -21,9 +22,6 @@
jmp *-8(%_ip)
.endm

# using a gas macro for this works fine on gcc but not on clang
#define REG_LIST eax,ecx,edx,ebx,esp,ebp,esi,edi

# memory reading and writing
# TODO cross-page access handling (but it's going to be so slow :cry:)
.irp type, read,write
Expand All @@ -48,36 +46,32 @@

.endr

# a gadget for each register
.macro .reg_gadgets type
.irp reg, REG_LIST
.gadget \type\()_\reg
.ifnc \reg,esp
x \reg
.else
x _esp
.endif
gret
.endr
.purgem x
.endm
# sync with enum reg
#define REG_LIST reg_a,reg_c,reg_d,reg_b,reg_sp,reg_bp,reg_si,reg_di
# sync with enum arg
#define GADGET_LIST REG_LIST,imm,mem,addr

# an array of gadgets
.macro .gadget_array_list type, list:vararg
.global \type\()_gadgets
.type \type\()_gadgets,@object
\type\()_gadgets:
.irp arg, \list
.ifndef gadget_\type\()_\arg
.set gadget_\type\()_\arg, 0
.endif
.quad gadget_\type\()_\arg
.endr
.macro .gadget_array type, list:vararg
.pushsection .rodata
.gadget_array_start \type
gadgets \type, \list
.popsection
.endm

.macro .gadget_array type
# This should stay in sync with enum arg in emu/gen.c
.gadget_array_list \type, eax,ecx,edx,ebx,esp,ebp,esi,edi,ax,cx,dx,bx,sp,bp,si,di,imm,mem32,mem8,addr
.macro .gadget_array_start name
.global \name\()_gadgets
.type \name\()_gadgets,@object
\name\()_gadgets:
.endm

.macro gadgets type, list:vararg
.irp arg, \list
.ifndef gadget_\type\()_\arg
.set gadget_\type\()_\arg, 0
.endif
.quad gadget_\type\()_\arg
.endr
.endm

.macro save_c
Expand Down
105 changes: 78 additions & 27 deletions emu/gadgets-x86/math.S
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "gadgets.h"
# asmsyntax=gas (for vim)

.gadget load_addr
.gadget load32_addr
movl %_addr, %_tmp
gret

Expand All @@ -18,16 +18,16 @@
andl $~AF_FLAG, CPU_eflags(%_cpu)
andl $~AF_OPS, CPU_flags_res(%_cpu)
.endm
.macro setf_zsp res
mov \res, CPU_res(%_cpu)
.macro setf_zsp res, ss
.ifnc ss,l
movl $0, CPU_res(%_cpu)
.endif
mov\ss \res, CPU_res(%_cpu)
orl $(ZF_RES|SF_RES|PF_RES), CPU_flags_res(%_cpu)
.endm

# cool thing where I just write a few nested loops and it generates all the gadgets automatically

# bwl
# bwd

#define ifin(thing, ...) irp da_op, __VA_ARGS__; .ifc thing,\da_op
#define endifin endif; .endr
#undef _tmp
Expand All @@ -49,54 +49,105 @@
.ifin(\op, add,sub)
setf_oc
.endifin
setf_zsp %_tmp\s
setf_zsp %_tmp\s, \ss
.endif; .endif
.endm
.macro do_op op, arg, size
.macro do_op op, size, arg
.ifc \size,8
_do_op \op, \arg, \size, b, b
.else; .ifc \size,16
_do_op \op, \arg, \size, w, w
.else; .ifc \size,32
_do_op \op, \arg, \size, d, l
.else
.error "bad size"
.endif; .endif
.endif; .endif; .endif
.endm
#undef _tmp
#define _tmp r10d

.irp op, load,store,add,and,sub,xor
.macro x reg
do_op \op, %\reg, 32
.endm
.reg_gadgets \op
.macro do_reg_op op, size, reg
.gadget \op\size\()_reg_\reg
.if \size == 32
do_op \op, \size, %e\reg\()x
.elseif \size == 16
do_op \op, \size, %\reg\()x
.elseif \size == 8
do_op \op, \size, %\reg\()l
.endif
gret
.endm

.macro do_hi_op op, size, reg
xchg %\reg\()h, %\reg\()l
do_op \op, \size, %\reg\()l
xchg %\reg\()h, %\reg\()l
.endm

.macro do_op_size op, size
.ifnc \op,store
.gadget \op\()_imm
do_op \op, (%_ip), 32
.gadget \op\size\()_imm
do_op \op, \size, (%_ip)
gret 1
.endif

.irp size, 8,32
.gadget \op\()_mem\size
.ifc \op,store
write_prep
.else
read_prep
.gadget \op\size\()_mem
.ifc \op,store
write_prep
.else
read_prep
.endif
do_op \op, \size, (%_addrq)
gret

.irp reg, a,b,c,d
do_reg_op \op, \size, \reg
.endr

.irp reg, si,di,sp,bp
.gadget \op\size\()_reg_\reg
.if \size == 32
.ifnc \reg,sp
do_op \op, \size, %e\reg
.else
do_op \op, \size, %_esp
.endif
.elseif \size == 16
.ifnc \reg,sp
do_op \op, \size, %\reg
.else
do_op \op, \size, %_sp
.endif
.elseif \size == 8
.ifc \reg,sp; do_hi_op \op, \size, a; .else
.ifc \reg,bp; do_hi_op \op, \size, c; .else
.ifc \reg,si; do_hi_op \op, \size, d; .else
.ifc \reg,di; do_hi_op \op, \size, b
.endif; .endif; .endif; .endif
.endif
do_op \op, (%_addrq), \size
gret
.endr
.endm

.irp op, load,store,add,and,sub,xor
.irp size, 8,16,32
do_op_size \op, \size
.endr

.section .rodata
.gadget_array \op
.previous
.pushsection .rodata
.gadget_array_start \op
# sync with enum size
.irp size, 8,16,32
gadgets \op\size, GADGET_LIST
.endr
.popsection
.endr

.irp op, inc,dec
.gadget \op
setf_a src=$1 dst=%_tmp, ss=l
\op\()l %_tmp
seto CPU_of(%_cpu)
setf_zsp %_tmp
setf_zsp %_tmp, l
gret
.endr
38 changes: 28 additions & 10 deletions emu/gadgets-x86/memory.S
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,43 @@
add $4, %_esp
gret

.macro x reg
movl %\reg, %_addr
addl (%_ip), %_addr
gret 1
.macro _invoke macro, reg, post
\macro reg_\reg, e\reg\post
.endm
.macro .each_reg macro
.irp reg, a,b,c,d
_invoke \macro, \reg, x
.endr
.irp reg, si,di,bp
_invoke \macro, \reg,
.endr
\macro reg_sp, _esp
.endm
.reg_gadgets addr

.irp reg, REG_LIST
.macro x name, reg
.gadget addr_\name
movl %\reg, %_addr
addl (%_ip), %_addr
gret 1
.endm
.each_reg x
.purgem x
.gadget_array addr, REG_LIST

.macro x name, reg
.irp times, 1,2,4
.gadget si_\reg\()_\times
.gadget si_\name\()_\times
.ifnc \reg,esp
leal (%_addr,%\reg,\times), %_addr
.else
leal (%_addr,%_esp,\times), %_addr
.endif
gret
.endr
.endr
.endm
.each_reg x
.purgem x

.section .rodata
.global si_gadgets
si_gadgets:
Expand Down Expand Up @@ -68,5 +87,4 @@ segfault:
movl $INT_GPF, %_tmp
jmp jit_exit

.section .rodata
.gadget_array_list addr, REG_LIST
.gadget_array, REG_LIST
Loading

0 comments on commit 3c0c9f8

Please sign in to comment.