SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
Dynamically Overriding Mac OS X
                           Down the Rabbit Hole
                              Jonathan ‘Wolf’ Rentzsch
                                 http://rentzsch.com




Monday, February 9, 2009
“These rules are no different than
  those of a computer system.

                 Some of them can be bent.
                  Others... can be broken.”
                                   —Morpheus
Monday, February 9, 2009
What Happened to
                How to Hack Mac OS X?
           The paper’s original title was “How to Hack Mac OS X”
           However, “hacking” is just too abused, especially in the
           Unix realm.
           Really, think “trap patching”. However:
                 On Mac OS X, traps aren’t used nearly as often.
                 “Patching” also has a specific definition in the Unix
                 realm: applying textual differences to source code.
           Thus, “dynamic overriding”.
Monday, February 9, 2009
Dynamic Overriding Defined
           The ability to modify software at runtime...
                 ...often in ways not originally anticipated by the
                 software’s original authors.
           Can suppress, change or extend existing functionality.
           Can add wholly new functionality to existing software.
           The modifications exist only in memory:
                 Never written to disk (save VM swapping).
                 Not permanent.
                 Easy to rollback — restart the app.
Monday, February 9, 2009
Dynamic Overriding
                                    Overriding:
                           Made possible by two
                           techniques that work
                                 together

            Function    Code
           Overriding Injection
Monday, February 9, 2009
Function Overriding
           Unlike the classic Mac OS, Mac OS X does not
           directly support dynamically overriding system
           functions.
           At best, APIs exposed with Objective C interfaces can
           be overridden with categories and/or posing. Major
           limitations:
                 Requires the API be exposed in ObjC. Excludes all of
                 Mach, BSD and Carbon.
                 Overriding an ObjC wrapper does not override the
                 original function. Override will not effect all of the
                 app if it has mixed procedural/objective code.
Monday, February 9, 2009
Function Overriding
           Ideally, overriding a system function would be simple:
                 Discover the function’s entry in a universal table.
                 Save off a pointer to the original code.
                 Replace it with a pointer to your overriding code.
           Alas, Mach’s linking model lacks any sort of centralized
           bottleneck. This stands in contrast to CFM.




Monday, February 9, 2009
CFM’s Model
                              Exporter-Owned Vector Table (i.e. CFM)
                              App Module
                                                    System Module
                           implementation block
                                                   implementation block

                               loadPlugins
                                                            free

                                   main
                                                           calloc


                           vector table (import)           malloc
                                   main
                               loadPlugins
                                                    vector table (export)
                                  malloc
                                                           malloc
                                                           calloc
                            Plugin Module
                                                            free
                           implementation block


                                   main



                           vector table (import)

                                   main
                                  malloc




Monday, February 9, 2009
CFM vs Mach
            Exporter-Owned Vector Table (i.e. CFM)            Importer-Owned Vector Table (i.e. Mach)
            App Module                                       App Module
                                  System Module
         implementation block                             implementation block
                                 implementation block

              loadPlugins                                     loadPlugins
                                          free
                                                                                   System Module
                  main                                            main
                                                                                  implementation block
                                         calloc

                                                                                           free
         vector table (import)                            vector table (import)
                                         malloc
                  main                                            main
                                                                                          calloc
              loadPlugins                                     loadPlugins
                                  vector table (export)
                 malloc                                          malloc
                                         malloc                                           malloc
                                         calloc
           Plugin Module                                   Plugin Module
                                          free
         implementation block                             implementation block     vector table (export)

                                                                                          malloc
                                                                  main
                  main
                                                                                          calloc
                                                                                           free
                                                          vector table (import)
         vector table (import)

                                                                  main
                  main
                                                                 malloc
                 malloc



Monday, February 9, 2009
Function Overriding
           You may think that you could walk all loaded modules
           to discover and rewrite all their vector tables.
           That won’t work:
                 Lazy binding means symbols aren’t resolved until
                 they’re first used.You’d have to force resolving of all
                 symbols before rewriting: expensive and tricky.
                 All the work needs to be done again when a new
                 module is loaded.
                 Won’t work for symbols looked up programatically.

