Category Archives: Blog

Sign a kext in Xcode8 for macOS Sierra 12

This post provides a solution in case you changed the Code Signing Identity fields in Xcode8 and see this error: "osx-pl2303 has conflicting provisioning settings. osx-pl2303 is automatically provisioned, but code signing identity Developer ID Application: BJA Electronics () has been manually specified. Set the code signing identity value to "Mac Developer" in the build settings editor, or switch to manual provisioning in the target editor."

This error occurs when the provisioning profile is automatic, which cannot be changed in the Kext project panels of Xcode8 and the Mac Developer identity has not been selected.

The solution for this error is:
– Close the project
– Open the contents of the project file (in my case osx-pl2303.pbxproj)
– Open the file project.pbxproj in a editor
– Search for ProvisioningStyle and set it to:
ProvisioningStyle = Manual;
– Open again your project, you can now freely select Code Signing Identities

How to interpret OS X Crash Logs using LLDB

Debugging kernel extensions surrounds you with less comfort as debugging applications running in user space. You can’t use debugging environments offered by IDEs and if a crash occurs, your computer will even shut down; The Kernel Panic. Especially, when you have shipped kernel extensions, such as drivers, these kernel panics are really undesired. However, as kernel programming is highly complex and most code runs in different threads, and memory allocation should all be handled by the programmer, one cannot easily avoid these panics. When you code is shipped to dozens of different configured systems, it is just a matter of time of your first user, or client, will report a Panic. You receive a report, which is cryptic for your client, and also for you… The report only contains hex-numbers, and you are expected to be the expert who can read them. This blog will help you understand OS X Crash Log reports. How you can read them, and how they will help you improve your OS X kernel extensions.

1. The Crash Log Report

Debugging an extension starts with  the crash report. The report looks cryptic, but contains all information you need to reconstructed the location where the crash occurred. Actually, the crash report is a stack trace without symbols (like function names) and it contains all information to look up these symbols using the LLDB debugger.

Look at the following error report:

*** Panic Report ***
panic(cpu 2 caller 0xffffff801265c266): "A kext releasing a(n) IOUSBInterface has corrupted the registry."@/SourceCache/xnu/xnu-2782.20.48/libkern/c++/OSObject.cpp:219
Backtrace (CPU 2), Frame : Return Address
0xffffff811e9a3d30 : 0xffffff801212bda1
0xffffff811e9a3db0 : 0xffffff801265c266
0xffffff811e9a3e00 : 0xffffff7f94857b6f
0xffffff811e9a3e20 : 0xffffff7f948579df
0xffffff811e9a3e40 : 0xffffff7f94857255
0xffffff811e9a3e70 : 0xffffff80126b3cad
0xffffff811e9a3eb0 : 0xffffff80126b379f
0xffffff811e9a3f30 : 0xffffff80126ae553
0xffffff811e9a3f70 : 0xffffff80126b4443
0xffffff811e9a3fb0 : 0xffffff80122125b7
      Kernel Extensions in backtrace:
         nl.repleo.osx-ch341(1.0)[C7A7FB19-256A-3FAA-9D05-AEF4EE7131DD]@0xffffff7f94856000->0xffffff7f94860fff
            dependency: com.apple.iokit.IOUSBFamily(720.4.4)[0D6EABE6-1CC7-348C-8BE2-AF04F66722BF]@0xffffff7f92e23000
            dependency: com.apple.iokit.IOSerialFamily(11)[0453BE0D-DB4F-3A51-9CFC-9A93615CCF3E]@0xffffff7f93134000
 
BSD process name corresponding to current thread: kernel_task
 
Mac OS version:
14D136
 
Kernel version:
Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64
Kernel UUID: 4B3A11F4-77AA-3D27-A22D-81A1BC5B504D
Kernel slide:     0x0000000011e00000
Kernel text base: 0xffffff8012000000
__HIB  text base: 0xffffff8011f00000
System model name: MacBook8,1 (Mac-BE0E8AC46FE800CC)

