PCSC framework spy: broken since Mac OS X Yosemite
In "PCSC API spy, on Mac OS X" I proposed a way to spy on all PC/SC calls of an application.
A few months later Yosemite was available and my spying library does not work any more ☹.
PCSC framework replacement: fails
Example of failure:$ DYLD_FRAMEWORK_PATH=/tmp pcsc_scan PC/SC device scanner V /Users/lroussea/Documents/sc/costa/pcsc-tools (c) 2001-2011, Ludovic Rousseau Compiled with PC/SC lite version: 1.4.0 SCardEstablishContext: Service not available.
Spy output (in a second terminal window):
$ ./pcsc-spy SCardEstablishContext i dwScope: SCARD_SCOPE_SYSTEM (0x00000002) o hContext: 0x00000000 => Service not available. (SCARD_E_NO_SERVICE [0x8010001D]) [0.000001109] SCardReleaseContext i hContext: 0x00000000 => Invalid handle. (SCARD_E_INVALID_HANDLE [0x80100003]) [0.000000006] Results sorted by total execution time total time: 0.001138 sec 0.001109 sec ( 1 calls) 97.45% SCardEstablishContext 0.000006 sec ( 1 calls) 0.53% SCardReleaseContext
If I run pcsc_scan alone, with no PC/SC spy, then the command runs as expected.
Something detects the usage of a new PCSC framework and rejects the first call. I guess the culprit is the original PCSC framework itself and this is a new security feature from Yosemite.
Running the application as root (using sudo) does not help.
SIP: System Integrity Protection
A new change since El Capitan is that the use of DYLD_FRAMEWORK_PATH does not work for programs in protected directories, like /usr/bin/.$ type pcsctest pcsctest is hashed (/usr/bin/pcsctest) $ DYLD_FRAMEWORK_PATH=/tmp pcsctest MUSCLE PC/SC Lite Test Program Testing SCardEstablishContext : Command successful. Testing SCardGetStatusChange Please insert a working reader : Command successful. Testing SCardListReaders : Command successful. Reader 01: Gemalto PC Twin Reader Enter the reader number : ^C
Here the command succeeds but nothing is sent over the spy pipe.
In Yosemite I could use DYLD_FRAMEWORK_PATH=/tmp but with the same results as described above. On El Capitan the dynamic linker dyld just ignores DYLD_FRAMEWORK_PATH.
Another way to check that is to use lldb, the debugger provided with Xcode.
$ lldb pcsctest
(lldb) target create "pcsctest"
Current executable set to 'pcsctest' (x86_64).
(lldb) run
error: process exited with status -1 (cannot attach to process due to System Integrity Protection)
(lldb) quit
Conclusion
I know no way to spy the PC/SC calls done by an application on Mac OS X (with version >= 10.10).This is problematic because PC/SC is still unstable on El Capitan. See "OS X El Capitan and smart cards: known bugs" for example. In some cases it would really help to know what PC/SC call returns an error to be able to:
- Report the error to Apple if it is a bug in PC/SC
- Tell the customer that it is a bug on Apple side
- Try to find a way to avoid the problem, if possible