Monday, February 9, 2009
Function Overriding
           What will work: rewrite the original function
           implementation, in memory, itself.
           Basic premise: replace the original function’s first
           instruction with a branch instruction to the desired
           override code.
           This technique is known as single-instruction
           overwriting.
           You may shudder now...



Monday, February 9, 2009
Single-Instruction Overwriting
           Benefits:
                 Atomic replacement. Safe in the face of multiple
                 preemptive threads calling the original function.
                 Less likely to harmfully impact the original code. If you
                 wish to reenter the original function from the
                 override, you’ll need to re-execute the replaced
                 instruction. Moving less code around makes this
                 more likely to work.
                 Compatibility. Works with the widest variety of
                 function prologs and other patching
                 implementations (including our own!)
Monday, February 9, 2009
Single-Instruction Overwriting
           Replacing a single instruction is good, but limiting.
           Can’t branch to an arbitrary address, as that would
           take at least three instructions.
           Leaves us with branch instructions that encode their
           targets:
                 b (branch relative)
                 ba (branch absolute)
                 bl (branch relative, update link register)
                 bla (branch absolute, update link regiter)
Monday, February 9, 2009
Single-Instruction Overwriting
           bl and bla go away since they stomp on the link
           register — that houses the caller’s return address!
           b and ba embed a 4-byte-aligned, 24-bit address.
           For b, that’s ±32MB relative to the current program
           counter. We really can’t guarantee our override will
           be within 32MB of the original function.
           For ba, that’s the lowermost and uppermost 32MB of
           the current address space. The lowermost 32MB
           tends to be busy with loaded code and data.
           That leaves ba’s uppermost 32MB of address space.
Monday, February 9, 2009
The Branch Island
           We can allocate a single page at the end of the
           address space to hold our branch island.
           (Mach’s sparse memory model works nicely here.)
           The branch island acts as a level of indirection,
           allowing the address-limited ba to effectively target
           any address.
           Two uses for branch islands: escape and reentry.




Monday, February 9, 2009
Branch Islands
           Escape branch island (required):
                 Used to jump from the original function to the
                 overriding function.
                 Allocated at the end of the address space.
                 What our generated ba instruction points at.
           Reentry branch island:
                 Optional, only generated if you wish to reenter the
                 original function.
                 Houses the original function’s first instruction.
Monday, February 9, 2009
Inside the Branch Island
           C definition:
           long kIslandTemplate[] = {
              0x9001FFFC,
              0x3C00DEAD,
              0x6000BEEF,
              0x7C0903A6,
              0x8001FFFC,
              0x60000000,
              0x4E800420
           };
           What, you guys don’t read machine language?!?

Monday, February 9, 2009
Branch Islands for Dummies
                  Opcode          Assembly            Comment
                                            save off original r0 into
   0x9001FFFC              stw r0,-4(SP)
                                            red zone
                                            load the high half of
   0x3C00DEAD              lis r0,0xDEAD
                                            address
                                            load the low half of
   0x6000BEEF              ori r0,r0,0xBEEF
                                            address
                                            load target into counter
   0x7C0903A6              mtctr r0
                                            register
                                                restore original r0
   0x8001FFFC              lwz r0,-4(SP)
                                                optional original first
   0x60000000              nop
                                                instruction (for
                                                reentry) the target in
                                                branch to
   0x4E800420              bctr
                                                counter register
Monday, February 9, 2009
Lame Override Animation
                           ! Initial State




                                        myMalloc




                                         malloc


                                       malloc client




Monday, February 9, 2009
Lame Override Animation
                           ! Escape Island Allocated
                             and Targeted



                                       myMalloc


                                     escape island


                                        malloc


                                     malloc client




Monday, February 9, 2009
Lame Override Animation
                           ! Reentry Island Allocated,
                             Targeted & Engaged

                                     reentry island


                                       myMalloc


                                     escape island


                                        malloc


                                      malloc client




