forked from ish-app/ish
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start translating gadgets into aarch64
- Loading branch information
Showing
18 changed files
with
1,130 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#include "gadgets.h" | ||
|
||
.macro do_shift type, size, s | ||
.irp arg, reg_c,imm | ||
.gadget \type\size\()_\arg | ||
.ifc \arg,imm | ||
ldr w8, [_ip] | ||
ands w8, w8, \size-1 | ||
.else | ||
ands w8, _ecx, \size-1 | ||
.endif | ||
b.eq 1f | ||
|
||
# shift by one less, then by one more | ||
# that way we can retrieve the last bit shifted out for calculating CF and OF | ||
.ifc \type,shl | ||
sub w8, w8, 1 | ||
lsl _tmp, _tmp, w8 | ||
ubfx w9, _tmp, \size-1, 1 | ||
ubfx w10, _tmp, \size-2, 1 | ||
lsl _tmp, _tmp, 1 | ||
eor w10, w10, w9 | ||
strb w9, [_cpu, CPU_cf] | ||
strb w10, [_cpu, CPU_of] | ||
.else | ||
brk 1 | ||
.endif | ||
|
||
.ifin(\type, shl,shr,sar) | ||
setf_zsp \s | ||
clearf_a | ||
.endifin | ||
1: | ||
.ifc \arg,imm | ||
gret 1 | ||
.else | ||
gret | ||
.endif | ||
.endr | ||
.endm | ||
|
||
.irp type, shl,shr,sar,rol,ror | ||
.irp size, 8,16,32 | ||
ss \size, do_shift, \type | ||
.endr | ||
.gadget_array \type | ||
.endr | ||
|
||
.macro do_shiftd op, arg | ||
.macro x name, reg | ||
.gadget \op\()_\arg\()32_\name | ||
brk 1 | ||
/* | ||
.ifc \arg,imm | ||
pushq %rcx | ||
movb (%_ip), %cl | ||
.endif | ||
testb $(32 - 1), %cl | ||
jz 1f | ||
\op %cl, %\reg, %tmpd | ||
setf_oc | ||
setf_zsp %tmpd, l | ||
1: | ||
.ifc \arg,imm | ||
popq %rcx | ||
gret 1 | ||
.else | ||
gret | ||
.endif | ||
*/ | ||
.endm | ||
.each_reg x | ||
.purgem x | ||
.gadget_array \op\()_\arg | ||
.endm | ||
.irp op, shrd,shld | ||
.irp arg, imm,cl | ||
do_shiftd \op, \arg | ||
.endr | ||
.endr | ||
|
||
.macro do_bt_w8 | ||
lsr w8, w8, _tmp | ||
and w8, w8, 1 | ||
strb w8, [_cpu, CPU_cf] | ||
.endm | ||
|
||
.gadget bt32_mem | ||
add _addr, _addr, _tmp, lsr 3 | ||
read_prep 32 | ||
ldr w8, [_xaddr] | ||
do_bt_w8 | ||
gret 1 | ||
|
||
.macro x name reg | ||
.gadget bt32_\name | ||
mov w8, \reg | ||
do_bt_w8 | ||
gret | ||
.endm | ||
.each_reg x | ||
.purgem x | ||
|
||
.gadget_array bt | ||
|
||
.macro x name reg | ||
.gadget bswap_\name | ||
rev \reg, \reg | ||
gret | ||
.endm | ||
.each_reg x | ||
.purgem x | ||
.gadget_list bswap, REG_LIST |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
#include "gadgets.h" | ||
|
||
.gadget call | ||
sub _esp, _esp, 4 | ||
mov _addr, _esp | ||
write_prep 32 | ||
ldr w8, [_ip, 16] | ||
str w8, [_xaddr] | ||
write_done 32 | ||
ldr _ip, [_ip, 8] | ||
b jit_ret_chain | ||
|
||
.gadget call_indir | ||
sub _esp, _esp, 4 | ||
mov _addr, _esp | ||
ldr w8, [_ip, 8] | ||
str w8, [_xaddr] | ||
write_done 32 | ||
mov _eip, _tmp | ||
b jit_ret | ||
|
||
.gadget ret | ||
mov _addr, _esp | ||
ldr w8, [_ip, 8] | ||
add _esp, _esp, w8 | ||
read_prep 32 | ||
ldr _eip, [_xaddr] | ||
b jit_ret | ||
|
||
.gadget jmp_indir | ||
mov _eip, _tmp | ||
b jit_ret | ||
.gadget jmp | ||
ldr _ip, [_ip] | ||
b jit_ret_chain | ||
.gadget jcxz | ||
cbnz _ecx, 1f | ||
ldr _ip, [_ip] | ||
b jit_ret_chain | ||
1: | ||
ldr _ip, [_ip, 8] | ||
b jit_ret_chain | ||
|
||
#define COND_LIST o,c,z,cz,s,p,sxo,sxoz | ||
#define IMPLEMENTED_CONDS c,z,cz,s,p,sxo,sxoz | ||
|
||
.macro check_res | ||
cmpl $0, CPU_res(%_cpu) | ||
.endm | ||
.macro check_cf | ||
cmpb $0, CPU_cf(%_cpu) | ||
.endm | ||
|
||
.macro check_res_or_flag resflag, flag, target | ||
ldr w8, [_cpu, CPU_flags_res] | ||
tbz w8, \resflag, 2f | ||
ldr w8, [_cpu, CPU_eflags] | ||
tbz w8, \flag, 2f | ||
b \target | ||
2: | ||
.endm | ||
|
||
.macro do_jump cond, target | ||
# please tell me if you know a better way | ||
.ifc \cond,o | ||
.else; .ifc \cond,c | ||
ldrb w8, [_cpu, CPU_cf] | ||
cbnz w8, \target | ||
.else; .ifc \cond,z | ||
check_res_or_flag 1/*ZF_RES*/, 6/*ZF_FLAG*/, \target | ||
ldr w8, [_cpu, CPU_res] | ||
cbz w8, \target | ||
.else; .ifc \cond,cz | ||
ldrb w8, [_cpu, CPU_cf] | ||
cbnz w8, \target | ||
check_res_or_flag 1/*ZF_RES*/, 6/*ZF_FLAG*/, \target | ||
ldr w8, [_cpu, CPU_res] | ||
cbz w8, \target | ||
.else; .ifc \cond,s | ||
check_res_or_flag 2/*SF_RES*/, 7/*SF_FLAG*/, \target | ||
ldr w8, [_cpu, CPU_res] | ||
cmp w8, 0 | ||
b.lt \target | ||
.else; .ifc \cond,p | ||
check_res_or_flag 0/*PF_RES*/, 2/*PF_FLAG*/, \target | ||
# this is so sad | ||
ldr w8, [_cpu, CPU_res] | ||
uxtb w8, w8 | ||
fmov s0, w8 | ||
cnt v0.8b, v0.8b | ||
uaddlv h0, v0.8b | ||
fmov w8, s0 | ||
tbz w8, 0, \target | ||
.else; .ifc \cond,sxo | ||
ldr w8, [_cpu, CPU_res] | ||
cmp w8, 0 | ||
cset w8, lt | ||
ldrb w9, [_cpu, CPU_of] | ||
cmp w8, w9 | ||
b.eq \target | ||
.else; .ifc \cond,sxoz | ||
ldr w8, [_cpu, CPU_res] | ||
cmp w8, 0 | ||
b.eq \target | ||
cset w8, lt | ||
ldrb w9, [_cpu, CPU_of] | ||
cmp w8, w9 | ||
b.eq \target | ||
.endif; .endif; .endif; .endif; .endif; .endif; .endif; .endif | ||
.endm | ||
|
||
.irp cond, IMPLEMENTED_CONDS | ||
.gadget jmp_\cond | ||
do_jump \cond, 1f | ||
ldr _ip, [_ip, 8] | ||
b jit_ret_chain | ||
1: ldr _ip, [_ip] | ||
b jit_ret_chain | ||
|
||
.gadget set_\cond | ||
do_jump \cond, 1f | ||
mov _tmp, 0 | ||
gret | ||
1: mov _tmp, 1 | ||
gret | ||
.gadget setn_\cond | ||
do_jump \cond, 1f | ||
mov _tmp, 1 | ||
gret | ||
1: mov _tmp, 0 | ||
gret | ||
|
||
.gadget skip_\cond | ||
do_jump \cond, 1f | ||
gret 1 | ||
1: ldr x8, [_ip] | ||
add _ip, _ip, x8 | ||
gret 1 | ||
.gadget skipn_\cond | ||
do_jump \cond, 1f | ||
ldr x8, [_ip] | ||
add _ip, _ip, x8 | ||
1: gret 1 | ||
.endr | ||
.gadget_list jmp, COND_LIST | ||
.gadget_list set, COND_LIST | ||
.gadget_list setn, COND_LIST | ||
.gadget_list skip, COND_LIST | ||
.gadget_list skipn, COND_LIST | ||
|
||
.gadget pushf | ||
save_c | ||
mov x0, _cpu | ||
bl helper_collapse_flags | ||
restore_c | ||
|
||
sub _esp, _esp, 4 | ||
mov _addr, _esp | ||
write_prep 32 | ||
ldr x8, [_cpu, CPU_eflags] | ||
str x8, [_xaddr] | ||
write_done 32 | ||
gret | ||
|
||
.gadget popf | ||
mov _addr, _esp | ||
read_prep 32 | ||
ldr x8, [_xaddr] | ||
add _esp, _esp, 4 | ||
|
||
save_c | ||
mov x0, _cpu | ||
bl helper_expand_flags | ||
restore_c | ||
gret | ||
|
||
.gadget sahf | ||
ubfx w8, _eax, 8, 8 | ||
strb w8, [_cpu, CPU_eflags] | ||
save_c | ||
mov x0, _cpu | ||
bl helper_expand_flags | ||
restore_c | ||
gret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include "emu/interrupt.h" | ||
#include "gadgets.h" | ||
|
||
.global jit_enter | ||
.type jit_enter,function | ||
jit_enter: | ||
stp x18, x19, [sp, -0x60]! | ||
stp x20, x21, [sp, 0x10] | ||
stp x22, x23, [sp, 0x20] | ||
stp x24, x25, [sp, 0x30] | ||
stp x26, x27, [sp, 0x40] | ||
stp x28, x29, [sp, 0x50] | ||
add _ip, x0, JIT_BLOCK_code | ||
# cpu is already x1 | ||
add _tlb, x2, TLB_entries | ||
ldr _eax, [_cpu, CPU_eax] | ||
ldr _ebx, [_cpu, CPU_ebx] | ||
ldr _ecx, [_cpu, CPU_ecx] | ||
ldr _edx, [_cpu, CPU_edx] | ||
ldr _esi, [_cpu, CPU_esi] | ||
ldr _ebp, [_cpu, CPU_ebp] | ||
ldr _esp, [_cpu, CPU_esp] | ||
gret | ||
|
||
.global jit_ret_chain | ||
jit_ret_chain: | ||
cmp _ip, 0 | ||
b.lt jit_ret | ||
gret | ||
|
||
.global jit_ret | ||
jit_ret: | ||
# load -1 | ||
mvn _tmp, wzr | ||
# fallthrough | ||
|
||
.global jit_exit | ||
jit_exit: | ||
str _eax, [_cpu, CPU_eax] | ||
str _ebx, [_cpu, CPU_ebx] | ||
str _ecx, [_cpu, CPU_ecx] | ||
str _edx, [_cpu, CPU_edx] | ||
str _esi, [_cpu, CPU_esi] | ||
str _ebp, [_cpu, CPU_ebp] | ||
str _esp, [_cpu, CPU_esp] | ||
str _eip, [_cpu, CPU_eip] | ||
ldp x28, x29, [sp, 0x50] | ||
ldp x26, x27, [sp, 0x40] | ||
ldp x24, x25, [sp, 0x30] | ||
ldp x22, x23, [sp, 0x20] | ||
ldp x20, x21, [sp, 0x10] | ||
ldp x18, x19, [sp], 0x60 | ||
# _tmp is already x0 | ||
ret | ||
|
||
.gadget interrupt | ||
ldr _tmp, [_ip] | ||
ldr _eip, [_ip, 8] | ||
b jit_exit | ||
|
||
.gadget exit | ||
ldr _eip, [_ip] | ||
b jit_ret |
Oops, something went wrong.