Dynamic Frameworks
来源:互联网 发布:apache 开源框架 编辑:程序博客网 时间:2024/06/04 19:54
A dynamic framework
is a bundle of code loaded into an executable at runtime, instead of at compile time.
Examples in iOS include UIKit and the Foundation frameworks. Frameworks such as these contain a dynamic library and optionally assets, such as images.
The most obvious advantage is you can make updates to the framework without having to recompile the executable that depends on the framework.
Why dynamic frameworks?
Since you’ve the ability to load the framework at runtime, you can use LLDB to explore and execute code at runtime, which is great for spelunking in both public and private frameworks.
Statically inspecting an executable’s frameworks
The loading of these dynamic libraries into memory is done using a piece of code called the dynamic loader, or dyld
Open Xcode and create a new iOS project, Single View Application named DeleteMe. Yep, this project won’t hang around for long, so feel free to remove it once you’re done with this chapter.
Add the Social and CallKit framework. To the right of the CallKit framework, select Optional from the drop-down. Ensure that the Social framework has the Required value
Build the project on the simulator using Cmd + B. Do not run just yet. Once the project has been successfully built for the simulator, open the products directory in the Xcode project navigator.
Next, open up the DeleteMe IPA by right clicking the IPA and selecting Show Package Contents.
Next, open a new Terminal window and type the following but don’t press Enter:
otool -L
Be sure to add a space at the end of the command. Next, drag the DeleteMe executable from the Finder window into the Terminal window. When finished, you should have a command that looks similar to the following:
devzkndeMacBook-Pro:.ssh devzkn$ otool -l /Users/devzkn/Library/Developer/Xcode/DerivedData/DeleteMe-ctwthypddlppxtdxhfdyydtqqytb/Build/Products/Debug-iphonesimulator/DeleteMe.app/DeleteMe
Press Enter and observe the output. You’ll see something similar to the following:
/System/Library/Frameworks/CallKit.framework/CallKit (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/Social.framework/Social (compatibility version 1.0.0, current version 87.0.0) /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 1238.50.2) /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.7.47)
You found the compiled binary DeleteMe and dumped out the list of dynamic frameworks it links to using the ever-so-awesome otool. Take note of the instructions to CallKit and the Social framework you manually added earlier. By default, the compiler automatically adds the “essential” frameworks to the iOS app, like UIKit and Foundation.
Take note of the directory path responsible for loading these frameworks;
/System/Library/Frameworks//usr/lib/
Let’s go a tad bit deeper. Remember how you optionally required the CallKit framework, and required the Social framework? You can view the results of these decisions by using otool.
In Terminal, press the up arrow to recall the previous Terminal command. Next, change the capital L to a lowercase l and press Enter. You’ll get a longer list of output that shows all the load commands for the DeleteMe executable.
Load command 12 cmd LC_LOAD_DYLIB cmdsize 80 name /System/Library/Frameworks/CallKit.framework/CallKit (offset 24) time stamp 2 Thu Jan 1 08:00:02 1970 current version 1.0.0compatibility version 1.0.0Load command 13 cmd LC_LOAD_WEAK_DYLIB cmdsize 80 name /System/Library/Frameworks/Social.framework/Social (offset 24) time stamp 2 Thu Jan 1 08:00:02 1970 current version 87.0.0compatibility version 1.0.0
Compare the cmd in the load commands output. In Social, the load command is LC_LOAD_WEAK_DYLIB, which represents an optional framework, while the LC_LOAD_DYLIB of the CallKit load command indicates a required framework.
This is ideal for an application that supports multiple iOS versions. For example, if you supported iOS 9 and up, you would strongly link the Social framework and weak link the CallKit framework since it’s only available in iOS 10 and up.
Modifying the load commands
here’s a nice little command that lets you augment and add the framework load commands named install_name_tool.
n Xcode and build and run the application so the simulator is running DeleteMe. Once running in the LLDB Terminal, verify the CallKit framework is loaded into the DeleteMe address space. Pause the debugger, then type the following into LLDB:
image list CallKit
If the CallKit module is correctly loaded into the process space, you’ll get output similar to the following:
(lldb) image list CallKit[ 0] 6558009B-6179-370D-ADD7-F9003764AFD3 0x0000000106e0e000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk//System/Library/Frameworks/CallKit.framework/CallKit
Provided DeleteMe is running, this will give you the full path of DeleteMe under the simulator app. You’ll get output similar to the following:
devzkndeMacBook-Pro:.ssh devzkn$ pgrep -fl DeleteMe21401 /Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/F0E41560-57C8-45F2-80E0-C0D04B4C6209/DeleteMe.app/DeleteMe
You’ll now modify this executable’s load commands to point to a different framework.
Grab the fullpath to the DeleteMe executable.
Stop the execution of the DeleteMe executable and temporarily close Xcode. If you were to accidentally build and run the DeleteMe application through Xcode at a later time, it would undo any tweaks you’re about to make.
In the same Terminal window, paste the full path you received from the output of your pgrep command along with the install_name_tool command as follows:
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool [-change old new] ... [-rpath old new] ... [-add_rpath new] ... [-delete_rpath old] ... [-id name] input
devzkndeMacBook-Pro:.ssh devzkn$ install_name_tool -change /System/Library/Frameworks/Social.framework/Social /System/Library/Frameworks/NotificationCenter.framework/NotificationCenter /Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/F0E41560-57C8-45F2-80E0-C0D04B4C6209/DeleteMe.app/DeleteMe
Verify if your changes were actually applied:
devzkndeMacBook-Pro:.ssh devzkn$ otool -L /Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/F0E41560-57C8-45F2-80E0-C0D04B4C6209/DeleteMe.app/DeleteMe/Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/F0E41560-57C8-45F2-80E0-C0D04B4C6209/DeleteMe.app/DeleteMe: /System/Library/Frameworks/CallKit.framework/CallKit (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/NotificationCenter.framework/NotificationCenter (compatibility version 1.0.0, current version 87.0.0) /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 1238.50.2) /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.7.47)
Verify these changes exist at runtime.
lldb -n DeleteMe
devzkndeMacBook-Pro:.ssh devzkn$ lldb -n DeleteMe(lldb) process attach --name "DeleteMe"Process 24703 stopped* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP frame #0: 0x000000010e85834a libsystem_kernel.dylib` mach_msg_trap + 10libsystem_kernel.dylib`mach_msg_trap:-> 0x10e85834a <+10>: ret 0x10e85834b <+11>: nop libsystem_kernel.dylib'mach_msg_overwrite_trap: 0x10e85834c <+0>: mov r10, rcx 0x10e85834f <+3>: mov eax, 0x1000020 0x10e858354 <+8>: syscall 0x10e858356 <+10>: ret 0x10e858357 <+11>: nop libsystem_kernel.dylib'semaphore_signal_trap: 0x10e858358 <+0>: mov r10, rcxExecutable module set to "/Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/F0E41560-57C8-45F2-80E0-C0D04B4C6209/DeleteMe.app/DeleteMe".Architecture set to: x86_64h-apple-ios.
In LLDB, check if the CallKit framework is still loaded.
ou’re in a bit of a predicament here. If you build and run a new version of DeleteMe using Xcode, it will erase these changes. Instead, launch the DeleteMe application through the simulator and then attach to it in a new LLDB Terminal window. To do this, launch DeleteMe in the simulator. Next, type the following into Terminal:
lldb -n DeleteMe```
(lldb) image list NotificationCenter
(lldb) image list CallKit
[ 0] 6558009B-6179-370D-ADD7-F9003764AFD3 0x000000010a86c000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/CallKit.framework/CallKit
(lldb) image list NotificationCenter
[ 0] 6BD68E1B-EF6D-37F9-8CF2-705851074B36 0x000000010a90c000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/NotificationCenter.framework/NotificationCenter
27460 /Users/devzkn/Library/Developer/CoreSimulator/Devices/03FD7AC9-0B1A-41C1-8790-9CF914D33B68/data/Containers/Bundle/Application/CF4DB53B-949E-45E8-A362-CEB1AFA3290D/DeleteMe.app/DeleteMe
27584 /Applications/Xcode.app/Contents/Developer/usr/bin/lldb -n DeleteMe
Loading frameworks at runtime-----------------------------Start by adding the following to your ~/.lldbinit file:
command regex ls ‘s/(.+)/po @import Foundation; [[NSFileManager
defaultManager] contentsOfDirectoryAtPath:@”%1” error:nil]/’
This creates a command named ls, which will take the directory path you give it and dump out the contents. This command will work on the directory of the device that’s being debugged. For example, since you’re running on the simulator on your computer’s local drive it will dump that directory. If you were to run this on an attached iOS, tvOS or other appleOS device, it would dump the directory you give it on that device, with one minor caveat which you’ll learn about shortly.Since LLDB is already running and attached to DeleteMe, you’ll need to load this command into LLDB manually as well since LLDB has already read the ~/.lldbinit file. Type the following into your LLDB session: (lldb) command source ~/.lldbinitNext, find the full path to the frameworks directory in the simulator by typing thefollowing:
(lldb) image list -d UIKit
[ 0] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework
You actually want to go one level higher to the Frameworks directory. Copy that full directory path and use the new command ls that you just created, like so:
(lldb) ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk//System/Library/Frameworks/
<__NSArrayM 0x608000052b70>(
Accelerate.framework,
Accounts.framework,
AddressBook.framework,
AddressBookUI.framework,
AdSupport.framework,
AssetsLibrary.framework,
From the list of frameworks, load the Speech framework into the DeleteMe process space like so:
process load /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk//System/Library/Frameworks/Speech.framework/Speech
Loading “/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk//System/Library/Frameworks/Speech.framework/Speech”…ok
Image 0 loaded.
====================Exploring frameworks--------------------
Exploring frameworks
devzkndeMacBook-Pro:~ devzkn$ lldb -n DeleteMe
Add the following to your ~/.lldbinit file.
Load this command into the active LLDB session and then give it a go with the Social framework.
(lldb) command source ~/.lldbinit
(lldb) dump_stuff Social
Loading frameworks on an actual iOS device------------------------------------------if you’re running on an actual iOS device, the frameworks path will be located at:
/System/Library/Frameworks/
“`
- Dynamic Frameworks
- Frameworks
- dynamic
- @dynamic
- Dynamic
- @dynamic
- dynamic
- dynamic
- dynamic
- @dynamic
- @dynamic
- Ajax Frameworks
- PHP Frameworks
- Flex Frameworks
- IOS Frameworks
- 编译frameworks
- android frameworks
- Frameworks & Modules
- Delphi中的ADOquery 用法以及ADOquery的自有方法Append 和Delete和 Edit 和Post
- 故都的秋-郁达夫
- React Native
- AMD-SDK的学习[2]--AtomicCounters
- 滑动后自动加载基础详解OnScrollListener
- Dynamic Frameworks
- shader实例(三)物体描边
- java线程池和队列
- 再见了,城堡
- Scoket编程--UDP
- android 三级界面返回直接到一级界面
- 行人属性“Weakly-supervised Learning of Mid-level Features for Pedestrian Attribute Recognition and Loca”
- 20.Container With Most Water
- 6、用vue2.0extend写alert模态框弹窗组件