Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory...

65
Implementing an LLVM based Dynamic Binary Instrumentation framework Charles Hubain Cédric Tessier

Transcript of Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory...

Page 1: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Implementing an LLVM based Dynamic Binary

Instrumentation framework

Charles Hubain

Cédric Tessier

Page 2: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Introduction to Instrumentation

34c3 - Implementing an LLVM based DBI framework2

Page 3: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

What is Instrumentation?

• “Transformation of a program into its own measurement tool”

• Observe any state of a program anytime during runtime

• Automate the data collection and processing

34c3 - Implementing an LLVM based DBI framework3

Page 4: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Use Cases• Finding memory bugs:

• Track memory allocations / deallocations

• Track memory accesses

• Fuzzing:

• Measure code coverage

• Build symbolic representation of code

• Recording execution traces

• Replay them for “timeless” debugging

• Software side-channel attacks against crypto

34c3 - Implementing an LLVM based DBI framework4

Page 5: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

“Why not … debuggers?”

• Debuggers are awesome but slooooooooow

Debugger Kernel Target

Resume Schedule

Trap interruptSignal + schedule

34c3 - Implementing an LLVM based DBI framework5

Page 6: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

https://asciinema.org/a/17nynlopg5a18e1qps3r9ou7g

Page 7: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

“Why not … debuggers?”

• Debuggers are awesome but slooooooooow

Debugger Kernel Target

Resume Schedule

Trap interruptSignal + schedule

• Solution? Get rid of the kernel

• How? Run the instrumentation inside the target

34c3 - Implementing an LLVM based DBI framework7

Page 8: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Instrumentation Techniques

• From source code:

• Manually, you know … printf(…)

• At compile time

• From binary:

• Static binary patching & hooking

• Dynamic Binary Instrumentation

BORING

Crude and barbaric

This talk

34c3 - Implementing an LLVM based DBI framework8

Page 9: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Existing Frameworks

• Valgrind since 2000

• Open source, only *nix platforms, very complex

• DynamoRIO since 2002

• Open source, cross-platforms, very raw

• Intel Pin since 2004

• Closed source, only Intel platforms, user friendly

34c3 - Implementing an LLVM based DBI framework9

Page 10: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

“Why we made our own”

• Cross-platform and cross-architecture

• Mobile and embedded targets support

• Simpler and modular design

• Focus on “heavy” instrumentation

What we wanted from a DBI framework in 2015

34c3 - Implementing an LLVM based DBI framework10

Page 11: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Introduction to DBI

34c3 - Implementing an LLVM based DBI framework11

Page 12: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Dynamic Binary Instrumentation

• Dynamically insert the instrumentation at runtime

Original Binary Code

Disassemble GenerateInstrumentation Insert Execute

Instru

PAC-MANfor scale

34c3 - Implementing an LLVM based DBI framework12

Page 13: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Disassembling

• What part of the binary is the code is unknown

➡ Disassembling the whole binary in advance is impossible

• We need to discover the code as we go

34c3 - Implementing an LLVM based DBI framework13

Page 14: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Code Discovery

• How?

• Execute a block of code

• Discover where the execution flow after the block

• Execute the next block of code

• This forms a short execution cycle

34c3 - Implementing an LLVM based DBI framework14

Page 15: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

No Free SpaceInstructionInstructionInstruction

COND JUMP

InstructionInstructionInstruction

JUMP

InstructionInstructionInstruction

JUMP

FALS

E TRUE

• The instrumented code is larger than the original code

• Binaries are usually tightly packed with little free space

➡ The instrumentation cannot be inserted in-place

➡ It needs to be “relocated”

34c3 - Implementing an LLVM based DBI framework15

Page 16: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Relocating

• Code contains relative reference to memory addresses

• These become invalid once we move the code

• We need to completely rewrite the code to fix those references

➡ This is what we call “patching”

34c3 - Implementing an LLVM based DBI framework16

Page 17: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

The “Cycle of Life”

34c3 - Implementing an LLVM based DBI framework17

Page 18: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Designing a DBI: 1. Low Level Abstractions

34c3 - Implementing an LLVM based DBI framework18

