MobSF: Solve #rpath violation - ios

We tested one of our iOS app with MobSF and the report highlighted that the binary has Runpath Search Path (#rpath) set.
In certain cases an attacker can abuse this feature to run arbitrary executable for code execution and privilege escalation.
I ran otool -L against the binary to check which dependencies are concerned. It turns out that all pods (Cocaopod) and and some system libraries are concerned.
name #rpath/Alamofire.framework/Alamofire (offset 24)
name #rpath/libswiftCoreAudio.dylib (offset 24)
name #rpath/libswiftCoreData.dylib (offset 24)
name #rpath/libswiftCoreFoundation.dylib (offset 24)
I wonder how to fix this issue. Cocoapods prints a warning if the project build setting Runpath Search Paths does not include $(inherited).
Is using #rpath considered harmful?
Any help/information appreciated.

The Runpath Search Path instructs the dynamic linker to search for a dynamic library (dylib) on an ordered list of paths, sort of like how Unix looks for binaries on $PATH.
If your application uses the Swift Package Manager, in order to compile the libraries without rpath you need to use some hidden build flags. On your local command line run:
Note the swift compiler option no-stdlib-rpath which disables rpath entries during compilation.
Configure your build settings so that the application is built with this configuration flag, e.g.: swift build -c release -Xswiftc -no-toolchain-stdlib-rpath.
Alternatively, if your application uses Cocoapods, you can first check the install directory of the pods:
And then use the following configuration on your Podfile:
For reference - MobSF IPA Binary Analysis

Related

Renaming an iOS Framework after it's been built

I've built a framework from modified open source C++ code for use in another development sdk. Apps are not able to use this sdk if they have another sdk that also depends on this framework. How can I re-namespace this framework after its already been built (changing MyFramework.xcframework -> MyNewFramework.xcframework).
After renaming all of the references I could find, I was still getting a linker error on install: dyld: Library not loaded: #rpath/MyFramework.framework/MyFramework Referenced from: /private/var/containers/Bundle/Application/[app] Reason: image not found
This requires updating the name of the framework everywhere:
Open MyFramework.framework directory (if using an XCFramework, this will require opening the .xcframework directory and repeating these steps for the .frameworks for both the x86_64 and arm64 architectures.)
Open the Info.plist and change the Bundle name and Executable file to MyNewFramework. You will also want to update the bundle id
Open Modules/module.modulemap. Change the uses of MyFramework to MyNewFramework:
framework module MyNewFramework {
umbrella header "MyNewFramework.h"
export *
module * { export * }
}
Open the Headers directory and for each and every header file in there, you'll need to change all of the imports of other local header files: #import <MyFramework/Something.h> -> #import <MyNewFramework/Something.h> (I would suggest a global find and replace for #import <MyFramework/).
Change the file in the Headers directory MyFramework.h to MyNewFramework.h
Change the name of the executable found in the framework directory from MyFramework to MyNewFramework
Once navigated to the MyFramework.framework directory, run the command: otool -l MyNewFramework | grep rpath. It should echo something like this: name #rpath/MyFramework.framework/MyFramework as one of the options. Copy this path.
Using the command copied from step 6, Replace the instances of MyFramework with MyNewFramework run this command: (changing #rpath/MyNewFramework.framework/MyNewFramework if different from what you'd copied)
install_name_tool -id #rpath/MyNewFramework.framework/MyNewFramework MyNewFramework
Confirm that renaming the rpath was successful by running otool -l MyNewFramework again and checking that the path has been updated to MyNewFramework.
Rename the name of the entire framework from MyFramework.framework to MyNewFramework.framework
If using an XCFramework, navigate outside of the architectures to the Info.plist found directly in the .xcframework directory. Under AvailableLibraries in both Item 0 and Item 1 change LibraryPath from MyFramework.framework to MyNewFramework.framework.
If using an XCFramework, don't forget to rename the name of the outermost directory from MyFramework.xcframework to MyNewFramework.xcframework.
To ensure there aren't any hanging references, delete derived data (rm -rf ~/Library/Developer/Xcode/DerivedData/). Make sure to tear down your dependencies and re-integrate them with the renamed one. (For cocoapods, this involves updating your Podfile or podspec with the new framework name, then running pod deintegrate && pod install.)
Whew! What a job! Go fix yourself a nice cup of something.
Note: verify that this doesn't cause any issues while building and exporting your app. If so, consider disabling Bitcode if that's a viable option for you.

Using CMake to copy .frameworks to iOS app bundle

A library I'm using recently switched to distribution as a .framework.
In my existing CMake file, I've been successful at getting it to link with my iOS app, but am getting:
dyld: Library not loaded: #rpath/Pizza.framework/Pizza
Referenced from: /var/mobile/Containers/Bundle/Application/D71ED298-C287-4B2F-8AFA-710A14C06D75/pizzashop.app/pizza
Reason: image not found
when I install it from Xcode. If I manually add it to my xcode project, in the "embedded binaries" section then I'm good (see image below)
So I've concluded that the problem is getting the .framework into my app bundle. I've come across this question and looked at the linked QT example, but I'm still trying to orient myself here as I'm finding the syntax a bit opaque.
Is CMake's BundleUtilities what I want to use here? In looking at the BundleUtilities example I'm a bit lost:
set(APPS ...) # paths to executables
set(DIRS ...) # directories to search for prerequisites
INSTALL(CODE "
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
" COMPONENT Runtime)
Is this OSX-specific or can I apply it similarly to iOS?
We didn't end up finding an ideal solution, and ended up doing things a bit more manually than preferred:
We added a custom command we run after the build is complete, but before it is packaged (see CMake's add_custom_command).
The custom command does the following:
creates a Frameworks directory under our app bundle folder (make sure it's somewhere where it will get copied in your packaging process).
we use cp -aH to copy all frameworks into this Frameworks directory
we then re-sign each framework in this directory using:
codesign --force --verbose Computers.framework --sign "$2"
Add the Frameworks directory to your search paths:
set_target_properties(${EXE_NAME} PROPERTIES
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "#executable_path/Frameworks")

how to build DLIB for iOS

I'm trying to build DLIB for an iOS project. Running the cmake results in a libdlib.a and a load of .o files.
When I add the library to an Xcode project I get warning that the library hasn't been built for arm64.
My question is two-part:
How can I build DLIB for iOS (I tried cmake **path_to_source** -DCMAKE_OSX_ARCHITECTURE="arm64" but it caused loads of errors e.g. unknown type name '__uint32_t'; did you mean '__uint128_t')?
What is the purpose of all the .o files that get built when you run cmake? Do I need to include them in an Xcode project?
I finally figured out how to do this:
Requirements
X11 (on a mac you can just open the X11 app and if X11 isn't installed it'll take you to the download).
Xcode
cmake (you can use home-brew for that)
Steps
In terminal make the lib-xx.xx/examples your root
Run:
mkdir build
cd build
cmake -G Xcode ..
cmake --build . --config Release
This will create a folder called dlib_build in which you can find an Xcode project that compiles the library. In the build settings of that Xcode project you can set the build architecture and SDK for any Xcode supported OS you like!
EDIT:
You have to include a lot of custom compiler flags and 3rd party libraries to get dlib to work in a project. Check out the examples.xcproject build settings.
To compliment RASS's answer, I am attaching screenshots showing how to change this to and from an iOS and OSX lib
After opening the project,
Select the project file from the project navigator
Select the dlib target all the way down the bottom
Select 'Build Settings'
Expand 'Base SDK' drop down
Select either iOS or macOS (OSX)
I hope this helps some people out! gl
Rob Sanders and mylogon already show how to build dlib for ios, here is how to use it:
add libdlib.a to project, and add path to library search paths
add all source to include directory(do not add to project), and add path to header search paths.
add accelerate framework, which contains blas symbols.
add preprocessor macros, from building settings, "custom compiler flag"/"other c flags". these macros make sure the header files match the lib.
-DDLIB_JPEG_SUPPORT
-DDLIB_NO_GUI_SUPPORT
-DNDEBUG
-DDLIB_USE_BLAS
-DDLIB_USE_LAPACK

Unity 4.6.5 project won't run on iOS simulator

Unity 4.6.5 project won't run on iOS simulator and I'm getting runtime error:
dyld: Symbol not found: _OBJC_CLASS_$_CBAnalytics
Referenced from: /Users/diverseconnection/Library/Developer/CoreSimulator/Devices/983BAC55-2713-423B-B5F3-C135ECCC2768/data/Containers/Bundle/Application/D4CAC0C7-E3D6-48F5-B264-E6EB715F9709/trouble.app/trouble
Expected in: flat namespace
in /Users/diverseconnection/Library/Developer/CoreSimulator/Devices/983BAC55-2713-423B-B5F3-C135ECCC2768/data/Containers/Bundle/Application/D4CAC0C7-E3D6-48F5-B264-E6EB715F9709/trouble.app/trouble
(lldb)
Any ideas how to fix it?
Well this error is usually rather broad as there can be number of causes. You can try these fixes
Add the correct libraries in the Link Binary With Libraries section of the Build Phases.
If you want to add a library outside of the default search path you can include the path in the Library Search Paths value in the Build Settings and add -l{library_name_without_lib_and_suffix} (eg. for libz.a use -lz) to the Other Linker Flags section of Build Settings.
You copy files into your project but forgot to check the target to add the files to. To resolve:
Open the Build Phases for the correct target, expand Compile Sources and add the missing .m files.
You include a static library that is built for another architecture like i386, the simulator on your host machine. To resolve:
If you have multiple library files from your libraries vendor to include in the project you need to include the one for the simulator (i386) and the one for the device (armv7 for example).
Optionally, you could create a fat static library that contains both architectures.
Also try this
Remove Build Active Architecture Only (build setting parameter key is 'ONLY_ACTIVE_ARCH') from all of your static libraries' project build settings or overwrite it with 'NO'

How to build ASSIMP Library for iOS (Device and Simulator) with boost-library?

I want to use the ASSIMP library http://assimp.sourceforge.net in an iOS project. Unfortunately, I'm not very experienced with makefiles and that stuff, so I need some help.
I've downloaded the sources and first I tried to build with make (in the code-subfolder)
In the makefile I've added INCLUDEFLAGS = -I/Lib because my boost header-files are in /Lib/boost
Executing make static succeeds with some warnings. A static library (.a) is generated.
Then I tried to add the .a-file to my xcode-project and specified the assimp-header folder as additional include directory (Other Search Paths). Linking failed with the message that the library has not the right architecture (i386 required for the simulator)
file libassimp.a outputs: "libassimp.a: current ar archive random library"
How can I build the library for the i386 architcture and for arm6 or arm7, whatever I need on an iOS device?
Is it ok to use the boost-headers only or is it better/necessary to build boost as a library? Currently I'm using boost headers only, which should be fine since boost is a header only library?!
There is also a cmake - makefile (CMakeLists.txt). cmake is the recommended way of building the library but I don't have any experience with cmake.
Or another thought: Is it possible to build a library via xcode?
The final result should be a library for i386, arm6 and arm7 architecture.
What shall I do? And how?
Edit:
I've just discovered that there are the following preprocessor checks in the file aiDefines.h:
#if defined(_MSC_VER)
// See http://msdn.microsoft.com/en-us/library/b0084kay.
# if defined(_M_IX86)
# define ASSIMP_BUILD_X86_32BIT_ARCHITECTURE
# elif defined(_M_X64)
# define ASSIMP_BUILD_X86_64BIT_ARCHITECTURE
# elif defined(_M_IA64)
# define ASSIMP_BUILD_IA_64BIT_ARCHITECTURE
# else
# error unknown architecture
# endif
#elif defined(__GNUC__)
// See http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html.
# if defined(__x86_32__) || defined(__i386__)
# define ASSIMP_BUILD_X86_32BIT_ARCHITECTURE
# elif defined(__x86_64__)
# define ASSIMP_BUILD_X86_64BIT_ARCHITECTURE
# elif defined(__ppc__)
# define ASSIMP_BUILD_PPC_32BIT_ARCHITECTURE
# else
# error unknown architecture
# endif
#else
# error unknown compiler
#endif
Does this mean, it is not possible to compile the ASSIMP library for ARM architecture?
I personally don't do any iOS development, but I know that others have successfully compiled Assimp for their iDevices using Xcode. An Xcode 3 project should be included with the distribution, although I don't know if you can use it without further modification.
The architecture preprocessor defines are currently only used for logging output (in code/Importer.cpp), and support for ARM has been added to trunk in the meantime (r919, to be exact).
I also had a few issues getting assimp to work on iOS devices.
Here's what I did in case anyone is also having similar issues - similar to Artur Sampaio's example above, but with a few differences:
get the latest assimp from https://github.com/assimp/assimp, i.e., git clone git://github.com/assimp/assimp.git
cd into the assimp directory and open up CMakeLists.txt. For some reason, the make file couldn't find my glut and gl libs, so I commented out the lines in CMakeLists.txt that referred to making the samples, i.e., the "IF ( BUILD_ASSIMP_SAMPLES)" block of code. There's probably a simple way to point to these, but since I didn't need the samples I just did commented those lines out.
cd to port/iOS/ and then sudo ./build_ios.sh (it takes a few minutes to compile all 3 versions of the lib).
now if you cd to assimp/lib/ios and lipo -info libassimp.a you will see that the library is a fat file with i386, arm6 and arm7 architectures (and will work on both the simulator and the arm6 or arm7 device).
to get it to work in XCode 4.3.2, drag&drop the libassimp.a file into my project (from the finder). You don't have to actually copy it over to your project directory, it doesn't hurt if you do though.
for some reason, a build will still fail unless you explicitly link to the libz dynamic library. Click the main project from the XCode file list, select TARGETS, then click on the Build Settings tab, scroll down to the Linking section, and then add "/usr/lib/libz.dylib" under "Other Linker Flags".
the current version of assimp on github seems to have restructured the code somewhat, and while all of the examples I tested from the assimp website work, they all require different, or at least renamed, header files:
Here I've commented out the previous names of the headers and below are the new names:
//#include <assimp.hpp> // C++ importer interface
//#include <aiScene.h> // Output data structure
//#include <aiPostProcess.h> // Post processing flags
#include "Importer.hpp"
#include "scene.h"
#include "postprocess.h"
After this point I was able to use assimp on my iPad.
Also, you probably want to make sure that you have uninstalled other versions of assimp before doing this (eg from macports or brew).
I found branch where one guy already changed project setting for your needs. https://github.com/blandinw/assimp/tree/ios-xcode46/doc
What I did was:
download version 1090 of the Assimp repo: http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/?pathrev=1090
unzip
cd ~/Downloads/trunk/port/iOS
sudo ./build_ios.sh
(replace ~/Downloads/trunk with the path to the unzipped folder)
wait...
check libs at ~/Downloads/trunk/libs/ios/
hope that works

Resources