1
0
mirror of https://github.com/pakt/ropc synced 2026-06-08 16:36:27 +00:00
Files
2012-09-20 03:16:35 -07:00

166 lines
4.8 KiB
OCaml

open Printf
type reg = EAX | EBX | ECX | EDX | ESI | EDI | EBP | ESP
type op = ADD | SUB | MUL | DIV | XOR | OR | AND
type gadget =
| LoadConst of reg * int (* reg, stack offset *)
| CopyReg of reg * reg (* dst reg = src reg *)
| BinOp of reg * reg * op * reg (* dst reg = src1 OP src2 *)
| ReadMem of reg * reg * int32 (* dst = [addr_reg + offset] *)
| WriteMem of reg * int32 * reg (* [addr_reg + offset] = src *)
| ReadMemOp of reg * op * reg * int32 (* dst OP= [addr_reg + offset] *)
| WriteMemOp of reg * int32 * op * reg (* [addr_reg + offset] OP= src_reg *)
| Lahf
| OpEsp of op * reg * int (* esp = esp op reg, where op=+/-, sf =
stack_fix *)
(* (offset_start, offset_end) *)
type fmeta = FileMeta of int * int
(* gadget, file meta, modified registers, stack_fix *)
type gmeta = GMeta of gadget * fmeta * reg list * int
(* filename, (data section start, data section end), gadget list
type used for marshaling candidates for verification *)
type gcontainer = GContainer of string * (int * int) * gmeta list
let rEGS = [EAX; EBX; ECX; EDX; ESI; EDI; EBP; ESP;]
let rEGS_NO_ESP = [EAX; EBX; ECX; EDX; ESI; EDI; EBP;]
let dump_reg r =
match r with
| EAX -> "eax"
| EBX -> "ebx"
| ECX -> "ecx"
| EDX -> "edx"
| ESI -> "esi"
| EDI -> "edi"
| EBP -> "ebp"
| ESP -> "esp"
let dump_op op =
match op with
| ADD -> "+"
| SUB -> "-"
| MUL -> "*"
| DIV -> "/"
| XOR -> "^"
| AND -> "&"
| OR -> "|"
let dump_filemeta fm =
let FileMeta(off_s, off_e) = fm in
let s = sprintf "(s: 0x%x, e: 0x%x)" off_s off_e in
s
let dump_gadget g =
match g with
| LoadConst(r, off) -> sprintf "LoadConst(%s, 0x%x)" (dump_reg r) off
| CopyReg(r1, r2) -> sprintf "CopyReg(%s, %s)" (dump_reg r1) (dump_reg r2)
| BinOp(r_dst,r1,op,r2) -> sprintf "BinOp(%s, %s, %s, %s)" (dump_reg r_dst) (dump_reg r1) (dump_op op) (dump_reg r2)
| ReadMem(r_dst, r_addr, off) -> sprintf "ReadMem(%s = [%s+0x%lx])" (dump_reg r_dst) (dump_reg r_addr) off
| WriteMem(r_addr, off, r_src) -> sprintf "WriteMem([%s+0x%lx] = %s)" (dump_reg r_addr) off (dump_reg r_src)
| ReadMemOp(r_dst, op, r_addr, off) -> sprintf "ReadMemOp(%s %s= [%s+0x%lx])" (dump_reg r_dst) (dump_op op) (dump_reg r_addr) off
| WriteMemOp(r_addr, off, op, r_src) -> sprintf "WriteMemOp([%s+0x%lx] %s= %s)" (dump_reg r_addr) off (dump_op op) (dump_reg r_src)
| OpEsp(op, r, sf) -> sprintf "OpEsp(%s, %s, %d)" (dump_op op) (dump_reg r) sf
| Lahf -> "Lahf"
let uniq eq l =
let rec aux l last uni dupes =
match l with
| hd::tl ->
if eq hd last = 0 then
aux tl last uni (hd::dupes)
else
aux tl hd (hd::uni) dupes
| [] -> uni, dupes
in
match l with
| [] -> l,l
| hd::[] -> l, []
| hd::tl -> aux tl hd [hd] []
let unique eq l =
let u, _ = uniq eq l in
u
let nonunique eq l =
let _, nu = uniq eq l in
nu
let generic_unique l =
let l = List.sort compare l in
unique compare l
let create_hashtable size init =
let tbl = Hashtbl.create size in
List.iter (fun (key, data) -> Hashtbl.add tbl key data) init;
tbl
let file_exc filename e =
Format.printf "Cannot open file \"%s\": %s\n" filename (Printexc.to_string e);
assert false
let open_file fn fopen =
try
let co = fopen fn in
co
with Sys_error _ as e ->
file_exc fn e
let open_file_in fn = open_file fn open_in_bin
let open_file_out fn = open_file fn open_out_bin
let write_str_to_file filename str =
let co = open_file_out filename in
(* let co = Format.formatter_of_out_channel co in*)
output_string co str;
close_out co
let read_file fn =
let ic = open_file_in fn in
let n = in_channel_length ic in
let s = String.create n in
really_input ic s 0 n;
close_in ic;
(s)
let marshal_to_file fn thing =
let co = open_file_out fn in
Marshal.to_channel co thing []
let unmarshal_from_file fn =
let ic = open_file_in fn in
let obj = Marshal.from_channel ic in
obj
(* this assumes that RET is the last instruction *)
let drop_last stmts =
let stmts = List.rev (List.tl (List.rev stmts)) in
stmts
let find_all p l =
let f acc x = if p x then (x::acc) else acc in
List.fold_left f [] l
let generic_dumper f_dump l =
let f _ x = Printf.printf "%s;" (f_dump x) in
let _ = List.fold_left f () l in
()
let dump_int_list l =
let f acc x =
let s = string_of_int x in
acc^";"^s
in
List.fold_left f "" l
let get_gadgets gmetas =
let strip acc gm =
let GMeta(g,_,_,_) = gm in
g::acc
in
let gadgets = List.fold_left strip [] gmetas in
gadgets