Page 19: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

InstructionInstructionInstruction

InstructionInstructionInstruction

InstructionInstructionInstruction

InstructionInstructionInstruction

Basic Blocks

34c3 - Implementing an LLVM based DBI framework19

Page 20: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

InstructionInstructionInstruction

InstructionInstructionInstruction

InstructionInstructionInstruction

InstructionInstructionInstruction

JUMP

JUMP JUMP

JUMP

Control Flow

34c3 - Implementing an LLVM based DBI framework20

Page 21: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Under Control FlowInstructionInstructionInstruction

JUMP

InstructionInstructionInstruction

JUMP

InstructionInstructionInstruction

JUMP

InstructionInstructionInstruction

JUMP

DBI

Guest Host

34c3 - Implementing an LLVM based DBI framework21

Page 22: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Under ControlDBI is all about keeping control of the execution

34c3 - Implementing an LLVM based DBI framework22

Page 23: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Under Control

• Keeping control of the execution

• requires modifying original instructions…

• …without modifying original behaviour

34c3 - Implementing an LLVM based DBI framework23

Page 24: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

What We Need

• A multi-architecture disassembler

• A multi-architecture assembler

• A generic intermediate representation to apply modifications on

34c3 - Implementing an LLVM based DBI framework24

Page 25: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

We Don't Want

• To implement a multi-architecture disassembler and assembler

• To abstract every single instruction semantic

• Architectures Developer Manuals are not that fun…

Actually we don’t have 10 years and unlimited ressources

34c3 - Implementing an LLVM based DBI framework25

Page 26: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Here Be DragonsThis has nothing to do with 26C3

34c3 - Implementing an LLVM based DBI framework26

Page 27: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

To the rescue

• LLVM already has everything

• It supports all major architectures

• It provides a disassembler and an assembler…

• …and both work on the same intermediate representation

• LLVM Machine Code (aka MC) to the rescue

34c3 - Implementing an LLVM based DBI framework27

Page 28: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

LLVM MC

<MCInst #1670 MOV64mr <MCOperand Reg:0> <MCOperand Imm:1> <MCOperand Reg:0> <MCOperand Imm:42> <MCOperand Reg:0> <MCOperand Reg:35>>

movq rax, 42

[0x48,0x89,0x04,0x25,0x2a,0x00,0x00,0x00]Binary

Instruction

LLVM MC

34c3 - Implementing an LLVM based DBI framework28

Page 29: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

LLVM MC• It’s minimalist

• It’s totally generic

• still encodes a lot of things about an instruction

• But very raw

• genericness means some heavy compromises

• doesn’t encode everything about an instruction

34c3 - Implementing an LLVM based DBI framework29

Page 30: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Creation

movq [rip+0x2600], rax

<MCInst #1139 MOV64mr <MCOperand Reg:41> <MCOperand Imm:1> <MCOperand Reg:0> <MCOperand Imm:0x2600> <MCOperand Reg:0> <MCOperand Reg:35>>

Every instruction is encoded using the same representation…

… but in a different way

34c3 - Implementing an LLVM based DBI framework30

Page 31: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Modification

<MCInst #1141 JMP_1 <MCOperand Imm: 0x41424242>>

<MCInst #1139 JMP64m <MCOperand Reg:41> <MCOperand Imm:1> <MCOperand Reg:0> <MCOperand Imm:0x2600> <MCOperand Reg:0>>

jmp 0x41424242 jmp [rip+0x2600]

34c3 - Implementing an LLVM based DBI framework31

Page 32: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch

mov r0, [r0+pc] ; Load a value relative to PC0x410000:

34c3 - Implementing an LLVM based DBI framework32

Page 33: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

0x7f10000: ; Load a value relative to R1mov r0, [r0+r1]

Patch

mov r1, 0x410000mov [pc+0x2600], r1

mov r1, [pc+0x2600]

; Set original instruction address

; Backup R1

; Restore R1

34c3 - Implementing an LLVM based DBI framework33

Page 34: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Abstractions

• MCInst encoding make transformations painful

• Patches can be really complex

• Many transformations are composed of generic steps

