10 years ago I documented in "PCSC API spy, third try" a way to generate PC/SC API traces when using pcsc-lite.
Since then the ecosystem has changed. This article is an update of the previous blog article with more up-to-date information.
Changes
-
The
pcsc-spy.py command has been renamedpcsc-spy (in 2012) -
The
libpcscspy.so library has been moved from/usr/lib/ to/usr/lib/x86_64-linux-gnu/ (for Intel 64-bits CPU systems) -
opensc-tool can't be used withLD_PRELOAD=
any more
Demo
As before we have two cases for the use ofApplications linked with libpcsclite.so.1
This is the case of the
You can use the ldd
command to know what library has been dynamically linked
at build time:
$ ldd /usr/bin/pcsc_scan
linux-vdso.so.1 (0x00007fffac11b000)
libpcsclite.so.1 => /lib/x86_64-linux-gnu/libpcsclite.so.1 (0x00007f85a5f24000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f85a5f03000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f85a5d2a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f85a5f4f000)
You can use the LD_PRELOAD solution by doing:
In on terminal you run the pcsc-spy
program. In another terminal you run:
$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libpcscspy.so.0 pcsc_scan -r libpcsclite_nospy.so.1: cannot open shared object file: No such file or directory No reader found.
In the first terminal you get the trace:
$ pcsc-spy SCardEstablishContext i dwScope: SCARD_SCOPE_SYSTEM (0x00000002) o hContext: 0x0E4C693B => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.002456] SCardGetStatusChange i hContext: 0x0E4C693B i dwTimeout: 0x00000000 (0) i cReaders: 1 i szReader: \\?PnP?\Notification i dwCurrentState: (0x00000000) i dwEventState: SCARD_STATE_IGNORE, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_EMPTY, SCARD_STATE_INUSE, SCARD_STATE_MUTE (0x55EDE352031D) i Atr length: 0x55EDE352032C (94480209412908) i Atr: NULL o szReader: \\?PnP?\Notification o dwCurrentState: (0x00000000) o dwEventState: (0x00000000) o Atr length: 0x55EDE352032C (94480209412908) o Atr: NULL => Command timeout. (SCARD_E_TIMEOUT [0x8010000A]) [0.007774] SCardListReaders i hContext: 0x0E4C693B i mszGroups: (null) o pcchReaders: 0x00000001 o mszReaders: NULL => Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) [0.000908] SCardListReaders i hContext: 0x0E4C693B i mszGroups: (null) o pcchReaders: 0x00000001 o mszReaders: NULL => Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) [0.000531] Thread 1/1 Results sorted by total execution time total time: 0.011769 sec 0.007774 sec ( 1 calls) 66.06% SCardGetStatusChange 0.002456 sec ( 1 calls) 20.87% SCardEstablishContext 0.001439 sec ( 2 calls) 12.23% SCardListReaders
Application loading libpcsclite.so.1
In this case you need to modify the system configuration to replace the
install_spy.sh
script. You only need to run the script once.
$ sudo bash /usr/share/doc/libpcsclite-dev/install_spy.sh Using directory: /lib/x86_64-linux-gnu Spying library is: /lib/x86_64-linux-gnu/libpcscspy.so.0
On Debian (and derivatives like Ubuntu) and with pcsc-lite version 1.9.8 and
more the script is provided by the libpcsclite-dev package.
In on terminal you run the pcsc-spy program. In another terminal you run the program you want to spy. For example:
$ opensc-tool -a No smart card readers found. Failed to connect to reader: No readers found
In the first terminal you get the trace:
SCardEstablishContext i dwScope: SCARD_SCOPE_USER (0x00000000) o hContext: 0x2667F6DA => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.005316] SCardListReaders i hContext: 0x2667F6DA i mszGroups: (null) o pcchReaders: 0x00000001 o mszReaders: NULL => Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) [0.000079] SCardReleaseContext i hContext: 0x2667F6DA => Command successful. (SCARD_S_SUCCESS [0x00000000]) [0.000074] Thread 1/1 Results sorted by total execution time total time: 0.007195 sec 0.005316 sec ( 1 calls) 73.88% SCardEstablishContext 0.000079 sec ( 1 calls) 1.10% SCardListReaders 0.000074 sec ( 1 calls) 1.03% SCardReleaseContext
Do not forget to restore the system configuration using the
uninstall_spy.sh
script.
$ sudo bash /usr/share/doc/libpcsclite-dev/uninstall_spy.sh Using directory: /lib/x86_64-linux-gnu
Redirection in a file
It is still possible to redirect the traces in a file. Instead of running
pcsc-spy
you do:
$ mkfifo ~/pcsc-spy $ cat ~/pcsc-spy > logfile
And in another terminal you start the application as indicated above (i.e.
using LD_PRELOAD=
or after running install_spy.sh
)
You can then analyse the logs later using:
$ pcsc-spy logfile
Remarks
Bugs found
I note that SCardReleaseContext()
is not always called by
pcsc_scan
before exit. I just fixed this problem in
pcsc-tools.
Install/uninstall
It is important to run the uninstall_spy.sh
script to undo the
changes made by the install_spy.sh
script.
It is important you undo the changes before any execution of the
If you run uninstall_spy.sh
after an execution of
$ pcsc_scan
pcsc_scan: error while loading shared libraries: libpcsclite.so.1: cannot open shared object file: No such file or directory
To fix te problem you can force reinstall the libpcsclite1 (or equivalent) package.
Order of execution
It is important to start pcsc-spy
before the application
you want to spy. If you start pcsc-spy after the application you have 2
cases:
-
if the fifo file
~/pcsc-spy does not yet exist then pcsc-spy will display nothing -
if the fifo file
~/pcsc-spy already exists thenlibpcscspy.so will use it to send logs and will be blocked until something reads the file (pcsc-spy
or thecat
command to redirect the content)
Conclusion
I hope this update is useful.
if you have ideas to improve the logs please contact me.