Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198
BiometricKit.framework: Difference between revisions - iPhone Development Wiki

BiometricKit.framework: Difference between revisions

From iPhone Development Wiki
No edit summary
m (Added some useful info)
 
(17 intermediate revisions by 9 users not shown)
Line 5: Line 5:
}}
}}


'''BiometricKit''' is the framework that handles [[TouchID]], debuted on the iPhone 5s. TouchID's internal codename is ''Mesa''. It is a private framework compiled only for arm64. You can also Google "Biokit.h", and from the Gist you can find the headers for the BiometricKit.framework. (You can also dump them yourselves; it is shipped with the iOS 7.0 SDK on Xcode and of course on an iPhone 5s.)
'''BiometricKit''' is the framework that handles [[TouchID]], present on the iPhone 5s and newer devices. TouchID's internal codename is ''Mesa''. It is a private framework compiled only for arm64. You can also Google "Biokit.h", and from the Gist you can find the headers for the BiometricKit.framework. (You can also dump them yourselves; it is shipped with the iOS 7.0 SDK on Xcode and of course on an iPhone 5s.)


== Classes ==
== Classes ==
Line 40: Line 40:
==== SBLockScreenManager of SpringBoardUIServices ====
==== SBLockScreenManager of SpringBoardUIServices ====
<tt>SBLockScreenManager</tt> <tt>- (void)biometricEventMonitor:(SBUIBiometricEventMonitor *)monitor handleBiometricEvent:(unsigned)event</tt> would always be invoked after the screen is on and a fingerprint is registered.
<tt>SBLockScreenManager</tt> <tt>- (void)biometricEventMonitor:(SBUIBiometricEventMonitor *)monitor handleBiometricEvent:(unsigned)event</tt> would always be invoked after the screen is on and a fingerprint is registered.
(Please investigate further on the meanings of the (unsigned)event. I believe 9 is for unrecognized fingerprint, 3 is for recognized fingerprint, 2 sometimes appears with 3, 1 perhaps means finger detected, 0 means nothing detected. --[[User:Jdoe|Jdoe]] ([[User talk:Jdoe|talk]]) 07:09, 4 January 2014 (PST))


==== XPC ====
==== XPC ====
Line 52: Line 50:
(If you find a workaround please edit this out. --[[User:Jdoe|Jdoe]] ([[User talk:Jdoe|talk]]) 07:06, 4 January 2014 (PST))
(If you find a workaround please edit this out. --[[User:Jdoe|Jdoe]] ([[User talk:Jdoe|talk]]) 07:06, 4 January 2014 (PST))


''Edit:'' <tt>Preferences.app</tt> initializes its own instance of BiometrikKit during enrollment, hence the lack of any signs of activity on SpringBoard while enrolling.
''Edit:'' <tt>Preferences.app</tt> initializes its own instance of BiometricKit during enrollment, hence the lack of any signs of activity on SpringBoard while enrolling.
Since the bundle is loaded at a later time than the tweak's constructor firetime, in order to access the methods we may need to use _dyld_register_func_for_add_image or a similar approach. --[[User:Limneoselias|Limneoselias]] ([[User talk:Limneoselias|talk]]) 15:16, 14 January 2014 (PST) </ref>
Since the bundle is loaded at a later time than the tweak's constructor firetime, in order to access the methods we may need to use _dyld_register_func_for_add_image or a similar approach. --[[User:Limneoselias|Limneoselias]] ([[User talk:Limneoselias|talk]]) 15:16, 14 January 2014 (PST)


=== Enrollment ===
=== Enrollment ===
Line 63: Line 61:


<tt>BiometricKit.manager</tt>'s delegate is SBUIBiometricEventMonitor.  
<tt>BiometricKit.manager</tt>'s delegate is SBUIBiometricEventMonitor.  
It also has a delegate itself , which is always SBLockScreenManager .  
It also has a delegate itself, which is always SBLockScreenManager.