Monday, February 9, 2009
Lame Override Animation
                           ! Escape Island Atomically
                             Engaged
                                     reentry island


                                       myMalloc


                                     escape island


                                        malloc


                                     malloc client




Monday, February 9, 2009
Function Overriding Details
           Discover the function’s address. Use
           _dyld_lookup_and_bind[with_hint]()
           and NSIsSymbolNameDefined[WithHint]().
           Test the waters. Watch out for functions that start with
           the mfctr instruction.
           Make the original function writable. vm_protect().
           Allocate the escape island. Use vm_allocate().
           Target the escape island and make it executable. Use
           msync().

Monday, February 9, 2009
Function Overriding Details
           Build the branch instruction. Target the escape island.
           Optionally allocate and engage the reentry island.
           Atomically:
                 Insert the original function’s first instruction into the
                 reentry island. If reentry is desired.
                 Target the reentry island and make it executable. Again,
                 if reentry is desired.
                 Swap the original function’s first instruction with the
                 generated ba instruction. If atomic replacement fails
                 (unlikely), loop and try again.
Monday, February 9, 2009
Code Injection Overview
           Function overriding is a powerful technique, but it’s
           only attains half of our goal.
           By itself, we can only override system functions in our
           own software.
           Code injection, on the other hand, allows us override
           application and system functions in any process.
           Not just override functions, but inject new Objective
           C classes (example: for posing)



Monday, February 9, 2009
Code Injection Overview
           Mach supplies everything we need.
           It’s just not very well documented. ; )
           Specifically, Mach provides APIs for:
                 Remote memory allocation. (vm_allocate())
                 Remote memory I/O. (vm_write())
                 Remote thread allocation. (thread_create())
                 Remote thread control.
                 (thread_create_running())

Monday, February 9, 2009
Code Injection Details
           Allocate a remote thread stack. No need to populate it
           — parameters will be passed in registers.
           Allocate and populate the thread’s code block. The gotcha
           here is determining the thread entry’s code size. It’s
           surprisingly hard, and requires a calling the dynamic
           loader APIs and stat()’ing the file system!
           Allocate, populate and start the thread. Set the thread
           control block’s srr0 to the code block, r1 to the
           stack, r3 through r10 to parameters and lr to
           0xDEADBEEF (this thread should never return).

Monday, February 9, 2009
Code Injection Leakage
           While the injected thread can stop itself, it can’t
           delete itself (it would need to deallocate its own stack
           and code while running).
           May be work-arounds, like the injected thread
           spawning another “normal” cleanup thread.
           Another solution is to install a permanent “injection
           manager” thread, that would start a Mach server to
           handle future injections via IPC.
                 Bonus feature: such an “injection server” would
                 eliminate the need to start a new thread per
                 injection.
Monday, February 9, 2009
Code & Doc Availability
           Two packages, both written in C:
                 mach_override: Implements function overriding.
                       http://rentzsch.com/mach_override
                 mach_inject: Implements code injection.
                       http://rentzsch.com/mach_inject
                 Code is hosted by Extendamac (BSD-style license)
                       http://extendamac.sourceforge.net


Monday, February 9, 2009
Conclusion


                            “Whoa.”
                                   —Neo




Monday, February 9, 2009

Contenu connexe

Similaire à Dynamic Overriding

Build Comet applications using Scala, Lift, and <b>jQuery</b>
Build Comet applications using Scala, Lift, and <b>jQuery</b>Build Comet applications using Scala, Lift, and <b>jQuery</b>
Build Comet applications using Scala, Lift, and <b>jQuery</b>
tutorialsruby
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />
tutorialsruby
 
Plug-in Architectures
Plug-in ArchitecturesPlug-in Architectures
Plug-in Architectures
elliando dias
 
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
IBM India Smarter Computing
 
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILABCOMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
Wildan Maulana
 

Similaire à Dynamic Overriding (20)

Pragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWarePragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWare
 
JVL MacComm OCX File
JVL MacComm OCX FileJVL MacComm OCX File
JVL MacComm OCX File
 
