Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initializes PLT GOT in Primus #993

Merged
merged 11 commits into from
Oct 18, 2019
65 changes: 58 additions & 7 deletions plugins/primus_x86/primus_x86_loader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,59 @@ open Bap.Std
open Bap_primus.Std
open X86_cpu

let is_section name v =
match Value.get Image.section v with
| Some x -> String.(x = name)
| _ -> false

module Make_unresolved(Machine : Primus.Machine.S) = struct
module Linker = Primus.Linker.Make(Machine)

let exec =
Linker.exec (`symbol Primus.Linker.unresolved_handler)
end

module Plt_jumps(Machine : Primus.Machine.S) = struct
module Linker = Primus.Linker.Make(Machine)
open Machine.Syntax

let section_memory sec_name =
Machine.get () >>| fun proj ->
Memmap.filter (Project.memory proj) ~f:(is_section sec_name) |>
Memmap.to_sequence |>
Seq.map ~f:fst

let load_table =
Machine.arch >>= fun arch ->
section_memory ".got.plt" >>| fun memory ->
Seq.fold memory ~init:[]
~f:(fun acc mem ->
let step = (Arch.addr_size arch :> size) in
Memory.fold mem ~word_size:step ~init:[] ~f:(fun a w -> a :: w))

let filter_plt addrs =
section_memory ".plt" >>= fun memory ->
Machine.return @@
List.filter addrs ~f:(fun a ->
Seq.exists memory ~f:(fun mem -> Memory.contains mem a))

let unlink addrs =
Machine.List.iter addrs ~f:(fun addr ->
Linker.link ~addr (module Make_unresolved))

let unresolve =
load_table >>=
filter_plt >>=
unlink

end

module Component(Machine : Primus.Machine.S) = struct
open Machine.Syntax
module Env = Primus.Env.Make(Machine)
module Value = Primus.Value.Make(Machine)
module Interpreter = Primus.Interpreter.Make(Machine)
module Plt_jumps = Plt_jumps(Machine)

let zero = Primus.Generator.static 0

Expand All @@ -23,18 +71,21 @@ module Component(Machine : Primus.Machine.S) = struct
match Var.typ sp with
| Mem _ -> Machine.return ()
| Imm width ->
Value.of_int ~width addend >>= fun addend ->
Primus.Linker.Trace.lisp_call_return >>> correct_sp sp addend

let seq = Machine.sequence
Value.of_int ~width addend >>= fun addend ->
Primus.Linker.Trace.lisp_call_return >>> correct_sp sp addend

let init () =
Machine.get () >>= fun proj ->
Machine.sequence @@
match Project.arch proj with
| `x86 ->
seq [initialize_flags IA32.flags; correct_sp IA32.sp 4]
[initialize_flags IA32.flags;
correct_sp IA32.sp 4;
Plt_jumps.unresolve ]
| `x86_64 ->
seq [initialize_flags AMD64.flags; correct_sp AMD64.sp 8]
| _ -> Machine.return ()
[initialize_flags AMD64.flags;
correct_sp AMD64.sp 8;
Plt_jumps.unresolve ]
| _ -> []

end