PCSC API spy using LIBPCSCLITE_DELEGATE

As explained in How to use LIBPCSCLITE_DELEGATE? a new mechanism has been introduced for PC/SC calls debug.

Changes

Compared to the previous version documented in PCSC API spy, update:

  • no need to play with LD_PRELOAD any more

  • no need to install/uninstall a spy library

Demo

Run your program (here pcsc_scan) with LIBPCSCLITE_DELEGATE defined.

$ LIBPCSCLITE_DELEGATE=libpcscspy.so.0 pcsc_scan
PC/SC device scanner
V 1.7.1 (c) 2001-2022, Ludovic Rousseau <ludovic.rousseau@free.fr>
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader...
^C
SCardGetStatusChange: Command cancelled.

I used Control-C to abort the program because pcsc_scan never ends.

Traces

In another window I get:

$ pcsc-spy
SCardEstablishContext
 i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)
 o hContext: 0x72EC0CEF
 => SCARD_S_SUCCESS [0x00000000]  [0.046759]
SCardGetStatusChange
 i hContext: 0x72EC0CEF
 i dwTimeout: 0x00000000 (0)
 i cReaders: 1
 i szReader: \\?PnP?\Notification
 i  dwCurrentState:  (0x00000000)
 i  dwEventState: SCARD_STATE_IGNORE, SCARD_STATE_CHANGED, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_PRESENT, SCARD_STATE_EXCLUSIVE, SCARD_STATE_INUSE, SCARD_STATE_MUTE (0x55A373FA63AF)
 i  Atr length: 0x55A373FA63BE (94160513819582)
 i  Atr: NULL
 o szReader: \\?PnP?\Notification
 o  dwCurrentState:  (0x00000000)
 o  dwEventState:  (0x00000000)
 o  Atr length: 0x55A373FA63BE (94160513819582)
 o  Atr: NULL
 => SCARD_E_TIMEOUT [0x8010000A]  [0.002514]
SCardListReaders
 i hContext: 0x72EC0CEF
 i mszGroups: (null)
 o pcchReaders: 0x00000001
 o mszReaders: NULL
 => SCARD_E_NO_READERS_AVAILABLE [0x8010002E]  [0.000045]
SCardListReaders
 i hContext: 0x72EC0CEF
 i mszGroups: (null)
 o pcchReaders: 0x00000001
 o mszReaders: NULL
 => SCARD_E_NO_READERS_AVAILABLE [0x8010002E]  [0.000434]
SCardGetStatusChange
 i hContext: 0x72EC0CEF
 i dwTimeout: 0x0036EE80 (3600000)
 i cReaders: 1
 i szReader: \\?PnP?\Notification
 i  dwCurrentState:  (0x00000000)
 i  dwEventState:  (0x00000000)
 i  Atr length: 0x55A373FA63BE (94160513819582)
 i  Atr: NULL
   SCardCancel
    i hCard: 0x72EC0CEF
    => SCARD_S_SUCCESS [0x00000000]  [0.000741]
 o szReader: \\?PnP?\Notification
 o  dwCurrentState:  (0x00000000)
 o  dwEventState:  (0x00000000)
 o  Atr length: 0x55A373FA63BE (94160513819582)
 o  Atr: NULL
 => SCARD_E_CANCELLED [0x80100002]  [1.015056]
SCardReleaseContext
 i hContext: 0x72EC0CEF
 => SCARD_S_SUCCESS [0x00000000]  [0.000632]

Thread 1/2
Results sorted by total execution time
total time: 1.065758 sec
1.017570 sec (  2 calls) 95.48% SCardGetStatusChange
0.046759 sec (  1 calls)  4.39% SCardEstablishContext
0.000632 sec (  1 calls)  0.06% SCardReleaseContext
0.000479 sec (  2 calls)  0.04% SCardListReaders

Thread 2/2
Results sorted by total execution time
total time: 1.065758 sec
0.000741 sec (  1 calls)  0.07% SCardCancel

The (Python) program pcsc-spy is provided by pcsc-lite. It is included in the Debian libpcsclite-dev package.

Absolute filename

If you want to use a specific spy library or if the library is installed in a directory not handled by the GNU/Linux dynamic loader ld.so you can use an absolute filename.

The script setup_spy.sh is provided by pcsc-lite. It is also included in the Debian libpcsclite-dev package.

$ sh /usr/share/doc/libpcsclite-dev/setup_spy.sh
export LIBPCSCLITE_DELEGATE=/lib/x86_64-linux-gnu/libpcscspy.so.0

If you want to have LIBPCSCLITE_DELEGATE defined and used for all the future executions (maybe not recommanded) you can execute the export command using:

$ source /usr/share/doc/libpcsclite-dev/setup_spy.sh
export LIBPCSCLITE_DELEGATE=/lib/x86_64-linux-gnu/libpcscspy.so.0

Conclusion

It should now be a bit simpler to generate PC/SC call traces.