PCSC API spy, on Mac OS X
In a previous article "PCSC API spy, third try" I described a way to get a nice log of all the PC/SC calls made by an application. The example was using an application on GNU/Linux. A version for Mac OS X was planned but not yet available at that time.
I now realise I finished the Mac OS X version of pcsc-spy but have not yet blogged about it. It is time to fix this.
Installation
pcsc-spy
is part of (the official) pcsc-lite. You can get it from the PCSC lite project web page. The latest version of pcsc-lite as I write this blog entry is 1.8.10.$ curl -O https://alioth.debian.org/frs/download.php/file/3963/pcsc-lite-1.8.10.tar.bz2 $ tar xjf pcsc-lite-1.8.10.tar.bz2 $ cd pcsc-lite-1.8.10/ $ ./configure [...] $ cd src/spy $ make $ make framework
Now you can find a
PCSC.framework
directory that is the equivalent of libpcscspy.so
on GNU/Linux.The installation is not automatic but very easy. You copy the
PCSC.framework
directory in /tmp
$ cp -a PCSC.framework /tmp
Copy the official
PCSC.framework
(binary only) in /tmp
$ cp /System/Library/Frameworks/PCSC.framework/PCSC /tmp
Since we use the temporary directory
/tmp
the log/debug files will be automatically erased on the next system boot. No side effect.Execution
In a Terminal application window (shell) run thepcsc-spy
command:$ ./pcsc-spy
In another Terminal application windows run the application you want to debug:
$ 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: Feitian bR301 00 00 Enter the reader number : 1 Waiting for card insertion : Command successful. Testing SCardConnect : Command successful. Testing SCardStatus : Command successful. Current Reader Name : Feitian bR301 00 00 Current Reader State : 0x34 Current Reader Protocol : 0x0 Current Reader ATR Size : 12 (0xc) Current Reader ATR Value : 3B A7 00 40 18 80 65 A2 08 01 01 52 Testing SCardDisconnect : Command successful. Testing SCardReleaseContext : Command successful. Testing SCardEstablishContext : Command successful. Testing SCardGetStatusChange Please insert a working reader : Command successful. Testing SCardListReaders : Command successful. Reader 01: Feitian bR301 00 00 Enter the reader number : 1 Waiting for card insertion : Command successful. Testing SCardConnect : Command successful. Testing SCardStatus : Command successful. Current Reader Name : Feitian bR301 00 00 Current Reader State : 0x34 Current Reader Protocol : 0x0 Current Reader ATR Size : 12 (0xc) Current Reader ATR Value : 3B A7 00 40 18 80 65 A2 08 01 01 52 Testing SCardDisconnect : Command successful. Testing SCardReleaseContext : Command successful. PC/SC Test Completed Successfully !
In the first Terminal window you will get the colorfull (oh yeah!) log output:
SCardEstablishContext i dwScope: SCARD_SCOPE_SYSTEM (0x00000002) o hContext: 0x0103253B => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000722] SCardGetStatusChange i hContext: 0x0103253B i dwTimeout: 0xFFFFFFFF (4294967295) i cReaders: 0 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000044] SCardListReaders i hContext: 0x0103253B i mszGroups: (null) o pcchReaders: 0x00000015 o mszReaders: NULL => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000059] SCardListReaders i hContext: 0x0103253B i mszGroups: (null) o pcchReaders: 0x00000015 o mszReaders: Feitian bR301 00 00 o mszReaders: => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000042] SCardGetStatusChange i hContext: 0x0103253B i dwTimeout: 0xFFFFFFFF (4294967295) i cReaders: 1 i szReader: Feitian bR301 00 00 i dwCurrentState: SCARD_STATE_EMPTY (0x00000010) i dwEventState: SCARD_STATE_IGNORE, SCARD_STATE_CHANGED, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_EXCLUSIVE, SCARD_STATE_INUSE, SCARD_STATE_EMPTY, SCARD_STATE_MUTE, SCARD_STATE_PRESENT, SCARD_STATE_UNPOWERED, SCARD_STATE_ATRMATCH (0x00007FFF) i Atr length: 0x00000012 (18) i Atr: 00 00 00 00 68 70 E7 0D 01 00 00 00 01 00 00 00 00 00 o szReader: Feitian bR301 00 00 o dwCurrentState: SCARD_STATE_EMPTY (0x00000010) o dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022) o Atr length: 0x0000000C (12) o Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000163] SCardConnect i hContext: 0x0103253B i szReader Feitian bR301 00 00 i dwShareMode: SCARD_SHARE_SHARED (0x00000002) i dwPreferredProtocols: 0x00000003 (T=0, T=1) i phCard 0x00007FFF (32767) i pdwActiveProtocol 0x00000000 (0) o phCard 0x0001616A (90474) o dwActiveProtocol: T=0 (0x00000001) => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000411198] SCardStatus i hCard: 0x0001616A i pcchReaderLen 0x00000034 (52) i pcbAtrLen 0x00000021 (33) o cchReaderLen 0x00000014 (20) o mszReaderName Feitian bR301 00 00 o dwState 0x00000034 (52) o dwProtocol 0x00000001 (1) o bAtrLen 0x0000000C (12) o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000473] SCardDisconnect i hCard: 0x0001616A i dwDisposition: SCARD_UNPOWER_CARD (0x00000002) => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000594971] SCardReleaseContext i hContext: 0x0103253B => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000209] SCardEstablishContext i dwScope: SCARD_SCOPE_SYSTEM (0x00000002) o hContext: 0x01035D3C => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000541] SCardGetStatusChange i hContext: 0x01035D3C i dwTimeout: 0xFFFFFFFF (4294967295) i cReaders: 0 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000033] SCardListReaders i hContext: 0x01035D3C i mszGroups: (null) o pcchReaders: 0x00000015 o mszReaders: NULL => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000034] SCardListReaders i hContext: 0x01035D3C i mszGroups: (null) o pcchReaders: 0x00000015 o mszReaders: Feitian bR301 00 00 o mszReaders: => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000039] SCardGetStatusChange i hContext: 0x01035D3C i dwTimeout: 0xFFFFFFFF (4294967295) i cReaders: 1 i szReader: Feitian bR301 00 00 i dwCurrentState: SCARD_STATE_EMPTY (0x00000010) i dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022) i Atr length: 0x0000000C (12) i Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52 o szReader: Feitian bR301 00 00 o dwCurrentState: SCARD_STATE_EMPTY (0x00000010) o dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022) o Atr length: 0x0000000C (12) o Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000129] SCardConnect i hContext: 0x01035D3C i szReader Feitian bR301 00 00 i dwShareMode: SCARD_SHARE_SHARED (0x00000002) i dwPreferredProtocols: 0x00000003 (T=0, T=1) i phCard 0x0001616A (90474) i pdwActiveProtocol 0x00000001 (1) o phCard 0x00011242 (70210) o dwActiveProtocol: T=0 (0x00000001) => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000411238] SCardStatus i hCard: 0x00011242 i pcchReaderLen 0x00000034 (52) i pcbAtrLen 0x00000021 (33) o cchReaderLen 0x00000014 (20) o mszReaderName Feitian bR301 00 00 o dwState 0x00000034 (52) o dwProtocol 0x00000001 (1) o bAtrLen 0x0000000C (12) o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52 => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000465] SCardDisconnect i hCard: 0x00011242 i dwDisposition: SCARD_UNPOWER_CARD (0x00000002) => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000594863] SCardReleaseContext i hContext: 0x01035D3C => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000000369] Results sorted by total execution time total time: 4.221649 sec 1.189834 sec ( 2 calls) 28.18% SCardDisconnect 0.822436 sec ( 2 calls) 19.48% SCardConnect 0.001263 sec ( 2 calls) 0.03% SCardEstablishContext 0.000938 sec ( 2 calls) 0.02% SCardStatus 0.000578 sec ( 2 calls) 0.01% SCardReleaseContext 0.000369 sec ( 4 calls) 0.01% SCardGetStatusChange 0.000174 sec ( 4 calls) 0.00% SCardListReaders
Analysis
- PC/SC commands are in blue
- Input arguments are in green
- Output arguments are in mangenta
- Errors are in bold red
- The last part of the log contains some statistics about: functions called and times consumed by each of them
Raw log file
If you want to store a log file for a later analysis or if you want to send me a log trace it is better to store the log in raw format. You can do that (as on GNU/Linux) by doing:$ mkfifo ~/pcsc-spy $ cat ~/pcsc-spy > logfileand run your PC/SC application.
The API trace is stored in the file
logfile
. It is displayed using:$ pcsc-spy.py logfile