Plugin-based IVI Architectures with Qt
Plugin-based IVI Architectures with Qt Plugin-based IVI Architectures with Qt
Plugin-based IVI Architectures with Qt
 
Build Comet applications using Scala, Lift, and <b>jQuery</b>
Build Comet applications using Scala, Lift, and <b>jQuery</b>Build Comet applications using Scala, Lift, and <b>jQuery</b>
Build Comet applications using Scala, Lift, and <b>jQuery</b>
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />
 
Nuxeo 5.2 Glassfish
Nuxeo 5.2 GlassfishNuxeo 5.2 Glassfish
Nuxeo 5.2 Glassfish
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 
Linux KVM のコードを追いかけてみよう
Linux KVM のコードを追いかけてみようLinux KVM のコードを追いかけてみよう
Linux KVM のコードを追いかけてみよう
 
Acceleo Code Generation
Acceleo Code GenerationAcceleo Code Generation
Acceleo Code Generation
 
A simplest way to reconstruct .Net Framework - CRB Tech
A simplest way to reconstruct .Net Framework - CRB TechA simplest way to reconstruct .Net Framework - CRB Tech
A simplest way to reconstruct .Net Framework - CRB Tech
 
A simplest-way-to-reconstruct-.net-framework
A simplest-way-to-reconstruct-.net-frameworkA simplest-way-to-reconstruct-.net-framework
A simplest-way-to-reconstruct-.net-framework
 
On Software Release Engineering (Bram Adams)
On Software Release Engineering (Bram Adams)On Software Release Engineering (Bram Adams)
On Software Release Engineering (Bram Adams)
 
Makefile
MakefileMakefile
Makefile
 
Flex Continuous Quality Builds Flex & (Ant || Maven)
Flex Continuous Quality Builds Flex & (Ant || Maven)Flex Continuous Quality Builds Flex & (Ant || Maven)
Flex Continuous Quality Builds Flex & (Ant || Maven)
 
Plug-in Architectures
Plug-in ArchitecturesPlug-in Architectures
Plug-in Architectures
 
Mac OS X Manual
Mac OS X ManualMac OS X Manual
Mac OS X Manual
 
Building the VM
Building the VMBuilding the VM
Building the VM
 
Caliburn.micro
Caliburn.microCaliburn.micro
Caliburn.micro
 
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
IBM’s System Director VMControl: Advanced Multi-Platform Virtualization Manag...
 
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILABCOMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
COMPARATIVE STUDY OF MATLAB AND ITS OPEN SOURCE ALTERNATIVE SCILAB
 

Dernier

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 