we need abstractions

34c3 - Implementing an LLVM based DBI framework34

Page 35: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch Engine

Patch EngineMCInst

MCInst

MCInst

MCInst

Abstractions Inside™

34c3 - Implementing an LLVM based DBI framework35

Page 36: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

36

Page 37: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL

• Identify transformation steps required to patch instructions

• Regroup and integrate them as a domain-specific language

• Instructions are architecture specifics…

• …DSL should be generic (as much as possible)

Abstractions you said?

34c3 - Implementing an LLVM based DBI framework37

Page 38: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSLRegistry

Memory

Program QBDI

Reg

Context

Temp

Shadows,Metadata

Copy

Load/Save

Write

Get/S

et

34c3 - Implementing an LLVM based DBI framework38

Page 39: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL

Temp(0)

mov [pc+0x2600], r1

mov r1, 0x410000

[…]

mov r1, [pc+0x2600]

34c3 - Implementing an LLVM based DBI framework39

Page 40: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL

SubstituteWithTemp(Reg(REG_PC), Temp(0))

mov [pc+0x2600], r1

mov r1, 0x410000

mov r0, [r0+r1]

mov r1, [pc+0x2600]

34c3 - Implementing an LLVM based DBI framework40

Page 41: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL

• Modifications are defined in rules

• A rule is composed of

• one (or several) condition(s)

• one (or several) action(s)

• Actions can modify or replace an instruction

34c3 - Implementing an LLVM based DBI framework41

Page 42: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL /* Rule #3: Generic RIP patching. * Target: Any instruction with RIP as operand, e.g. LEA RAX, [RIP + 1] * Patch: Temp(0) := rip * LEA RAX, [RIP + IMM] --> LEA RAX, [Temp(0) + IMM] */ PatchRule( UseReg(Reg(REG_PC)), { GetPCOffset(Temp(0), Constant(0)), ModifyInstruction({ SubstituteWithTemp(Reg(REG_PC), Temp(0)) }) } );

34c3 - Implementing an LLVM based DBI framework42

Page 43: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Patch DSL /* Rule #0: Simulating BX instructions. * Target: BX REG * Patch: Temp(0) := Operand(0) * DataOffset[Offset(PC)] := Temp(0) */ PatchRule( Or({ OpIs(llvm::ARM::BX), OpIs(llvm::ARM::BX_pred) }), { GetOperand(Temp(0), Operand(0)), WriteTemp(Temp(0), Offset(Reg(REG_PC))) } );

34c3 - Implementing an LLVM based DBI framework43

Page 44: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Lessons Learned

• LLVM provides robust foundations for modifying binary code

• Abstractions on top of it are:

• vital to make quite a simple intermediate representation do complex things

• very (very) hard to conceptualise

34c3 - Implementing an LLVM based DBI framework44

Page 45: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Designing a DBI: 2. Cross-Architecture Support

34c3 - Implementing an LLVM based DBI framework45

Page 46: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Host and GuestProcess

Host

DBI Engine

Instrumentation Tool

Guest

Original Binary

Instrumented Code

34c3 - Implementing an LLVM based DBI framework46

Page 47: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Context Switch

• They share the same memory and the same CPU context

• We need to switch between those two contexts at every cycle

• No help from the kernel or the CPU

34c3 - Implementing an LLVM based DBI framework47

Page 48: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Context Switch

• Save / restore CPU context from guest / host

• Avoid any side effects on the guest

• We can’t modify its stack

• We can’t erase any register

➡ We need to relatively address host memory from the guest

34c3 - Implementing an LLVM based DBI framework48

Page 49: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Relative Addressing• Constrained by CPU architecture capabilities

• Limited to +/- 4096 under ARM

➡ We need host memory next to guest code

• We want to play nice with Data Execution Prevention

➡ Allocate 2 contiguous memory pages:

• Code block in Read eXecute

• Data block in Read Write

34c3 - Implementing an LLVM based DBI framework49

Page 50: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

ExecBlockCode Block RX

Prologue

Instrumented Code

Epilogue

Data Block RW

Guest Context

Host Context

34c3 - Implementing an LLVM based DBI framework50

