Paradyn Project
Paradyn / Dyninst WeekCollege Park, Maryland
March 26-28, 2012
Modifying Binaries with Dyninst
Andrew Bernat, Bill Williams
Binary Modification
2Binary Modification with Dyninst
Insert error checking and
handling
Predicate switching
Dynamic patching
Code surgery
Goalso Use familiar abstractions
oCFGo Snippets
o Platform independent
o SafeoAvoid side-effectso Prevent invalid control flow
3Binary Modification with Dyninst
Outlineo Related Work: Binary Modification
Techniques
o Theory: Structured Binary Editing
o Practice: PatchAPI Interface
o Example: Hot Patching Apache Vulnerabilities
4Binary Modification with Dyninst
Related Work
5Binary Modification with Dyninst
Insn 1
Insn 2
Insn 3
Insn 4
Insn 5
Insn 6 ...
Block 1 Block 2 ...
Function1
Fine grainedUser must preserve validity
Requires architecture
expertise
Coarse grained Safe
DynamoRIOValgrindSecondWrite
DyninstPIN
Diablo
User must preserve validity
Theory: Structured Binary Editing
6Binary Modification with Dyninst
Original CFG Transformed CFGOriginal Binary Transformed Binary
Invalid CFG
CFG Validityo Block validity
oBlocks contain valid instruction sequenceso Edge validity
o Edges point to valid (block) targetso Edge types correspond with branches/calls
7Binary Modification with Dyninst
CallNot Taken
Valid Invalid(no target)
Invalid(invalid target)
Valid (PowerPC/ARM)Invalid (x86/x86-64)
CFG Transformationso Simple: block split, edge redirection
o Complex: inserting conditional branches or calls
8Binary Modification with Dyninst
Composition: Function Unsharing
9Binary Modification with Dyninst
Handling Indirect Control Flowo Transforming the CFG can alter indirect
control flowoCorrupting function pointeroAltering jump table index
o Detect alterations with slice-based analysis
o Spectrum of possible responses:oAllow transformationoDisallow transformationo Insert runtime monitoring code
10Binary Modification with Dyninst
Practice: PatchAPI Interface
11Binary Modification with Dyninst
Dyninst
ParseAPI
A Dyninst Component
Dataflow API
A Dyninst Component
ProcControl
APIA Dyninst
Component
Patch API
A Dyninst Component
Stack Walker
APIA Dyninst
Component
DynCA Dyninst
Component
SymtabAPI
A Dyninst Component
InstructionAPI
A Dyninst Component
CodegenA Dyninst
Component
o Point/Snippet instrumentation interface
o Interactive modification interface
o Changes not reflected at BPatch layero Greatly simplifies
implementationo Callbacks for
updating user data
PatchAPI Overviewo CFG classes
o PatchBlock, PatchEdge, PatchFunctiono Binary file class
o PatchObjecto Instrumentation
o Point, PatchMgro Modification
o PatchModifier, PatchCallback
12Binary Modification with Dyninst
, Snippet
(BETA) class Snippeto bool generate(Point *point, Buffer
&buffer)o Point provides context for code generationoBuffer is a code container
o Convert BPatch_snippets to PatchAPI::Snippets
o Inherit to define your own Snippets
13Binary Modification with Dyninst
(BETA) class PatchModifiero bool redirect(PatchEdge *, PatchBlock
*);o PatchBlock *split(PatchBlock *,
Address);o bool remove(vector<PatchBlock *>);o bool remove(PatchFunction *);o InsertedCode::Ptr insert(PatchObject *, SnippetPtr, Point
*);o class InsertedCode:
oPatchBlock *entry()ovector<PatchEdge *> &exits()oset<PatchBlock *> &blocks()
14Binary Modification with Dyninst
(BETA) class PatchCallbacko Interface class for CFG modification
updateso Register one (or more) child classeso Notify on CFG element:
oCreationoDestructionoBlock splittingoNew in-edge or out-edgeoRemoved in-edge or out-edge
o Notify on Point creation, destruction, or change 15Binary Modification with Dyninst
Example: Hot Patching Apache Vulnerability o Apache 2.2.21 has several
vulnerabilities:oUsing reverse proxy to access arbitrary
servero Privilege escalation via .htaccess fileoDenial of service with badly formatted
cookieo (and others)
o We used binary modification to patch these flawsoAct on unprepared, executing httpd
daemonoDo not rely on specific compiler version(s)oCreate “click to run” patching tool
16Binary Modification with Dyninst
CVE-2011-3368o Reverse proxy functionality broken in
Apacheo Introduced in 1.3.xo Fixed in 2.3.15 (released November 16,
2011)o Attacker sends illegal URI
oGET @hiddenServer/hiddenFileo Proxy incorrectly forwards request
oGET proxy@hiddenServer/hiddenFileo Attacker can access internal files
17Binary Modification with Dyninst
Hot Patching Overviewo Create CFG “fingerprint” that identifies
patch site(s)oDo not rely on addresses, functions, or
particular instruction sequenceso Create snippets from security patch file
oAccess and update local variableso Insert conditional error handling
o Modify binary to incorporate new codeoMatching patch file
18Binary Modification with Dyninst
Patch File
19Binary Modification with Dyninst
ap_parse_uri(r, uri);
+ if (r->method_number != M_CONNECT+ && !r->parsed_uri.scheme+ && uri[0] != ‘/’+ && !(uri[0] == ‘*’ && uri[1] == ‘\0’)) {+ r->args = NULL;+ r->hostname = NULL;+ r->status = HTTP_BAD_REQUEST;+ }
if (ll[0]) { r->assbackwards = 0; pro = ll; ...
Error ConditionDetection
Error Handling
CFG Fingerprinting
20Binary Modification with Dyninst
ap_parse_uri(r, uri);if (ll[0]) { r->assbackwards = 0; pro = ll; len = strlen(ll);}else { r->assbackwards = 1; pro = “HTTP/0.9”; len = 8;}
ap_parse_uri
strlen
Snippet (error detection)
21Binary Modification with Dyninst
// r->method_number != M_CONNECTboolExpr cond1(ne, r_method_number, constExpr(M_CONNECT));
// !r->parsed_uri.schemeboolExpr cond2(eq, r_parsed_uri_scheme, constExpr(0));
// uri[0] != ‘/’boolExpr cond3(ne, arithExpr(deref, uri), constExpr(‘/’));
// !(uri[0] == ‘*’ && uri[1] == ‘\0’)boolExpr cond4(or, boolExpr(ne, arithExpr(deref, uri), constExpr(‘*’)), boolExpr(ne, arithExpr(deref, ...)));
boolExpr cond(and, boolExpr(and, cond1, cond2), boolExpr(and, cond3, cond4));
Snippet (error handling)
22Binary Modification with Dyninst
// r->args = NULL;arithExpr body1(assign, r_args, constExpr(0));
// r->hostname = NULL;arithExpr body2(assign, r_hostname, constExpr(0));
// r->status = HTTP_BAD_REQUESTarithExpr body3(assign, r_status, constExpr(HTTP_BAD_REQUEST));
// r->uri = apr_pstrdup(r->pool, uri)vector<snippet> call_args;call_args.push_back(r_pool);call_args.push_back(uri);arithExpr body4(assign, r_uri, funcCallExpr(findFunction(“apr_pstrdup”), call_args));
Modification Code
23Binary Modification with Dyninst
b2
ap_parse_uri
b1
strlen
bool patch(PatchBlock *b1, PatchBlock *b2, SnippetPtr snip, Point *point) { IC::Ptr code = PatchModifier::insert(b1->obj(), snip, point);
// Redirect fallthrough of ap_parse_uri call to // the entry of the inserted code region PatchModifier::redirect(getEdge(b1, CALL_FT), code->entry());
// Redirect exits of inserted code to b2 for (iterator iter = code->exits().begin(); iter != code->exits().end(); ++iter) { PatchModifier::redirect(*iter, b2);}
Hot Patching
24Binary Modification with Dyninst
ap_parse_uri
strlenapr_pstrdu
p
Error Detection
Error Handlingap_parse_
uri
Summaryo Structured binary editing
oModify binaries by transforming their CFGso Ensure validity of the resulting binary
o PatchAPI implementationo Interactive CFG modificationoMix modification and instrumentationoCallback interface for updating user data
25Binary Modification with Dyninst
Bernat and Miller, “Structured Binary Editing with a
CFG Transformation Algebra”