It contains the following information:

  • The exception message and its stacktrace;
  • The kernel extensions mentioned in the stacktrace including the memory location where they are loaded;
  • The OS X kernel build version;
  • The memory locations where the kernel is loaded.

2. Prerequisites for using LLDB to symbolicate the kernel panic

The debugger LLDB is the preferred tool for OS X to perform advanced debugging activities like analyzing crash reports. Before you can use LLDB to symbolicate the crash report, you need to collect the symbolicated binaries of all code of interest. In this example: the kernel, and the osx-ch341 driver.

To get the symbolicated kernel, visit the developer download site of Apple: https://developer.apple.com/downloads/index.action?q=Kernel%20Debug%20Kit. The kernel kit required for this example is version 10.10.3 (14D136), as can be read in the crash report. After running the installation program, the symbolicated kernel is stored in /Library/Developer/KDKs/.

Second, you need symbolicated kernel extensions. Make sure that your kernel extension is compiled with all debugging symbols enabled.

3. Starting LLDB and loading modules

It is now time to start LLDB. Open a terminal, and provide the command: xcrun lldb. You will see the prompt: (lldb). Load the kernel of the crash log: target create --no-dependents --arch x86_64 /Library/Developer/KDKs/KDK_10.10.3_14D136.kdk/System/Library/Kernels/kernel
Load_Kernel_Symbols

Load the kernel extension(s) you need to interpret the stacktrace of the crash report: target modules add /tmp/osx-ch341.kext/Contents/MacOS/osx-ch341
Load_KEXT_symbols

You can check that the modules are loaded using the command: image list. When running this command, you will see the modules are loaded at default memory locations. To use the modules for the earlier showed crash report, we need to set the memory locations to the ones mentioned in the crash report.

Following the crash report, the kernel slide is loaded at  0x0000000011e00000 and the ch341 kext drivers offset start at 0xffffff7f94856000. To set the offsets of the kernel we need to run the following commands: target modules load --file kernel --slide 0x000000000b600000 and target modules load --file osx-ch341 __TEXT 0xffffff7f898fb000.

Set_base_addresses

You can verify the offsets are correctly set by using again the command: image list.

4. Symbolicate the stack trace

LLDB is now ready for decrypt the crash log reported by the kernel. The stacktrace shows a list of return addresses. In this case we are only interested in the return addresses of our ch341 driver. That are the addresses in the range of 0xffffff7f94856000->0xffffff7f94860fff. The image lookup -a command will show where these numbers point to.

Lookup_symbol_at_address_1 Lookup_symbol_at_address_2 Lookup_symbol_at_address_3