Page 51: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

ExecBlock

• Bind instrumented code and instrumentation data

• Data is guaranteed to be directly addressable

• 4 KB pages give us a lot of space…

• We can put multiple instrumented basic blocks in the code block

• We can put more than just context in the data block

34c3 - Implementing an LLVM based DBI framework51

Page 52: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Things Got More Complex …Code Block RX

Prologue JMP selector

Basic Block 0

Epilogue

Data Block RW

Guest Context

Host Context selector

Basic Block 1

Constants & Shadows

34c3 - Implementing an LLVM based DBI framework52

Page 53: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Making 4K Useful

• Instrumentation constants

• used in the same way as ARM’s literal pool

• Instruction shadows

• “instruction analog” to Valgrind's memory shadow

• instrumentation variable abstraction

• can be used to record memory accesses

34c3 - Implementing an LLVM based DBI framework53

Page 54: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

What We Need

• A cross-platform memory management abstraction

• allocating memory pages

• changing page permissions

• A cross-architecture assembler working in-memory

• It’s not just about building binary objects in-memory

34c3 - Implementing an LLVM based DBI framework54

Page 55: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Guess What?

34c3 - Implementing an LLVM based DBI framework55

Page 56: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

LLVM JIT• LLVM already has several JIT engine

• They are very well designed…

• …but none of them fitted our strict constraints

• LLVM provides everything to create a custom one

• cross-architecture memory management abstraction

• powerful in-memory assembler (LLVM MC)

34c3 - Implementing an LLVM based DBI framework56

Page 57: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Lessons learned

• LLVM is perfect for creating a JIT

• Designing a JIT engine for DBI is hard

• Really easy to make a design locked down on a particular CPU architecture

• Portability need to be taken into account from the start

34c3 - Implementing an LLVM based DBI framework57

Page 58: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

QBDI

• Linux, macOS, Windows, Android and iOS

• User friendly

• easy to use C/C++ APIs

• extensive documentation

• binary packages for all major OS

• Modular design (Unix philosophy)

QuarkslaB Dynamic binary Instrumentation is a modular, cross-platform and cross-architecture DBI framework

34c3 - Implementing an LLVM based DBI framework58

Page 59: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

QBDI• Modularity stands for:

• core only provides what is essential

• don’t force users to do thing in your way

• easy integration everywhere

• Fun and flexible Python bindings

• Full featured integration with Frida

34c3 - Implementing an LLVM based DBI framework59

Page 60: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Roadmap• Improve ARM architecture support

• Thumb-2

• Memory Access information

• ARMv8 (AArch64)

• Add SIMD memory access

• Multithreading and exceptions

• probably not as part of the core engine (KISS)34c3 - Implementing an LLVM based DBI framework60

Page 61: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Demo time!

34c3 - Implementing an LLVM based DBI framework61

Page 62: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

pyQBDI

import pyqbdi;

def printInstruction(vm, gpr, fpr, data): inst = vm.getInstAnalysis() print "0x%x %s" % (inst.address, inst.disassembly) return pyqbdi.CONTINUE

def pyqbdipreload_on_run(vm, start, stop): state = vm.getGPRState() success, addr = pyqbdi.allocateVirtualStack(state, 0x100000) funcPtr = ctypes.cast(aLib.aFunction, ctypes.c_void_p).value vm.addInstrumentedModuleFromAddr(funcPtr) vm.addCodeCB(pyqbdi.PREINST, printInstruction, None) vm.call(funcPtr, [42])

34c3 - Implementing an LLVM based DBI framework62

Page 63: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Frida / QBDI

34c3 - Implementing an LLVM based DBI framework63

Page 64: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Give it a try

• https://qbdi.quarkslab.com/

• https://github.com/quarkslab/QBDI

• Free software under permissive license (Apache 2)

• All suggestions / pull requests are most welcome

• #qbdi on freenode

Many thanks to Paul and djo for their major contributions to this release!

Page 65: Implementing an LLVM based DBI framework · Use Cases • Finding memory bugs: • Track memory allocations / deallocations • Track memory accesses • Fuzzing: • Measure code

Any questions?