Dynamic Overriding

  • 1. Dynamically Overriding Mac OS X Down the Rabbit Hole Jonathan ‘Wolf’ Rentzsch http://rentzsch.com Monday, February 9, 2009
  • 2. “These rules are no different than those of a computer system. Some of them can be bent. Others... can be broken.” —Morpheus Monday, February 9, 2009
  • 3. What Happened to How to Hack Mac OS X? The paper’s original title was “How to Hack Mac OS X” However, “hacking” is just too abused, especially in the Unix realm. Really, think “trap patching”. However: On Mac OS X, traps aren’t used nearly as often. “Patching” also has a specific definition in the Unix realm: applying textual differences to source code. Thus, “dynamic overriding”. Monday, February 9, 2009
  • 4. Dynamic Overriding Defined The ability to modify software at runtime... ...often in ways not originally anticipated by the software’s original authors. Can suppress, change or extend existing functionality. Can add wholly new functionality to existing software. The modifications exist only in memory: Never written to disk (save VM swapping). Not permanent. Easy to rollback — restart the app. Monday, February 9, 2009
  • 5. Dynamic Overriding Overriding: Made possible by two techniques that work together Function Code Overriding Injection Monday, February 9, 2009
  • 6. Function Overriding Unlike the classic Mac OS, Mac OS X does not directly support dynamically overriding system functions. At best, APIs exposed with Objective C interfaces can be overridden with categories and/or posing. Major limitations: Requires the API be exposed in ObjC. Excludes all of Mach, BSD and Carbon. Overriding an ObjC wrapper does not override the original function. Override will not effect all of the app if it has mixed procedural/objective code. Monday, February 9, 2009
  • 7. Function Overriding Ideally, overriding a system function would be simple: Discover the function’s entry in a universal table. Save off a pointer to the original code. Replace it with a pointer to your overriding code. Alas, Mach’s linking model lacks any sort of centralized bottleneck. This stands in contrast to CFM. Monday, February 9, 2009
  • 8. CFM’s Model Exporter-Owned Vector Table (i.e. CFM) App Module System Module implementation block implementation block loadPlugins free main calloc vector table (import) malloc main loadPlugins vector table (export) malloc malloc calloc Plugin Module free implementation block main vector table (import) main malloc Monday, February 9, 2009
  • 9. CFM vs Mach Exporter-Owned Vector Table (i.e. CFM) Importer-Owned Vector Table (i.e. Mach) App Module App Module System Module implementation block implementation block implementation block loadPlugins loadPlugins free System Module main main implementation block calloc free vector table (import) vector table (import) malloc main main calloc loadPlugins loadPlugins vector table (export) malloc malloc malloc malloc calloc Plugin Module Plugin Module free implementation block implementation block vector table (export) malloc main main calloc free vector table (import) vector table (import) main main malloc malloc Monday, February 9, 2009
  • 10. Function Overriding You may think that you could walk all loaded modules to discover and rewrite all their vector tables. That won’t work: Lazy binding means symbols aren’t resolved until they’re first used.You’d have to force resolving of all symbols before rewriting: expensive and tricky. All the work needs to be done again when a new module is loaded. Won’t work for symbols looked up programatically. Monday, February 9, 2009
  • 11. Function Overriding What will work: rewrite the original function implementation, in memory, itself. Basic premise: replace the original function’s first instruction with a branch instruction to the desired override code. This technique is known as single-instruction overwriting. You may shudder now... Monday, February 9, 2009
  • 12. Single-Instruction Overwriting Benefits: Atomic replacement. Safe in the face of multiple preemptive threads calling the original function. Less likely to harmfully impact the original code. If you wish to reenter the original function from the override, you’ll need to re-execute the replaced instruction. Moving less code around makes this more likely to work. Compatibility. Works with the widest variety of function prologs and other patching implementations (including our own!) Monday, February 9, 2009
  • 13. Single-Instruction Overwriting Replacing a single instruction is good, but limiting. Can’t branch to an arbitrary address, as that would take at least three instructions. Leaves us with branch instructions that encode their targets: b (branch relative) ba (branch absolute) bl (branch relative, update link register) bla (branch absolute, update link regiter) Monday, February 9, 2009
  • 14. Single-Instruction Overwriting bl and bla go away since they stomp on the link register — that houses the caller’s return address! b and ba embed a 4-byte-aligned, 24-bit address. For b, that’s ±32MB relative to the current program counter. We really can’t guarantee our override will be within 32MB of the original function. For ba, that’s the lowermost and uppermost 32MB of the current address space. The lowermost 32MB tends to be busy with loaded code and data. That leaves ba’s uppermost 32MB of address space. Monday, February 9, 2009
  • 15. The Branch Island We can allocate a single page at the end of the address space to hold our branch island. (Mach’s sparse memory model works nicely here.) The branch island acts as a level of indirection, allowing the address-limited ba to effectively target any address. Two uses for branch islands: escape and reentry. Monday, February 9, 2009
  • 16. Branch Islands Escape branch island (required): Used to jump from the original function to the overriding function. Allocated at the end of the address space. What our generated ba instruction points at. Reentry branch island: Optional, only generated if you wish to reenter the original function. Houses the original function’s first instruction. Monday, February 9, 2009
  • 17. Inside the Branch Island C definition: long kIslandTemplate[] = { 0x9001FFFC, 0x3C00DEAD, 0x6000BEEF, 0x7C0903A6, 0x8001FFFC, 0x60000000, 0x4E800420 }; What, you guys don’t read machine language?!? Monday, February 9, 2009
  • 18. Branch Islands for Dummies Opcode Assembly Comment save off original r0 into 0x9001FFFC stw r0,-4(SP) red zone load the high half of 0x3C00DEAD lis r0,0xDEAD address load the low half of 0x6000BEEF ori r0,r0,0xBEEF address load target into counter 0x7C0903A6 mtctr r0 register restore original r0 0x8001FFFC lwz r0,-4(SP) optional original first 0x60000000 nop instruction (for reentry) the target in branch to 0x4E800420 bctr counter register Monday, February 9, 2009
  • 19. Lame Override Animation ! Initial State myMalloc malloc malloc client Monday, February 9, 2009
  • 20. Lame Override Animation ! Escape Island Allocated and Targeted myMalloc escape island malloc malloc client Monday, February 9, 2009
  • 21. Lame Override Animation ! Reentry Island Allocated, Targeted & Engaged reentry island myMalloc escape island malloc malloc client Monday, February 9, 2009
  • 22. Lame Override Animation ! Escape Island Atomically Engaged reentry island myMalloc escape island malloc malloc client Monday, February 9, 2009
  • 23. Function Overriding Details Discover the function’s address. Use _dyld_lookup_and_bind[with_hint]() and NSIsSymbolNameDefined[WithHint](). Test the waters. Watch out for functions that start with the mfctr instruction. Make the original function writable. vm_protect(). Allocate the escape island. Use vm_allocate(). Target the escape island and make it executable. Use msync(). Monday, February 9, 2009
  • 24. Function Overriding Details Build the branch instruction. Target the escape island. Optionally allocate and engage the reentry island. Atomically: Insert the original function’s first instruction into the reentry island. If reentry is desired. Target the reentry island and make it executable. Again, if reentry is desired. Swap the original function’s first instruction with the generated ba instruction. If atomic replacement fails (unlikely), loop and try again. Monday, February 9, 2009
  • 25. Code Injection Overview Function overriding is a powerful technique, but it’s only attains half of our goal. By itself, we can only override system functions in our own software. Code injection, on the other hand, allows us override application and system functions in any process. Not just override functions, but inject new Objective C classes (example: for posing) Monday, February 9, 2009
  • 26. Code Injection Overview Mach supplies everything we need. It’s just not very well documented. ; ) Specifically, Mach provides APIs for: Remote memory allocation. (vm_allocate()) Remote memory I/O. (vm_write()) Remote thread allocation. (thread_create()) Remote thread control. (thread_create_running()) Monday, February 9, 2009
  • 27. Code Injection Details Allocate a remote thread stack. No need to populate it — parameters will be passed in registers. Allocate and populate the thread’s code block. The gotcha here is determining the thread entry’s code size. It’s surprisingly hard, and requires a calling the dynamic loader APIs and stat()’ing the file system! Allocate, populate and start the thread. Set the thread control block’s srr0 to the code block, r1 to the stack, r3 through r10 to parameters and lr to 0xDEADBEEF (this thread should never return). Monday, February 9, 2009
  • 28. Code Injection Leakage While the injected thread can stop itself, it can’t delete itself (it would need to deallocate its own stack and code while running). May be work-arounds, like the injected thread spawning another “normal” cleanup thread. Another solution is to install a permanent “injection manager” thread, that would start a Mach server to handle future injections via IPC. Bonus feature: such an “injection server” would eliminate the need to start a new thread per injection. Monday, February 9, 2009
  • 29. Code & Doc Availability Two packages, both written in C: mach_override: Implements function overriding. http://rentzsch.com/mach_override mach_inject: Implements code injection. http://rentzsch.com/mach_inject Code is hosted by Extendamac (BSD-style license) http://extendamac.sourceforge.net Monday, February 9, 2009
  • 30. Conclusion “Whoa.” —Neo Monday, February 9, 2009