diff options
| -rw-r--r-- | reproducers/issue-1373.c | 6 | ||||
| -rw-r--r-- | reproducers/issue-1376.c | 5 | ||||
| -rw-r--r-- | reproducers/issue-1377.c | 30 | ||||
| -rw-r--r-- | reproducers/issue-1832422.c | 3 | ||||
| -rw-r--r-- | reproducers/issue-1861404.c | 29 | ||||
| -rw-r--r-- | reproducers/issue-2495.c | 32 | ||||
| -rw-r--r-- | src/focaccia/miasm_util.py | 21 | ||||
| -rw-r--r-- | src/focaccia/tools/_qemu_tool.py | 25 |
8 files changed, 149 insertions, 2 deletions
diff --git a/reproducers/issue-1373.c b/reproducers/issue-1373.c new file mode 100644 index 0000000..b9f100e --- /dev/null +++ b/reproducers/issue-1373.c @@ -0,0 +1,6 @@ +void main() { + asm("push 512; popfq;"); + asm("mov rax, 0xffffffff84fdbf24"); + asm("mov rbx, 0xb197d26043bec15d"); + asm("adox eax, ebx"); +} diff --git a/reproducers/issue-1376.c b/reproducers/issue-1376.c new file mode 100644 index 0000000..8611c95 --- /dev/null +++ b/reproducers/issue-1376.c @@ -0,0 +1,5 @@ +void main() { + asm("mov rax, 0xa02e698e741f5a6a"); + asm("mov rbx, 0x20959ddd7a0aef"); + asm("lsl ax, bx"); +} diff --git a/reproducers/issue-1377.c b/reproducers/issue-1377.c new file mode 100644 index 0000000..b6b1309 --- /dev/null +++ b/reproducers/issue-1377.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<sys/mman.h> +__attribute__((naked,noinline)) void* f(void* dst, void* p) { + __asm__( + "\n pushq %rbp" + "\n movq %rsp, %rbp" + "\n movq %rdi, %rax" + "\n movq $0x0, (%rdi)" + "\n movl $0x140a, (%rdi) # imm = 0x140A" + "\n movb $0x4, 0x5(%rdi)" + "\n cvtps2pd (%rsi), %xmm0" + "\n movups %xmm0, 0x8(%rdi)" + "\n cvtps2pd 0x8(%rsi), %xmm0" + "\n movups %xmm0, 0x18(%rdi)" + "\n popq %rbp" + "\n retq" + ); +} +int main() { + char dst[1000]; + int page = 4096; + char* buf = mmap(NULL, page*2, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + // mprotect(buf+page, page, 0); + + float* src = (float*)(buf+0x40); + printf("src: %p\n", src); + + void* r = f(dst, src); + printf("res: %p\n", r); +} diff --git a/reproducers/issue-1832422.c b/reproducers/issue-1832422.c new file mode 100644 index 0000000..108b661 --- /dev/null +++ b/reproducers/issue-1832422.c @@ -0,0 +1,3 @@ +void main() { + asm("cmppd xmm0,xmm0,0xd1"); +} diff --git a/reproducers/issue-1861404.c b/reproducers/issue-1861404.c new file mode 100644 index 0000000..c83dbc2 --- /dev/null +++ b/reproducers/issue-1861404.c @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <string.h> + +#define YMM_SIZE (32) // bytes + +void hex_dump(unsigned char *data, unsigned int len) { + for(unsigned int i=0; i<len; i++) { + printf("%02X ", data[i]); + } + printf("\n"); +} + +void set_ymm0(unsigned char m[YMM_SIZE]) { +} + +void get_ymm0(unsigned char m[YMM_SIZE]) { + __asm__ __volatile__ ("vmovdqu %%ymm0, (%0);"::"r"(m):); +} + +int main() { + unsigned char src[YMM_SIZE] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}; + unsigned char dst[YMM_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + __asm__ __volatile__ ("vmovdqu (%0), %%ymm0;"::"r"(src):); + + hex_dump(dst, YMM_SIZE); + + return 0; +} diff --git a/reproducers/issue-2495.c b/reproducers/issue-2495.c new file mode 100644 index 0000000..3648c1a --- /dev/null +++ b/reproducers/issue-2495.c @@ -0,0 +1,32 @@ +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +uint8_t i_R8[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; +uint8_t i_MM0[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +uint8_t o_R8[8]; + +void __attribute__ ((noinline)) show_state() { + printf("R8: "); + for (int i = 0; i < 8; i++) { + printf("%02x ", o_R8[i]); + } + printf("\n"); +} + +void __attribute__ ((noinline)) run() { + __asm__ ( + ".intel_syntax noprefix\n" + "mov r8, qword ptr [rip + i_R8]\n" + "movq mm0, qword ptr [rip + i_MM0]\n" + ".byte 0x4f, 0x0f, 0x7e, 0xc0\n" + "mov qword ptr [rip + o_R8], r8\n" + ".att_syntax\n" + ); +} + +int main(int argc, char **argv) { + run(); + show_state(); + return 0; +} diff --git a/src/focaccia/miasm_util.py b/src/focaccia/miasm_util.py index cacc6e8..c9dc4e5 100644 --- a/src/focaccia/miasm_util.py +++ b/src/focaccia/miasm_util.py @@ -86,10 +86,29 @@ def simp_fsub(expr_simp, expr: ExprOp): return expr_simp(ExprInt(res, expr.size)) return expr +def simp_fpconvert_fp64(expr_simp, expr: ExprOp): + from .utils import float_bits_to_uint, uint_bits_to_float, \ + double_bits_to_uint, uint_bits_to_double + + if expr.op != 'fpconvert_fp64': + return expr + + if not len(expr.args) == 1: + raise NotImplementedError(f'fpconvert_fp64 on number of arguments not in 1: {expr.args}') + + operand = expr.args[0] + if operand.is_int(): + if not operand.size == 32: + raise NotImplementedError(f'fpconvert_fp64 on values of size not in 64: {operand.size}') + + res = double_bits_to_uint(uint_bits_to_double(float_bits_to_uint(operand.arg))) + return expr_simp(ExprInt(res, 64)) + return expr + # The expression simplifier used in this module expr_simp = expr_simp_explicit expr_simp.enable_passes({ - ExprOp: [simp_segm, simp_fadd, simp_fsub], + ExprOp: [simp_segm, simp_fadd, simp_fsub, simp_fpconvert_fp64], }) class MiasmSymbolResolver: diff --git a/src/focaccia/tools/_qemu_tool.py b/src/focaccia/tools/_qemu_tool.py index cc97c95..02d150b 100644 --- a/src/focaccia/tools/_qemu_tool.py +++ b/src/focaccia/tools/_qemu_tool.py @@ -13,7 +13,7 @@ from typing import Iterable import focaccia.parser as parser from focaccia.arch import supported_architectures, Arch -from focaccia.compare import compare_symbolic +from focaccia.compare import compare_symbolic, Error, ErrorTypes from focaccia.snapshot import ProgramState, ReadableProgramState, \ RegisterAccessError, MemoryAccessError from focaccia.symbolic import SymbolicTransform, eval_symbol, ExprMem @@ -27,6 +27,15 @@ debug = logger.debug info = logger.info warn = logger.warning +qemu_crash = { + "crashed": False, + "pc": None, + 'txl': None, + 'ref': None, + 'errors': [Error(ErrorTypes.CONFIRMED, "QEMU crashed")], + 'snap': None, +} + class GDBProgramState(ReadableProgramState): from focaccia.arch import aarch64, x86 @@ -315,9 +324,15 @@ def collect_conc_trace(gdb: GDBServerStateIterator, \ if symb_i >= len(strace): break except StopIteration: + # TODO: The conditions may test for the same if stop_addr and pc != stop_addr: raise Exception(f'QEMU stopped at {hex(pc)} before reaching the stop address' f' {hex(stop_addr)}') + if symb_i+1 < len(strace): + qemu_crash["crashed"] = True + qemu_crash["pc"] = strace[symb_i].addr + qemu_crash["ref"] = strace[symb_i] + qemu_crash["snap"] = states[-1] break except Exception as e: print(traceback.format_exc()) @@ -374,6 +389,14 @@ def main(): if not args.quiet: try: res = compare_symbolic(conc_states, matched_transforms) + if qemu_crash["crashed"]: + res.append({ + 'pc': qemu_crash["pc"], + 'txl': None, + 'ref': qemu_crash["ref"], + 'errors': qemu_crash["errors"], + 'snap': qemu_crash["snap"], + }) print_result(res, verbosity[args.error_level]) except Exception as e: raise Exception('Error occured when comparing with symbolic equations: {e}') |