In our example we can build up this part of the stacktrace:

  • osx-ch341`nl_repleo_driver_ch341::MetaClass::~MetaClass() + 3 at osx_ch341.h:44
  • osx-ch341`nl_repleo_driver_ch341::createPort() + 589 at osx_ch341.cpp:314
  • osx-ch341`nl_repleo_driver_ch341::allocateResources() + 203 at osx_ch341.cpp:379

This stack trace points to the code causing the panic, and now we are able to solve the problem, or prevent a crash by adding failure handling.

5. conclusions

We showed how you can symbolicate crash logs of OS X using LLDB. Crash logs can provide relevant information about problems in your kernel extensions.

Detect Private Calls in iOS App Code

Apple requires that apps only use the public API’s provided by iOS. This tutorial describes how you can list the outbound calls and dependencies of your app and how you can verify they are allowed. Especially, when you are using third party libraries, disallowed dependencies can be created. Manually reviewing these libraries can be very time consuming, and is at least not the aim of using libraries.

 1. Locate the App binary

First, create an archive of you app via the Product menu in Xcode. The binary is located in a xcarchive file. These files are stored in:

  • $home/Library/Developer/Xcode/Archives/<date>/<appname><datetime>.xcarchive/

Open a Terminal and change directory to this path.  The app is located in:

  • Products/Applications/<appname>.app

The binary is located in the root of the app directory and its name is <appname>

2. Library Dependencies

The linked libraries can be listed using otool. The command is otool -L <binary>. An example:

otool output linked libraries app

This list can be scanned for libraries which should not be linked, like the obvious IOKit and WebKit library.

3. Linked Symbols

The list of linked symbols can be obtained using the nm -u command. The output will look like:

nm list all linked symbols

You can use this list to detect:

  • Undocumented C functions;
  • Private Objective-C classes;
  • Ivars

4. What’s next?

Unfortunately, Apple is not providing a list of forbidden symbols. You may search Apple’s documents for every referred symbol to check if it is documented.

 

Swift IOS AddressBook: Cast Optional AnyObject without Null Pointer Exception

The runtime environment of Apple’s Swift contains an error in handling optional AnyObjects. This blog discusses a workaround for this crash.

Swift is a new language created by Apple making iOS programming easier. Swift code runs on the operating system stack of a Mac or iPhone, and it uses a runtime library for type handling and memory allocation. A swift-programmer would normally never be bothered by null-pointer checking (introduction of optionals), allocating memory (no retain, release) and unnecessary untyped variables (syntax for casting). An isolated environment supports developers to write correct, and working, code in different situations. For example, null-pointer checking cannot be performed in swift, as null-pointer handling is performed by the optional syntax. These language constructs avoid runtime crashes caused by the famous null-pointer exception, which is a huge benefit for reliability of applications.

For example, in Swift, one can write a cast of an optional AnyObject to String as follows:

var result:String = "";
var _result:AnyObject = _objc_result.takeRetainedValue()
if let __result: String = _result as? String {
  result = __result ;
}
println(result);

The theory is nice, however, in practice it only holds if the typing and runtime library are implemented (and designed) correctly. Unfortunately, the dynamic runtime library of swift in IOS 8.1.2 (and earlier) contains a bug regarding casting optional AnyObject types: The code presented above will crash if it tries to lookup the type of a nil-AnyObject:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Triggered by Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libswiftCore.dylib            	0x00000001003964e8 0x10021c000 + 1549544
1   libswiftCore.dylib            	0x0000000100372bf4 0x10021c000 + 1403892

The crash is caused by the var as? type expression. The runtime library tries first to type the variable, instead of checking whether it is set or not. This lookup causes a null-pointer exception if it has no value, which is allowed for an optional! Of course, this issue will probably be fixed in newer releases of iOS 8 🙂

As we want to publish also apps today, we present a workaround in this blog. As earlier stated, Swift hides the existence of nil via optionals, so we need a trick. A common way in programming to enable super-power is to escape a lower execution environment, and fortunately Swift allows that. The proposed solution uses a short Objective-C for the casting, preventing Swift from crashing.

The header file (.h):

@interface AddressBookWrapper : NSObject

- (NSString *) anyObjectToString:(id) object;

@end

The code file (.m):

#import <Foundation/Foundation.h>

#import "AddressBookWrapper.h"

@implementation AddressBookWrapper

- (NSString *) anyObjectToString:(id) object {
    if (object != nil && [object isKindOfClass:[NSString class]]) {
      NSString *result = [NSString stringWithFormat:@"%@", object];
      return result;
    } else {
      return @"";
    }
}

@end

The calling code in Swift:

private func extractStringProperty(propertyName : ABPropertyID) -> String? {
   var result:String = ""
     if let _result = ABRecordCopyValue(self.internalRecord, propertyName)? {
         var addressBookWrapper: AddressBookWrapper = AddressBookWrapper()
         var __result:AnyObject = _result.takeRetainedValue()
         result = addressBookWrapper.anyObjectToString(__result)
     }
     return result;
}

We wrote the wrapper as class, we keep writing it as a static function as exercise for the reader :-).

The Swift code calls the wrapper before the value is used for further processing. The wrapper ensures that the value is safe in the context of Swift, and that it will not cause a run-time exception.

The AddressBook of iOS is implemented in C, and bridging code is necessary to access the AddressBook from a Swift-based application. The wrapper as described above is necessary to access the values from the AddressBook within Swift. In case a field is empty, i.e. nil, the Swift-based application will crash if the Objective-C wrapper is not used.

This bug is not reproducible if the code is executed via Xcode, but only occurs when an App is published as .ipa.