Instead of everyone hooking these methods and adding their own code, probably causing conflicts to other TouchID related tweaks,
Instead of everyone hooking these methods and adding their own code, probably causing conflicts to other TouchID related tweaks,
a suggested approach that can easily maintain compatibility is to add our object as an "observer" to SBUIBiometricEventMonitor
a suggested approach that can easily maintain compatibility is to add our object as an "observer" to SBUIBiometricEventMonitor. Observers seem to only work inside of the SpringBoard process.


<tt>SBUIBiometricEventMonitor</tt> accepts observers, which we can think of as "multiple delegates", but usually with read-only or less privileged actions.  
<tt>SBUIBiometricEventMonitor</tt> accepts observers, which we can think of as "multiple delegates", but usually with read-only or less privileged actions.  
Line 72: Line 70:
An observer must conform to this protocol:
An observer must conform to this protocol:


@protocol SBUIBiometricEventMonitorDelegate
<source lang=objc>
@required
@protocol SBUIBiometricEventMonitorDelegate
-(void)biometricEventMonitor:(id)monitor handleBiometricEvent:(unsigned)event;
@required
@end
-(void)biometricEventMonitor:(id)monitor handleBiometricEvent:(unsigned)event;
@end
</source>


In <tt>handleBiometricEvent:</tt> an <tt>int</tt> value is passed after a biometric event occurs, which is very convenient to interpret and covers most tweaks' needs.
In <tt>handleBiometricEvent:</tt> an <tt>int</tt> value is passed after a biometric event occurs, which is very convenient to interpret and covers most tweaks' needs.
1 = Finger down
2 = Finger held


0 = Finger up
0 = Finger up


3 = Successful identity match
1 = Finger down, scanning


9 = Failed identity match
2 = Device requests finger to be lifted


3 = Identity match succeeded


We can create our own object that conforms to the above protocol and add it to SBUIBiometricEventMonitor:
9 = Identity match failed (Note: appears to be 10 on iOS 7.1 & iOS 8.x. Maybe from now on?)
[[[objc_getClass("BiometricKit") manager] delegate] addObserver:MyObject];


''We may need to enable or disable matching , as it is now always enabled by the system. (e.g. when no passcode is required at lock screen)''
4 = Device unlocked following successful scan


So if any tweak that uses the above approach would conflict with our actions we can :
5 = Passcode entry required


6 = Passcode entry required due to a lockout (max failed attempts)


1) Store all SBUIBiometricEventMonitor observers to a variable (or only the conflicting observer)
7 = Passcode entry required due to expired print


2) Remove all observers (or only the conflicting observer)
8 = Passcode entry required due to a reboot


3) Add our object as the observer
We can create our own object that conforms to the above protocol and add it to SBUIBiometricEventMonitor:
<source lang=objc>
[[[objc_getClass("BiometricKit") manager] delegate] addObserver:MyObject];
</source>


4) Perform our actions
''We may need to enable or disable matching, as it is not always enabled by the system. (e.g. when no passcode is required at lock screen).''


5) Replace all observers as they were before , from our stored variable
So if any tweak that uses the above approach would conflict with our actions we can:


# Store all SBUIBiometricEventMonitor observers to a variable (or only the conflicting observer)
# Remove all observers (or only the conflicting observer)
# Add our object as the observer
# Perform our actions
# Replace all observers as they were before, from our stored variable


And this should work for most tweaks.
And this should work for most tweaks.
Line 114: Line 119:
Example:
Example:


<source lang=objc>
  #define TouchIDFingerDown  1
  #define TouchIDFingerDown  1
  #define TouchIDFingerUp    0
  #define TouchIDFingerUp    0
  #define TouchIDFingerHeld  2
  #define TouchIDFingerHeld  2
  #define TouchIDMatched    3
  #define TouchIDMatched    3
  #define TouchIDNotMatched  9<br />
  #define TouchIDNotMatched  9 // or 10 for iOS 7.1 & iOS 8.x, probably from now on
  @interface AwesomeTouchIDController : NSObject <SBUIBiometricEventMonitorDelegate>{
  @interface AwesomeTouchIDController : NSObject <SBUIBiometricEventMonitorDelegate>{
       BOOL _wasMatching;
       BOOL _wasMatching;
Line 125: Line 131:
       BOOL isMonitoringEvents;
       BOOL isMonitoringEvents;
  }
  }
  @end<br />
  @end
  @implementation AwesomeTouchIDController<br />
  @implementation AwesomeTouchIDController
  -(void)biometricEventMonitor: (id)monitor handleBiometricEvent: (unsigned)event
  -(void)biometricEventMonitor: (id)monitor handleBiometricEvent: (unsigned)event
  {
  {
       switch (event
       switch (event)
       {
       {
           case TouchIDFingerDown :  
           case TouchIDFingerDown:  
                 //finger touchdown!
                 //finger touchdown!
                 break;
                 break;
           case TouchIDFingerUp
           case TouchIDFingerUp:
                 // finger removed
                 // finger removed
                 break;
                 break;
           case TouchIDFingerHeld
           case TouchIDFingerHeld:
                 // finger was held
                 // finger was held
                 break;
                 break;
           case TouchIDMatched
           case TouchIDMatched:
                 // positive match!
                 // positive match!
                 break;
                 break;
           case TouchIDNotMatched
           case TouchIDNotMatched:
                 // not matched!
                 // not matched!
                 break;
                 break;
       }<br />
       }
  }<br />
  }
  -(void)startMonitoringEvents
  -(void)startMonitoringEvents
  {
  {
Line 156: Line 162:
     isMonitoringEvents=YES;
     isMonitoringEvents=YES;
     _monitorDelegate=[[objc_getClass("BiometricKit") manager] delegate];
     _monitorDelegate=[[objc_getClass("BiometricKit") manager] delegate];
     monitor=[[objc_getClass("SBUIBiometricEventMonitor") sharedInstance];
     monitor=[objc_getClass("SBUIBiometricEventMonitor") sharedInstance];
     [[objc_getClass("BiometricKit") manager] setDelegate:monitor];
     [[objc_getClass("BiometricKit") manager] setDelegate:monitor];
     _wasMatching=[[monitor valueForKey:@"_matchingEnabled] boolValue];
     _wasMatching=[[monitor valueForKey:@"_matchingEnabled"] boolValue];
     _monitorObservers=[[monitor valueForKey:@"observers"] copy];
     _monitorObservers=[[monitor valueForKey:@"observers"] copy];
     for (int i=0; i<_monitorObservers.count;  i++)
     for (int i=0; i<_monitorObservers.count;  i++)
Line 166: Line 172:
     [monitor addObserver:self];
     [monitor addObserver:self];
     [monitor _setMatchingEnabled:YES];
     [monitor _setMatchingEnabled:YES];
     [monitor _startMatching];<br />
     [monitor _startMatching];
  }<br />
  }
  -(void)stoptMonitoringEvents
  -(void)stoptMonitoringEvents
  {<br />
  {
     if (!isMonitoringEvents)
     if (!isMonitoringEvents)
     {
     {
Line 183: Line 189:
     [[objc_getClass("BiometricKit") manager] setDelegate:_monitorDelegate];
     [[objc_getClass("BiometricKit") manager] setDelegate:_monitorDelegate];
     isMonitoringEvents=NO;
     isMonitoringEvents=NO;
    <br />
  }
  }
  .
  .
Line 189: Line 194:
  . // cleanup and release as needed
  . // cleanup and release as needed
  @end
  @end
--[[User:Limneoselias|Limneoselias]] ([[User talk:Limneoselias|talk]]) 15:16, 14 January 2014 (PST)
</source>
 
= References =
 
=== Examples ===


{| class="wikitable"
|-
! Project
! Author
|-
| [https://github.com/Sassoty/BioTesting BioTesting]
| [https://github.com/Sassoty Sassoty]
|}


{{Navbox Frameworks}}
{{Navbox Frameworks}}

Latest revision as of 02:53, 31 October 2014

BiometricKit.framework
Private Framework
Availabile 7.0 – present
Class Prefix BiometricKit
Headers [headers.cynder.me]


BiometricKit is the framework that handles TouchID, present on the iPhone 5s and newer devices. TouchID's internal codename is Mesa. It is a private framework compiled only for arm64. You can also Google "Biokit.h", and from the Gist you can find the headers for the BiometricKit.framework. (You can also dump them yourselves; it is shipped with the iOS 7.0 SDK on Xcode and of course on an iPhone 5s.)

Classes

BiometricKitIdentity

BiometricKitIdentity represents the enrolled fingerprints on the device. Properties for the user-defined name and UUID are available.

BiometricKitMatchInfo

A BiometricKitMatchInfo object has two properties:

  • A dictionary of details, including (presumably) the area of the enrolled fingerprint, the number of nodes on file, and whether the enrollment data have been updated just now from the latest scan.
  • An array of topology's of class BiometricKitEnrollProgressInfo. Currently observed to contain up to 15 "topology nodes".

BiometricKitEnrollProgressInfo

A BiometricKitEnrollProgressInfo object contains presumably the actual fingerprint digital representation as BiometricKitEnrollProgressCoordinates objects in its BKEPDNewNodeCoordinates key of messageDetails dictionary.

BiometricKitEnrollProgressCoordinates

A BiometricKitEnrollProgressCoordinates object is suspected to record the x and y coordinates and the angle (probably in radians) of the a particular fingerprint distinguishing feature.

Uses

Querying the enrolled fingerprints

You can get an array of all BiometricKitIdentity's on file with [[BiometricKit manager] identities:nil]. Note that this will only give you the user-defined names and UUIDs, but not the actual fingerprint characteristics as in BiometricKitEnrollProgressInfo.

Getting scan results

There are at least three ways you can get the scan results from the TouchID sensor.

BiometricKit manager and delegate methods

Simple to set up in your own apps. Note that if you decide to use the BiometricKit class and the BiometricKitDelegate in your own app, the app needs the entitlement of com.apple.private.bmk.allow.

SBLockScreenManager of SpringBoardUIServices

SBLockScreenManager - (void)biometricEventMonitor:(SBUIBiometricEventMonitor *)monitor handleBiometricEvent:(unsigned)event would always be invoked after the screen is on and a fingerprint is registered.

XPC

BiometricKitXPCClient - (void)matchResult:(BiometricKitIdentity *)result withDictionary:(NSDictionary *)dictionary

Issues after going into the TouchID settings

For some unknown reason, no further message would be called upon scanning if the user enters the TouchID settings under Preferences.app. The device has to be slept and unlocked in order to receive messages from the aforementioned methods again.

(If you find a workaround please edit this out. --Jdoe (talk) 07:06, 4 January 2014 (PST))

Edit: Preferences.app initializes its own instance of BiometricKit during enrollment, hence the lack of any signs of activity on SpringBoard while enrolling. Since the bundle is loaded at a later time than the tweak's constructor firetime, in order to access the methods we may need to use _dyld_register_func_for_add_image or a similar approach. --Limneoselias (talk) 15:16, 14 January 2014 (PST)

Enrollment

(Not investigated, but there are some methods regarding enrollment in this framework. Also refer to the BiometricKitUI.framework --Jdoe (talk) 07:06, 4 January 2014 (PST))

Tweak Basics

Suggested method

BiometricKit.manager's delegate is SBUIBiometricEventMonitor. It also has a delegate itself, which is always SBLockScreenManager.

Instead of everyone hooking these methods and adding their own code, probably causing conflicts to other TouchID related tweaks, a suggested approach that can easily maintain compatibility is to add our object as an "observer" to SBUIBiometricEventMonitor. Observers seem to only work inside of the SpringBoard process.

SBUIBiometricEventMonitor accepts observers, which we can think of as "multiple delegates", but usually with read-only or less privileged actions.

An observer must conform to this protocol:

@protocol SBUIBiometricEventMonitorDelegate
@required
-(void)biometricEventMonitor:(id)monitor handleBiometricEvent:(unsigned)event;
@end

In handleBiometricEvent: an int value is passed after a biometric event occurs, which is very convenient to interpret and covers most tweaks' needs.

0 = Finger up

1 = Finger down, scanning

2 = Device requests finger to be lifted

3 = Identity match succeeded

9 = Identity match failed (Note: appears to be 10 on iOS 7.1 & iOS 8.x. Maybe from now on?)

4 = Device unlocked following successful scan

5 = Passcode entry required

6 = Passcode entry required due to a lockout (max failed attempts)

7 = Passcode entry required due to expired print

8 = Passcode entry required due to a reboot

We can create our own object that conforms to the above protocol and add it to SBUIBiometricEventMonitor:

[[[objc_getClass("BiometricKit") manager] delegate] addObserver:MyObject];

We may need to enable or disable matching, as it is not always enabled by the system. (e.g. when no passcode is required at lock screen).

So if any tweak that uses the above approach would conflict with our actions we can:

  1. Store all SBUIBiometricEventMonitor observers to a variable (or only the conflicting observer)
  2. Remove all observers (or only the conflicting observer)
  3. Add our object as the observer
  4. Perform our actions
  5. Replace all observers as they were before, from our stored variable

And this should work for most tweaks.

Example:

 #define TouchIDFingerDown  1
 #define TouchIDFingerUp    0
 #define TouchIDFingerHeld  2
 #define TouchIDMatched     3
 #define TouchIDNotMatched  9 // or 10 for iOS 7.1 & iOS 8.x, probably from now on
 @interface AwesomeTouchIDController : NSObject <SBUIBiometricEventMonitorDelegate>{
      BOOL _wasMatching;
      id _monitorDelegate;
      NSArray *_monitorObservers;
      BOOL isMonitoringEvents;
 }
 @end
 @implementation AwesomeTouchIDController
 -(void)biometricEventMonitor: (id)monitor handleBiometricEvent: (unsigned)event
 {
      switch (event)
      {
           case TouchIDFingerDown: 
                //finger touchdown!
                break;
           case TouchIDFingerUp:
                // finger removed
                break;
           case TouchIDFingerHeld:
                // finger was held
                break;
           case TouchIDMatched:
                // positive match!
                break;
           case TouchIDNotMatched:
                // not matched!
                break;
      }
 }
 -(void)startMonitoringEvents
 {
     if(isMonitoringEvents)
     {
          return;
     }
     isMonitoringEvents=YES;
     _monitorDelegate=[[objc_getClass("BiometricKit") manager] delegate];
     monitor=[objc_getClass("SBUIBiometricEventMonitor") sharedInstance];
     [[objc_getClass("BiometricKit") manager] setDelegate:monitor];
     _wasMatching=[[monitor valueForKey:@"_matchingEnabled"] boolValue];
     _monitorObservers=[[monitor valueForKey:@"observers"] copy];
     for (int i=0; i<_monitorObservers.count;  i++)
     {
          [monitor removeObserver:[[monitor valueForKey:@"observers"] objectAtIndex:i]];
     }
     [monitor addObserver:self];
     [monitor _setMatchingEnabled:YES];
     [monitor _startMatching];
 }
 -(void)stoptMonitoringEvents
 {
     if (!isMonitoringEvents)
     {
          return;
     }
     SBUIBiometricEventMonitor *monitor=[[objc_getClass("BiometricKit") manager] delegate];
     [monitor removeObserver:self]; 
     for (id observer in _monitorObservers)
     {
          [monitor addObserver:observer];
     }
     [monitor _setMatchingEnabled:_wasMatching];
     [[objc_getClass("BiometricKit") manager] setDelegate:_monitorDelegate];
     isMonitoringEvents=NO;
 }
 .
 .
 . // cleanup and release as needed
 @end

References

Examples

Project Author
BioTesting Sassoty