<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ludovic Rousseau's blog (Posts about debug)</title><link>https://blog.apdu.fr/</link><description></description><atom:link href="https://blog.apdu.fr/categories/debug.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:ludovic.rousseau+blog@free.fr"&gt;Ludovic Rousseau&lt;/a&gt; - License &lt;a href="/posts/2010/08/my-blog-messages-license/"&gt;CC BY-NC-SA 4.0 Deed&lt;/a&gt; for the text &amp;amp; &lt;a href="/posts/2019/01/my-blog-source-code-license/"&gt;GNU GPLv3&lt;/a&gt; for the code</copyright><lastBuildDate>Fri, 02 Jan 2026 16:23:54 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>PCSC API spy using LIBPCSCLITE_DELEGATE</title><link>https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;As explained in &lt;a class="reference external" href="https://blog.apdu.fr/posts/2024/04/how-to-use-libpcsclite_delegate/"&gt;How to use LIBPCSCLITE_DELEGATE?&lt;/a&gt; a new mechanism has
been introduced for PC/SC calls debug.&lt;/p&gt;
&lt;section id="changes"&gt;
&lt;h2&gt;Changes&lt;/h2&gt;
&lt;p&gt;Compared to the previous version documented in &lt;a class="reference external" href="https://blog.apdu.fr/posts/2022/06/pcsc-api-spy-update/"&gt;PCSC API spy, update&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;no need to play with &lt;code class="docutils literal"&gt;LD_PRELOAD&lt;/code&gt; any more&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;no need to install/uninstall a spy library&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="demo"&gt;
&lt;h2&gt;Demo&lt;/h2&gt;
&lt;p&gt;Run your program (here &lt;code class="docutils literal"&gt;pcsc_scan&lt;/code&gt;) with &lt;code class="docutils literal"&gt;LIBPCSCLITE_DELEGATE&lt;/code&gt; defined.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-1" name="rest_code_c8c47caee97649f2be616aa766834154-1" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nv"&gt;LIBPCSCLITE_DELEGATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;libpcscspy.so.0&lt;span class="w"&gt; &lt;/span&gt;pcsc_scan
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-2" name="rest_code_c8c47caee97649f2be616aa766834154-2" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;PC/SC device scanner&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-3" name="rest_code_c8c47caee97649f2be616aa766834154-3" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-3"&gt;&lt;/a&gt;&lt;span class="go"&gt;V 1.7.1 (c) 2001-2022, Ludovic Rousseau &amp;lt;ludovic.rousseau@free.fr&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-4" name="rest_code_c8c47caee97649f2be616aa766834154-4" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-4"&gt;&lt;/a&gt;&lt;span class="go"&gt;Using reader plug'n play mechanism&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-5" name="rest_code_c8c47caee97649f2be616aa766834154-5" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-5"&gt;&lt;/a&gt;&lt;span class="go"&gt;Scanning present readers...&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-6" name="rest_code_c8c47caee97649f2be616aa766834154-6" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-6"&gt;&lt;/a&gt;&lt;span class="go"&gt;Waiting for the first reader...&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-7" name="rest_code_c8c47caee97649f2be616aa766834154-7" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-7"&gt;&lt;/a&gt;&lt;span class="go"&gt;^C&lt;/span&gt;
&lt;a id="rest_code_c8c47caee97649f2be616aa766834154-8" name="rest_code_c8c47caee97649f2be616aa766834154-8" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_c8c47caee97649f2be616aa766834154-8"&gt;&lt;/a&gt;&lt;span class="go"&gt;SCardGetStatusChange: Command cancelled.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I used Control-C to abort the program because &lt;code class="docutils literal"&gt;pcsc_scan&lt;/code&gt; never ends.&lt;/p&gt;
&lt;section id="traces"&gt;
&lt;h3&gt;Traces&lt;/h3&gt;
&lt;p&gt;In another window I get:&lt;/p&gt;
&lt;style type="text/css"&gt;
pre {
        font-weight: normal;
        color: #bbb;
        white-space: -moz-pre-wrap;
        white-space: -o-pre-wrap;
        white-space: -pre-wrap;
        white-space: pre-wrap;
        word-wrap: break-word;
        overflow-wrap: break-word;
}
b {font-weight: normal}
b.BOLD {color: #fff}
b.ITA {font-style: italic}
b.UND {text-decoration: underline}
b.STR {text-decoration: line-through}
b.UNDSTR {text-decoration: underline line-through}
b.BLK {color: #000000}
b.RED {color: #aa0000}
b.GRN {color: #00aa00}
b.YEL {color: #aa5500}
b.BLU {color: #0000aa}
b.MAG {color: #aa00aa}
b.CYN {color: #00aaaa}
b.WHI {color: #aaaaaa}
b.HIK {color: #555555}
b.HIR {color: #ff5555}
b.HIG {color: #55ff55}
b.HIY {color: #ffff55}
b.HIB {color: #5555ff}
b.HIM {color: #ff55ff}
b.HIC {color: #55ffff}
b.HIW {color: #ffffff}
b.BBLK {background-color: #000000}
b.BRED {background-color: #aa0000}
b.BGRN {background-color: #00aa00}
b.BYEL {background-color: #aa5500}
b.BBLU {background-color: #0000aa}
b.BMAG {background-color: #aa00aa}
b.BCYN {background-color: #00aaaa}
b.BWHI {background-color: #aaaaaa}
&lt;/style&gt;
&lt;pre&gt;$ pcsc-spy
&lt;b class="BLU"&gt;SCardEstablishContext&lt;/b&gt;
&lt;b class="GRN"&gt; i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)&lt;/b&gt;
&lt;b class="MAG"&gt; o hContext: 0x72EC0CEF&lt;/b&gt;
 =&amp;gt; SCARD_S_SUCCESS [0x00000000]  [0.046759]
&lt;b class="BLU"&gt;SCardGetStatusChange&lt;/b&gt;
&lt;b class="GRN"&gt; i hContext: 0x72EC0CEF&lt;/b&gt;
&lt;b class="GRN"&gt; i dwTimeout: 0x00000000 (0)&lt;/b&gt;
&lt;b class="GRN"&gt; i cReaders: 1&lt;/b&gt;
&lt;b class="GRN"&gt; i szReader: \\?PnP?\Notification&lt;/b&gt;
&lt;b class="GRN"&gt; i  dwCurrentState:  (0x00000000)&lt;/b&gt;
&lt;b class="GRN"&gt; 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)&lt;/b&gt;
&lt;b class="GRN"&gt; i  Atr length: 0x55A373FA63BE (94160513819582)&lt;/b&gt;
&lt;b class="GRN"&gt; i  Atr: NULL&lt;/b&gt;
&lt;b class="MAG"&gt; o szReader: \\?PnP?\Notification&lt;/b&gt;
&lt;b class="MAG"&gt; o  dwCurrentState:  (0x00000000)&lt;/b&gt;
&lt;b class="MAG"&gt; o  dwEventState:  (0x00000000)&lt;/b&gt;
&lt;b class="MAG"&gt; o  Atr length: 0x55A373FA63BE (94160513819582)&lt;/b&gt;
&lt;b class="MAG"&gt; o  Atr: NULL&lt;/b&gt;
&lt;b class="HIR"&gt; =&amp;gt; SCARD_E_TIMEOUT [0x8010000A] &lt;/b&gt; [0.002514]
&lt;b class="BLU"&gt;SCardListReaders&lt;/b&gt;
&lt;b class="GRN"&gt; i hContext: 0x72EC0CEF&lt;/b&gt;
&lt;b class="GRN"&gt; i mszGroups: (null)&lt;/b&gt;
&lt;b class="MAG"&gt; o pcchReaders: 0x00000001&lt;/b&gt;
&lt;b class="MAG"&gt; o mszReaders: NULL&lt;/b&gt;
&lt;b class="HIR"&gt; =&amp;gt; SCARD_E_NO_READERS_AVAILABLE [0x8010002E] &lt;/b&gt; [0.000045]
&lt;b class="BLU"&gt;SCardListReaders&lt;/b&gt;
&lt;b class="GRN"&gt; i hContext: 0x72EC0CEF&lt;/b&gt;
&lt;b class="GRN"&gt; i mszGroups: (null)&lt;/b&gt;
&lt;b class="MAG"&gt; o pcchReaders: 0x00000001&lt;/b&gt;
&lt;b class="MAG"&gt; o mszReaders: NULL&lt;/b&gt;
&lt;b class="HIR"&gt; =&amp;gt; SCARD_E_NO_READERS_AVAILABLE [0x8010002E] &lt;/b&gt; [0.000434]
&lt;b class="BLU"&gt;SCardGetStatusChange&lt;/b&gt;
&lt;b class="GRN"&gt; i hContext: 0x72EC0CEF&lt;/b&gt;
&lt;b class="GRN"&gt; i dwTimeout: 0x0036EE80 (3600000)&lt;/b&gt;
&lt;b class="GRN"&gt; i cReaders: 1&lt;/b&gt;
&lt;b class="GRN"&gt; i szReader: \\?PnP?\Notification&lt;/b&gt;
&lt;b class="GRN"&gt; i  dwCurrentState:  (0x00000000)&lt;/b&gt;
&lt;b class="GRN"&gt; i  dwEventState:  (0x00000000)&lt;/b&gt;
&lt;b class="GRN"&gt; i  Atr length: 0x55A373FA63BE (94160513819582)&lt;/b&gt;
&lt;b class="GRN"&gt; i  Atr: NULL&lt;/b&gt;
   &lt;b class="BLU"&gt;SCardCancel&lt;/b&gt;
   &lt;b class="GRN"&gt; i hCard: 0x72EC0CEF&lt;/b&gt;
    =&amp;gt; SCARD_S_SUCCESS [0x00000000]  [0.000741]
&lt;b class="MAG"&gt; o szReader: \\?PnP?\Notification&lt;/b&gt;
&lt;b class="MAG"&gt; o  dwCurrentState:  (0x00000000)&lt;/b&gt;
&lt;b class="MAG"&gt; o  dwEventState:  (0x00000000)&lt;/b&gt;
&lt;b class="MAG"&gt; o  Atr length: 0x55A373FA63BE (94160513819582)&lt;/b&gt;
&lt;b class="MAG"&gt; o  Atr: NULL&lt;/b&gt;
&lt;b class="HIR"&gt; =&amp;gt; SCARD_E_CANCELLED [0x80100002] &lt;/b&gt; [1.015056]
&lt;b class="BLU"&gt;SCardReleaseContext&lt;/b&gt;
&lt;b class="GRN"&gt; i hContext: 0x72EC0CEF&lt;/b&gt;
 =&amp;gt; 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
&lt;/pre&gt;&lt;p&gt;The (Python) program &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;pcsc-spy&lt;/span&gt;&lt;/code&gt; is provided by pcsc-lite. It is
included in the Debian &lt;a class="reference external" href="https://packages.debian.org/search?keywords=libpcsclite-dev"&gt;libpcsclite-dev&lt;/a&gt; package.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="absolute-filename"&gt;
&lt;h2&gt;Absolute filename&lt;/h2&gt;
&lt;p&gt;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 &lt;code class="docutils literal"&gt;ld.so&lt;/code&gt; you
can use an absolute filename.&lt;/p&gt;
&lt;p&gt;The script &lt;code class="docutils literal"&gt;setup_spy.sh&lt;/code&gt; is provided by pcsc-lite. It is also
included in the Debian &lt;a class="reference external" href="https://packages.debian.org/search?keywords=libpcsclite-dev"&gt;libpcsclite-dev&lt;/a&gt; package.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_a8f22ff4cb1249c6b7a879ed3624e244-1" name="rest_code_a8f22ff4cb1249c6b7a879ed3624e244-1" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_a8f22ff4cb1249c6b7a879ed3624e244-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;sh&lt;span class="w"&gt; &lt;/span&gt;/usr/share/doc/libpcsclite-dev/setup_spy.sh
&lt;a id="rest_code_a8f22ff4cb1249c6b7a879ed3624e244-2" name="rest_code_a8f22ff4cb1249c6b7a879ed3624e244-2" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_a8f22ff4cb1249c6b7a879ed3624e244-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;export LIBPCSCLITE_DELEGATE=/lib/x86_64-linux-gnu/libpcscspy.so.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to have &lt;code class="docutils literal"&gt;LIBPCSCLITE_DELEGATE&lt;/code&gt; defined and used for all
the future executions (maybe not recommanded) you can execute the
&lt;code class="docutils literal"&gt;export&lt;/code&gt; command using:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_34291b89998444eb8fe7d45ca9f40784-1" name="rest_code_34291b89998444eb8fe7d45ca9f40784-1" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_34291b89998444eb8fe7d45ca9f40784-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/share/doc/libpcsclite-dev/setup_spy.sh
&lt;a id="rest_code_34291b89998444eb8fe7d45ca9f40784-2" name="rest_code_34291b89998444eb8fe7d45ca9f40784-2" href="https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/#rest_code_34291b89998444eb8fe7d45ca9f40784-2"&gt;&lt;/a&gt;&lt;span class="go"&gt;export LIBPCSCLITE_DELEGATE=/lib/x86_64-linux-gnu/libpcscspy.so.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It should now be a bit simpler to generate PC/SC call traces.&lt;/p&gt;
&lt;/section&gt;</description><category>debug</category><category>pcsc-lite</category><guid>https://blog.apdu.fr/posts/2024/04/pcsc-api-spy-using-libpcsclite_delegate/</guid><pubDate>Fri, 12 Apr 2024 15:17:59 GMT</pubDate></item><item><title>FAQ: wintypes.h or winscard.h not found</title><link>https://blog.apdu.fr/posts/2023/03/faq-wintypesh-or-winscardh-not-found/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;
  One of the most popular search requests that bring people on my website
  &lt;a href="https://pcsclite.apdu.fr/"&gt;https://pcsclite.apdu.fr/&lt;/a&gt; is about
  wintypes.h not found.
&lt;/p&gt;
&lt;h2 style="text-align: left;"&gt;Problem &lt;br&gt;&lt;/h2&gt;
&lt;p&gt;For example you try to compile something and get the error:&lt;br&gt;&lt;/p&gt;

&lt;pre&gt;smartcard/scard/helpers.c:28:10: fatal error: winscard.h: No such file or directory
 #include &amp;lt;winscard.h&amp;gt;
          ^~~~~~~~~~~~ 
&lt;/pre&gt;

&lt;h2 style="text-align: left;"&gt;Solution &lt;br&gt;&lt;/h2&gt;
&lt;p&gt;
  The PC/SC header files (winscard.h, wintypes.h and some others) are provided by the
  &lt;b&gt;development&lt;/b&gt; pcsclite package.
&lt;/p&gt;
&lt;ul style="text-align: left;"&gt;
  &lt;li&gt;
    for Debian, Ubuntu or derivatives the package is
    &lt;a href="https://packages.debian.org/search?keywords=pcsclite-dev"&gt;pcsclite-dev&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    for Red Hat, Fedora and derivatives the package is
    &lt;a href="https://pkgs.org/search/?q=pcsc-lite-devel"&gt;pcsc-lite-devel&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;for other Unixes, use your favourite search engine 😜&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  You install the correct package and you try again to build your software.&lt;br&gt;
&lt;/p&gt;
&lt;h2 style="text-align: left;"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;
  I hope this blog article will be correctly indexed by search engines to help people find the
  solution.&lt;br&gt;
&lt;/p&gt;</description><category>code</category><category>debug</category><category>pcsc-lite</category><guid>https://blog.apdu.fr/posts/2023/03/faq-wintypesh-or-winscardh-not-found/</guid><pubDate>Fri, 17 Mar 2023 20:45:00 GMT</pubDate></item><item><title>PCSC API spy, update</title><link>https://blog.apdu.fr/posts/2022/06/pcsc-api-spy-update/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;
  10 years ago I documented in "&lt;a href="https://blog.apdu.fr/posts/2011/11/pcsc-api-spy-third-try/"&gt;PCSC API spy, third try&lt;/a&gt;" a way to generate PC/SC API traces when using &lt;a href="https://pcsclite.apdu.fr/"&gt;pcsc-lite&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  Since then the ecosystem has changed. This article is an update of the
  previous blog article with more up-to-date information.
&lt;/p&gt;
&lt;h2 style="text-align: left;"&gt;Changes&lt;/h2&gt;
&lt;ul style="text-align: left;"&gt;
  &lt;li&gt;
    The pcsc-spy.py command has been renamed
    pcsc-spy (in 2012)
  &lt;/li&gt;
  &lt;li&gt;
    The libpcscspy.so library has been moved from
    /usr/lib/ to /usr/lib/x86_64-linux-gnu/ (for Intel
    64-bits CPU systems)
  &lt;/li&gt;
  &lt;li&gt;
    opensc-tool can't be used with &lt;code&gt;LD_PRELOAD=&lt;/code&gt; any
    more
  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style="text-align: left;"&gt;Demo&lt;/h2&gt;
As before we have two cases for the use of libpcsclite.so.1.&lt;br&gt;
&lt;h4&gt;Applications linked with libpcsclite.so.1&lt;/h4&gt;
&lt;p&gt;This is the case of the pcsc_scan command for example.&lt;/p&gt;
&lt;p&gt;
  You can use the &lt;code&gt;ldd&lt;/code&gt; command to know what library has been dynamically linked
  at build time:
&lt;/p&gt;
&lt;pre&gt;$ ldd /usr/bin/pcsc_scan 
	linux-vdso.so.1 (0x00007fffac11b000)
	&lt;span style="background-color: #fcff01;"&gt;libpcsclite.so.1 =&amp;gt; /lib/x86_64-linux-gnu/libpcsclite.so.1 (0x00007f85a5f24000)&lt;/span&gt;
	libpthread.so.0 =&amp;gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f85a5f03000)
	libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f85a5d2a000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f85a5f4f000)&lt;/pre&gt;
&lt;p&gt;You can use the LD_PRELOAD solution by doing:&lt;/p&gt;
&lt;p&gt;In on terminal you run the &lt;code&gt;pcsc-spy&lt;/code&gt; program. In another terminal you run:&lt;/p&gt;
&lt;pre&gt;$ 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.&lt;/pre&gt;
&lt;p&gt;In the first terminal you get the trace:&lt;/p&gt;

&lt;pre&gt;$ pcsc-spy 
&lt;span class="ansi34"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span class="ansi32"&gt; i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)&lt;/span&gt;
&lt;span class="ansi35"&gt; o hContext: 0x0E4C693B&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.002456]
&lt;span class="ansi34"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span class="ansi32"&gt; i hContext: 0x0E4C693B&lt;/span&gt;
&lt;span class="ansi32"&gt; i dwTimeout: 0x00000000 (0)&lt;/span&gt;
&lt;span class="ansi32"&gt; i cReaders: 1&lt;/span&gt;
&lt;span class="ansi32"&gt; i szReader: \\?PnP?\Notification&lt;/span&gt;
&lt;span class="ansi32"&gt; i  dwCurrentState:  (0x00000000)&lt;/span&gt;
&lt;span class="ansi32"&gt; i  dwEventState: SCARD_STATE_IGNORE, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_EMPTY, SCARD_STATE_INUSE, SCARD_STATE_MUTE (0x55EDE352031D)&lt;/span&gt;
&lt;span class="ansi32"&gt; i  Atr length: 0x55EDE352032C (94480209412908)&lt;/span&gt;
&lt;span class="ansi32"&gt; i  Atr: NULL&lt;/span&gt;
&lt;span class="ansi35"&gt; o szReader: \\?PnP?\Notification&lt;/span&gt;
&lt;span class="ansi35"&gt; o  dwCurrentState:  (0x00000000)&lt;/span&gt;
&lt;span class="ansi35"&gt; o  dwEventState:  (0x00000000)&lt;/span&gt;
&lt;span class="ansi35"&gt; o  Atr length: 0x55EDE352032C (94480209412908)&lt;/span&gt;
&lt;span class="ansi35"&gt; o  Atr: NULL&lt;/span&gt;
&lt;span class="ansi1 ansi31"&gt; =&amp;gt; Command timeout. (SCARD_E_TIMEOUT [0x8010000A]) &lt;/span&gt; [0.007774]
&lt;span class="ansi34"&gt;SCardListReaders&lt;/span&gt;
&lt;span class="ansi32"&gt; i hContext: 0x0E4C693B&lt;/span&gt;
&lt;span class="ansi32"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span class="ansi35"&gt; o pcchReaders: 0x00000001&lt;/span&gt;
&lt;span class="ansi35"&gt; o mszReaders: NULL&lt;/span&gt;
&lt;span class="ansi1 ansi31"&gt; =&amp;gt; Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) &lt;/span&gt; [0.000908]
&lt;span class="ansi34"&gt;SCardListReaders&lt;/span&gt;
&lt;span class="ansi32"&gt; i hContext: 0x0E4C693B&lt;/span&gt;
&lt;span class="ansi32"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span class="ansi35"&gt; o pcchReaders: 0x00000001&lt;/span&gt;
&lt;span class="ansi35"&gt; o mszReaders: NULL&lt;/span&gt;
&lt;span class="ansi1 ansi31"&gt; =&amp;gt; Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) &lt;/span&gt; [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&lt;/pre&gt;

&lt;h4&gt;Application loading libpcsclite.so.1&lt;/h4&gt;
&lt;p&gt;
  In this case you need to modify the system configuration to replace the
  libpcsclite.so.1 library. This is done by the
  &lt;code&gt;install_spy.sh&lt;/code&gt; script. You only need to run the script once.
&lt;/p&gt;
&lt;pre&gt;$ 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&lt;/pre&gt;
&lt;p&gt;
  On Debian (and derivatives like Ubuntu) and with pcsc-lite version 1.9.8 and
  more the script is provided by the &lt;a href="https://packages.debian.org/sid/libpcsclite-dev"&gt;libpcsclite-dev&lt;/a&gt; package.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
  In on terminal you run the pcsc-spy program. In another terminal you run the
  program you want to spy. For example:
&lt;/p&gt;
&lt;pre&gt;$ opensc-tool -a
No smart card readers found.
Failed to connect to reader: No readers found&lt;/pre&gt;
&lt;p&gt;In the first terminal you get the trace:&lt;/p&gt;
&lt;pre&gt;&lt;span class="ansi34"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span class="ansi32"&gt; i dwScope: SCARD_SCOPE_USER (0x00000000)&lt;/span&gt;
&lt;span class="ansi35"&gt; o hContext: 0x2667F6DA&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.005316]
&lt;span class="ansi34"&gt;SCardListReaders&lt;/span&gt;
&lt;span class="ansi32"&gt; i hContext: 0x2667F6DA&lt;/span&gt;
&lt;span class="ansi32"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span class="ansi35"&gt; o pcchReaders: 0x00000001&lt;/span&gt;
&lt;span class="ansi35"&gt; o mszReaders: NULL&lt;/span&gt;
&lt;span class="ansi1 ansi31"&gt; =&amp;gt; Cannot find a smart card reader. (SCARD_E_NO_READERS_AVAILABLE [0x8010002E]) &lt;/span&gt; [0.000079]
&lt;span class="ansi34"&gt;SCardReleaseContext&lt;/span&gt;
&lt;span class="ansi32"&gt; i hContext: 0x2667F6DA&lt;/span&gt;
 =&amp;gt; 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
&lt;/pre&gt;
&lt;p&gt;
  Do not forget to restore the system configuration using the
  &lt;code&gt;uninstall_spy.sh&lt;/code&gt; script.
&lt;/p&gt;
&lt;pre&gt;$ sudo bash /usr/share/doc/libpcsclite-dev/uninstall_spy.sh
Using directory: /lib/x86_64-linux-gnu&lt;/pre&gt;
&lt;h3&gt;Redirection in a file&lt;/h3&gt;
&lt;p&gt;
  It is still possible to redirect the traces in a file. Instead of running
  &lt;code&gt;pcsc-spy&lt;/code&gt; you do:&lt;br&gt;
&lt;/p&gt;
&lt;pre&gt;$ mkfifo ~/pcsc-spy
$ cat ~/pcsc-spy &amp;gt; logfile&lt;/pre&gt;
&lt;p&gt;
  And in another terminal you start the application as indicated above (&lt;i&gt;i.e.&lt;/i&gt;
  using &lt;code&gt;LD_PRELOAD=&lt;/code&gt; or after running &lt;code&gt;install_spy.sh&lt;/code&gt;)
&lt;/p&gt;
&lt;p&gt;You can then analyse the logs later using:&lt;/p&gt;
&lt;pre&gt;$ pcsc-spy logfile&lt;/pre&gt;
&lt;h2 style="text-align: left;"&gt;Remarks&lt;/h2&gt;
&lt;h3 style="text-align: left;"&gt;Bugs found&lt;br&gt;&lt;/h3&gt;
&lt;p&gt;
  I note that &lt;code&gt;SCardReleaseContext()&lt;/code&gt; is not always called by
  &lt;code&gt;pcsc_scan&lt;/code&gt; before exit. I just fixed this problem in
  &lt;a href="https://github.com/LudovicRousseau/pcsc-tools"&gt;pcsc-tools&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;h3 style="text-align: left;"&gt;Install/uninstall&lt;br&gt;&lt;/h3&gt;
&lt;p&gt;
  It is important to run the &lt;code&gt;uninstall_spy.sh&lt;/code&gt; script to undo the
  changes made by the &lt;code&gt;install_spy.sh&lt;/code&gt; script.
&lt;/p&gt;
&lt;p&gt;
  It is important you undo the changes before any execution of the
  ldconfig (configure dynamic linker run-time bindings)
  administration command. ldconfig is used, for example, during the installation
  of a package.
&lt;/p&gt;
&lt;p&gt;
  If you run &lt;code&gt;uninstall_spy.sh&lt;/code&gt; &lt;b&gt;after&lt;/b&gt; an execution of
  ldconfig you may get a broken libpcsclite installation with an
  error like:
&lt;/p&gt;
&lt;pre&gt;$ pcsc_scan &lt;br&gt;pcsc_scan: error while loading shared libraries:
libpcsclite.so.1: cannot open shared object file: No such file or directory&lt;/pre&gt;
&lt;p&gt;To fix te problem you can force reinstall the libpcsclite1 (or equivalent) package.&lt;/p&gt;
&lt;h3 style="text-align: left;"&gt;Order of execution&lt;br&gt;&lt;/h3&gt;
&lt;p&gt;
  It is important to start &lt;code&gt;pcsc-spy&lt;/code&gt; &lt;b&gt;before&lt;/b&gt; the application
  you want to spy. If you start pcsc-spy after the application you have 2
  cases:&lt;br&gt;
&lt;/p&gt;
&lt;ol style="text-align: left;"&gt;
  &lt;li&gt;
    if the fifo file ~/pcsc-spy does not yet exist then pcsc-spy
    will display nothing
  &lt;/li&gt;
  &lt;li&gt;
    if the fifo file ~/pcsc-spy already exists then
    libpcscspy.so will use it to send logs and will be blocked
    until something reads the file (&lt;code&gt;pcsc-spy&lt;/code&gt; or the &lt;code&gt;cat&lt;/code&gt; command to redirect the
    content)
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 style="text-align: left;"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope this update is useful.&lt;/p&gt;&lt;p&gt;if you have ideas to improve the logs please contact me.&lt;br&gt;&lt;/p&gt;</description><category>debug</category><category>pcsc-lite</category><guid>https://blog.apdu.fr/posts/2022/06/pcsc-api-spy-update/</guid><pubDate>Sun, 12 Jun 2022 13:31:00 GMT</pubDate></item><item><title>Level 1.5 smart card support on macOS</title><link>https://blog.apdu.fr/posts/2018/03/level-15-smart-card-support-on-macos/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;In a previous article "&lt;a href="https://blog.apdu.fr/posts/2014/03/level-1-smart-card-support-on-mac-os-x/"&gt;Level 1 smart card support on Mac OS X&lt;/a&gt;" I described some simple commands to check if the smart card stack is working correctly on a macOS system.&lt;br&gt;
&lt;br&gt;
By re-reading the presentation "&lt;a href="http://macadmins.psu.edu/files/2017/07/psumac2017-120-macOS-and-Smart-Cards-2d0v717.pdf"&gt;Working with Smart Cards: macOS and Security&lt;/a&gt;" by Richard Purves I discovered a new command.&lt;br&gt;
&lt;br&gt;
I already knew "&lt;code&gt;system_profiler SPUSBDataType&lt;/code&gt;" to list the USB devices. I mentioned it in "Level 1 smart card support on Mac OS X" to check the USB reader is seen by the system. But &lt;code&gt;system_profiler&lt;/code&gt; provides a better command for smart cards.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;h2&gt;
SPSmartCardsDataType&lt;/h2&gt;
system_profiler has another very interesting command: &lt;code&gt;system_profiler SPSmartCardsDataType&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
Clean macOS installation&lt;/h3&gt;
Example 1:&lt;br&gt;
&lt;pre&gt;$ system_profiler SPSmartCardsDataType
SmartCards:

    Readers:

      #01: Cherry KC 1000 SC (ATR:&amp;lt;3b7f9600 00803180 65b08441 3df612ff fe829000&amp;gt;)

    Reader Drivers:

      #01: org.debian.alioth.pcsclite.smartcardccid:1.4.27 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)

    Tokend Drivers:

    SmartCard Drivers:

      #01: com.apple.CryptoTokenKit.pivtoken:1.0 (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)

    Available SmartCards (keychain):

    Available SmartCards (token):

&lt;/pre&gt;
&lt;br&gt;
You get a lot of useful information:&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;list of smart card readers&lt;/li&gt;
&lt;li&gt;list of installed reader drivers&lt;/li&gt;
&lt;li&gt;list of tokend drivers&lt;/li&gt;
&lt;li&gt;list of smart card drivers&lt;/li&gt;
&lt;li&gt;available smart cards (keychain)&lt;/li&gt;
&lt;li&gt;available smart cards (token)&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
What you can see in my example:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;I use a Cherry KC 1000 SC reader. A card is inserted in the reader and you see the ATR.&lt;/li&gt;
&lt;li&gt;by default Apple provides a &lt;a href="https://ccid.apdu.fr/"&gt;CCID driver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;by default Apple provides a PIV CryptoTokenKit token to support &lt;a href="https://en.wikipedia.org/wiki/FIPS_201"&gt;Personal Identity Verification&lt;/a&gt; cards&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;
Using SafeNet Authentication Client&lt;/h3&gt;
Example 2:&lt;br&gt;
&lt;pre&gt;$ system_profiler SPSmartCardsDataType 
SmartCards:

    Readers:

      #01: Gemalto PC Twin Reader (ATR:&amp;lt;3b7f9600 00803180 65b08503 00ef120f fe829000&amp;gt;)

    Reader Drivers:

      #01: org.debian.alioth.pcsclite.smartcardccid:1.4.27 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)
      #02: com.SafeNet.eTokenIfdh:9.0.0.0 (/Library/Frameworks/eToken.framework/Versions/A/aks-ifdh.bundle)
      #03: com.gemalto.ifd-bccid:1.0 (/usr/local/libexec/SmartCardServices/drivers/ifd-bccid.bundle)
      #04: org.debian.alioth.pcsclite.smartcardccid:1.4.27 (/usr/local/libexec/SmartCardServices/drivers/ifd-ccid-SafeNet-eToken5300.bundle)
      #05: (null):(null) (/Library/Frameworks/eToken.framework/Versions/A/ikey-ifdh.bundle)

    Tokend Drivers:

      #01: com.Safenet.eTokend:9.0 (/Library/Frameworks/eToken.framework/Versions/A/eTokend.tokend)

    SmartCard Drivers:

      #01: com.apple.CryptoTokenKit.pivtoken:1.0 (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)
      #02: com.gemalto.Gemalto-Smart-Card-Token.PKCS11-Token:1.0 (/Library/Frameworks/eToken.framework/Versions/A/SafeNet Authentication Client.app/Contents/PlugIns/PKCS11 Token.appex)

    Available SmartCards (keychain):

        com.gemalto.Gemalto-Smart-Card-Token.PKCS11-Token:9A522A4489DFA3DE:

          #01: Kind: private RSA 2048-bit, Certificate: &amp;lt;1cc4a99c 25e2b4eb 381850d2 e8e7a9a8 8d258b31&amp;gt;, Usage: Sign Decrypt Unwrap 
          #02: Kind: private RSA 2048-bit, Certificate: &amp;lt;425fa8c1 27ad75a1 aec73183 2b053b41 38befe7f&amp;gt;, Usage: Sign Decrypt Unwrap 
          #03: Kind: private RSA 4096-bit, Certificate: &amp;lt;16b5321b d4c7f3e0 e68ef3bd d2b03aee b23918d1&amp;gt;, Usage: Sign Decrypt Unwrap 
          #04: Kind: private RSA 4096-bit, Certificate: &amp;lt;16b5321b d4c7f3e0 e68ef3bd d2b03aee b23918d1&amp;gt;, Usage: Sign Decrypt Unwrap 
          #05: Kind: private RSA 2048-bit, Certificate: &amp;lt;31fde547 b4ca58d4 7b6231c2 62730efd 8c7538a1&amp;gt;, Usage: Sign Derive Decrypt Unwrap 

    Available SmartCards (token):

        com.gemalto.Gemalto-Smart-Card-Token.PKCS11-Token:9A522A4489DFA3DE:

          #01: Kind: private RSA 2048-bit, Certificate: &amp;lt;1cc4a99c 25e2b4eb 381850d2 e8e7a9a8 8d258b31&amp;gt;, Usage: Sign Decrypt Unwrap 
          #02: Kind: private RSA 2048-bit, Certificate: &amp;lt;425fa8c1 27ad75a1 aec73183 2b053b41 38befe7f&amp;gt;, Usage: Sign Decrypt Unwrap 
          #03: Kind: private RSA 4096-bit, Certificate: &amp;lt;16b5321b d4c7f3e0 e68ef3bd d2b03aee b23918d1&amp;gt;, Usage: Sign Decrypt Unwrap 
          #04: Kind: private RSA 2048-bit, Certificate: &amp;lt;31fde547 b4ca58d4 7b6231c2 62730efd 8c7538a1&amp;gt;, Usage: Sign Derive Decrypt Unwrap 
          #05: Certificate &amp;lt;1a222d8f 7458d082 d413fbdb 40c85f56 f48def63&amp;gt;

&lt;/pre&gt;
&lt;br&gt;
In this second example I installed SAC (SafeNet Authentication Client) from Gemalto. You can see some differences:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;more reader drivers are installed&lt;/li&gt;
&lt;li&gt;a tokend driver is installed&lt;/li&gt;
&lt;li&gt;another SmartCard (Crypto Token Kit or CTK) driver is installed &lt;/li&gt;
&lt;li&gt;the card inserted in the reader is available in the keychain&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
This command provides information of a higher level that &lt;code&gt;pcsctest&lt;/code&gt;.&lt;br&gt;
You know what drivers (for readers and for cards) are installed.</description><category>debug</category><category>Mac OS X</category><guid>https://blog.apdu.fr/posts/2018/03/level-15-smart-card-support-on-macos/</guid><pubDate>Thu, 01 Mar 2018 13:07:00 GMT</pubDate></item><item><title>PCSC framework spy: broken since Mac OS X Yosemite</title><link>https://blog.apdu.fr/posts/2016/02/pcsc-framework-spy-broken-since-mac-os/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;In "&lt;a href="https://blog.apdu.fr/posts/2014/02/pcsc-api-spy-on-mac-os-x/"&gt;PCSC API spy, on Mac OS X&lt;/a&gt;" I proposed a way to spy on all PC/SC calls of an application.&lt;br&gt;
&lt;br&gt;
A few months later Yosemite was available and my spying library does not work any more ☹.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;h2&gt;PCSC framework replacement: fails&lt;/h2&gt;Example of failure:&lt;br&gt;
&lt;pre&gt;$ 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.
&lt;/pre&gt;&lt;br&gt;
Spy output (in a second terminal window):&lt;br&gt;
&lt;pre&gt;$ ./pcsc-spy
&lt;span style="color: #0000aa;"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)&lt;/span&gt;
&lt;span style="color: #e850a8;"&gt; o hContext: 0x00000000&lt;/span&gt;
&lt;span style="color: #aa0000; font-weight: bold;"&gt; =&amp;gt; Service not available. (SCARD_E_NO_SERVICE [0x8010001D]) &lt;/span&gt; [0.000001109]
&lt;span style="color: #0000aa;"&gt;SCardReleaseContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x00000000&lt;/span&gt;
&lt;span style="color: #aa0000; font-weight: bold;"&gt; =&amp;gt; Invalid handle. (SCARD_E_INVALID_HANDLE [0x80100003]) &lt;/span&gt; [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
&lt;/pre&gt;&lt;br&gt;
If I run pcsc_scan alone, with no PC/SC spy, then the command runs as expected.&lt;br&gt;
&lt;br&gt;
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.&lt;br&gt;
&lt;br&gt;
Running the application as root (using sudo) does not help.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;SIP: System Integrity Protection&lt;/h2&gt;A new change since El Capitan is that the use of DYLD_FRAMEWORK_PATH does not work for programs in &lt;a href="https://support.apple.com/en-us/HT204899"&gt;protected directories&lt;/a&gt;, like /usr/bin/.&lt;br&gt;
&lt;pre&gt;$ 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&lt;/pre&gt;&lt;br&gt;
Here the command succeeds but nothing is sent over the spy pipe.&lt;br&gt;
&lt;br&gt;
In Yosemite I could use &lt;tt&gt;DYLD_FRAMEWORK_PATH=/tmp&lt;/tt&gt; but with the same results as described above. On El Capitan the dynamic linker dyld just ignores &lt;tt&gt;DYLD_FRAMEWORK_PATH&lt;/tt&gt;.&lt;br&gt;
&lt;br&gt;
Another way to check that is to use lldb, the debugger provided with Xcode.&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ 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 &lt;span style="background-color: yellow;"&gt;System Integrity Protection&lt;/span&gt;)
(lldb) quit&lt;/pre&gt;&lt;br&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;I know no way to spy the PC/SC calls done by an application on Mac OS X (with version &amp;gt;= 10.10).&lt;br&gt;
&lt;br&gt;
This is problematic because PC/SC is still unstable on El Capitan. See "&lt;a href="https://blog.apdu.fr/posts/2015/11/os-x-el-capitan-and-smart-cards-known/"&gt;OS X El Capitan and smart cards: known bugs&lt;/a&gt;" for example. In some cases it would really help to know what PC/SC call returns an error to be able to:&lt;br&gt;
&lt;ul&gt;&lt;li&gt;Report the error to Apple if it is a bug in PC/SC&lt;/li&gt;
&lt;li&gt;Tell the customer that it is a bug on Apple side&lt;/li&gt;
&lt;li&gt;Try to find a way to avoid the problem, if possible&lt;/li&gt;
&lt;/ul&gt;</description><category>debug</category><category>Mac OS X</category><guid>https://blog.apdu.fr/posts/2016/02/pcsc-framework-spy-broken-since-mac-os/</guid><pubDate>Tue, 23 Feb 2016 14:18:00 GMT</pubDate></item><item><title>CCID USB spy using Wireshark</title><link>https://blog.apdu.fr/posts/2014/10/ccid-usb-spy-using-wireshark/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;Sometimes you need to know exactly what is happening at the USB level. You have two options:&lt;br&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;use a hardware USB analyzer&lt;/li&gt;
&lt;li&gt;use a software USB analyzer&lt;/li&gt;
&lt;/ul&gt;
Since I do not have the budget to buy a hardware USB monitor I will use the software solution.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Wireshark&lt;/h2&gt;
Since some time, it is possible to use the wonderful &lt;a href="https://www.wireshark.org/"&gt;Wireshark&lt;/a&gt; program to display and analyze USB frames. Wireshark is mainly used for analyzing network packets but it is also possible to display USB packets. Wireshark is even able to display the CCID commands inside the USB packets.&lt;br&gt;
&lt;br&gt;
&lt;img border="0" src="https://blog.apdu.fr/images/2014/10/Wireshark.thumb.jpg"&gt;&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
How-to&lt;/h2&gt;
A documentation is available at &lt;a href="http://wiki.wireshark.org/CaptureSetup/USB"&gt;USB capture setup&lt;/a&gt; and also at &lt;a href="http://nagaraj-embedded.blogspot.fr/2012/03/capturing-usb-data-through-wireshark.html"&gt;Capturing USB data through Wireshark&lt;/a&gt;.&lt;br&gt;
This article describes what I did.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Setup the kernel&lt;/h2&gt;
You first need to load the usbmon kernel module.&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ sudo modprobe usbmon&lt;/pre&gt;
&lt;br&gt;
&lt;code&gt;tshark&lt;/code&gt; (a command line tool) should now be able to capture on usbmon interfaces. Check it using:&lt;br&gt;
&lt;pre&gt;$ tshark -D
1. eth0
2. any
3. lo (Loopback)
4. nflog
5. nfqueue
6. usbmon1
7. usbmon2&lt;/pre&gt;
&lt;br&gt;
In my case I have 2 USB buses labeled usbmon1 and usbmon2.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Capture the USB frames&lt;/h2&gt;
Before capturing the USB frames you need to know on which USB bus is connected your device.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
Identify the device USB bus&lt;/h3&gt;
&lt;pre&gt;$ lsusb 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 004: ID 08e6:3437 Gemplus GemPC Twin SmartCard Reader
Bus 002 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub&lt;/pre&gt;
&lt;br&gt;
In my case the device I want to study is on the bus 002 so I will use usbmon2.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
Start the capture&lt;/h3&gt;
&lt;pre&gt;$ tshark -i usbmon2 -w trace1.pcap
Capturing on 'usbmon2'
tshark: The capture session could not be initiated on interface 'usbmon2' (Can't open USB bus file /sys/kernel/debug/usb/usbmon/2t: Permission denied).
Please check to make sure you have sufficient permissions, and that you have the proper interface or pipe specified.&lt;/pre&gt;
&lt;br&gt;
For security reasons &lt;code&gt;tshark&lt;/code&gt; refuses to be run as root. So I needed to change some file access rights.&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ sudo chmod +rx /sys/kernel/debug/
$ sudo chmod a+rw /sys/kernel/debug/usb/usbmon/2t&lt;/pre&gt;
&lt;br&gt;
Then (re)start tshark and use Ctrl-C to stop after some traffic has been captured.&lt;br&gt;
&lt;pre&gt;$ tshark -i usbmon2 -w trace1.pcap
Capturing on 'usbmon2'
1270 tshark: Can't get packet-drop statistics: Can't open USB stats file /sys/kernel/debug/usb/usbmon/2s: Permission denied
Please report this to the Wireshark developers.
http://bugs.wireshark.org/
(This is not a crash; please do not report it as such.)&lt;/pre&gt;
&lt;br&gt;
&lt;h2&gt;
Capture analysis&lt;/h2&gt;
The file &lt;code&gt;trace1.pcap&lt;/code&gt; contains the USB frames and can be displayed using the graphical interface of Wireshark.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
Enable the CCID decoder&lt;/h3&gt;
Unless you can read the CCID protocol from hexadecimal, it is a good idea to tell Wireshark to decode the USB frames as USBCCID.&lt;br&gt;
Go in the menu "Analyze" -&amp;gt; "Decode as..." and select USBCCID in the dialog.&lt;br&gt;
&lt;br&gt;
&lt;img border="0" src="https://blog.apdu.fr/images/2014/10/wireshark_usbccid.thumb.png"&gt;&lt;br&gt;
&lt;br&gt;
Wireshark will then display the USB frames with nice CCID names:&lt;br&gt;
&lt;img border="0" src="https://blog.apdu.fr/images/2014/10/wireshark_poweron.thumb.png"&gt;&lt;br&gt;
&lt;br&gt;
Here you can see a CCID Power On command.&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;The command name is displayed in the top window: "Packet - PC to Reader: ICC Power On"&lt;/li&gt;
&lt;li&gt;And the content of the command (the 10 last bytes specific to CCID) are documented in the lower window: "Message Type: PC_to_RDR_IccPowerOn (0x62)", etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
I do not expect every one to use Wireshark to look at CCID frames. But if you have a problem with a CCID reader and wants to know exactly what is happening Wireshark can help you for a very very limited budget (Wireshark is a free software under GNU GPL v2 license).&lt;br&gt;
&lt;br&gt;
This blog article is also a way for me to document how to do it for the next time :-)&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
Wireshark is a great tool.&lt;br&gt;
Linux is a great kernel.&lt;br&gt;
Debian GNU/Linux is a great operating system.</description><category>ccid</category><category>debug</category><category>wireshark</category><guid>https://blog.apdu.fr/posts/2014/10/ccid-usb-spy-using-wireshark/</guid><pubDate>Wed, 08 Oct 2014 19:35:00 GMT</pubDate></item><item><title>USB issues with a Raspberry Pi</title><link>https://blog.apdu.fr/posts/2014/04/usb-issues-with-raspberry-pi/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;Some people report problems with my &lt;a href="https://ccid.apdu.fr/"&gt;CCID driver&lt;/a&gt; and a &lt;a href="http://www.raspberrypi.org/"&gt;Raspberry Pi&lt;/a&gt;. The problem is not with the CCID driver but with the Raspberry Pi itself.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="https://blog.apdu.fr/images/2014/04/rpi+logo.thumb.png"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
I don't know if the problem is hardware, software or a combination of the two. I found a description of the problem on the excellent website &lt;span id="goog_1181587165"&gt;&lt;/span&gt;&lt;span id="goog_1181587166"&gt;&lt;/span&gt;&lt;a href="http://yoctopuce.com/"&gt;yoctopuce.com&lt;/a&gt;. For example from the article "&lt;a href="http://www.yoctopuce.com/EN/article/cook-and-hold-with-raspberry-pi-video"&gt;Cook and Hold with Raspberry Pi (video)&lt;/a&gt;" you can read:&lt;br&gt;
&lt;br&gt;
&lt;blockquote class="tr_bq"&gt;
There is one caveat on the Raspberry Pi : the USB support is still somewhat &lt;strike&gt;buggy&lt;/strike&gt; perfectible, and we will need to configure it to make it work reliably. The problem is, the RasPi will occasionally drop USB packets for "full-speed" peripherals (such as keyboard, mouse, modems, as well as some audio devices) when working in standard "high-speed" mode. The problem is less acute with the &lt;a href="https://github.com/raspberrypi/firmware"&gt;most recent firmware&lt;/a&gt;, but it is not completely solved. The only reliable workaround for now is to force all peripherals to run in "full-speed" mode. This will have the negative side effect of limiting all peripherals (including the on-board network adapter) to 1.5 MBytes/s, but anyway, the Raspberry Pi is not designed to be a race horse...&lt;br&gt;
&lt;br&gt;
To force USB to run in "full-speed" mode, simply add &lt;code&gt;dwc_otg.speed=1&lt;/code&gt; to the &lt;code&gt;/boot/cmdline.txt&lt;/code&gt; file, as follows:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
dwc_otg.speed=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4
elevator=deadline rootwait&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br&gt;</description><category>ccid</category><category>debug</category><guid>https://blog.apdu.fr/posts/2014/04/usb-issues-with-raspberry-pi/</guid><pubDate>Thu, 24 Apr 2014 17:50:00 GMT</pubDate></item><item><title>Level 1 smart card support on Mac OS X</title><link>https://blog.apdu.fr/posts/2014/03/level-1-smart-card-support-on-mac-os-x/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;It may not be easy to check if a smart card stack works or not. I will explain what you can do as a first step to check your smart card stack on Mac OS X.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;h2&gt;pcsctest&lt;/h2&gt;Apple provides a command line tool &lt;code&gt;pcsctest&lt;/code&gt;. It is an evolution of &lt;a href="http://anonscm.debian.org/viewvc/pcsclite/trunk/PCSC/src/testpcsc.c?view=markup"&gt;testpcsc&lt;/a&gt; provided by the "official" pcsc-lite.&lt;br&gt;
&lt;br&gt;
The Apple pcsctest source code is available at &lt;a href="http://opensource.apple.com/source/SmartCardServices/SmartCardServices-55111/src/PCSC/testpcsc.c"&gt;http://opensource.apple.com/source/SmartCardServices/SmartCardServices-55111/src/PCSC/testpcsc.c&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
The good news is that this command line tool is installed by default. So every Mac OS X install should have it out of the box.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;Command line tool &lt;/h3&gt;To run a command line tool you need to start the Terminal application from the &lt;tt&gt;/Applications/Utilities/&lt;/tt&gt; directory.&lt;br&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://blog.apdu.fr/images/2014/03/terminal.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="https://blog.apdu.fr/images/2014/03/terminal.png"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Terminal icon&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;
&lt;br&gt;
You will then get a Terminal window with a prompt&lt;br&gt;
&lt;pre&gt;$
&lt;/pre&gt;&lt;br&gt;
&lt;h3&gt;Normal execution&lt;/h3&gt;In &lt;span style="background-color: lime;"&gt;green&lt;/span&gt; the commands entered by the user.&lt;br&gt;
In &lt;span style="background-color: yellow;"&gt;yellow&lt;/span&gt; the important information. &lt;br&gt;
&lt;br&gt;
If your reader is connected and a smart card is inserted you should get something like:&lt;br&gt;
&lt;pre&gt;$ &lt;span style="background-color: lime;"&gt;pcsctest&lt;/span&gt; 

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: &lt;span style="background-color: yellow;"&gt;Gemplus GemPC Twin 00 00&lt;/span&gt;
Enter the reader number          : &lt;span style="background-color: lime;"&gt;1&lt;/span&gt;
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : &lt;span style="background-color: yellow;"&gt;Gemplus GemPC Twin 00 00&lt;/span&gt;
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 9 (0x9)
Current Reader ATR Value         : &lt;span style="background-color: yellow;"&gt;3B 65 00 00 20 63 CB A6 A0&lt;/span&gt; 
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: Gemplus GemPC Twin 00 00
Enter the reader number          : &lt;span style="background-color: lime;"&gt;1&lt;/span&gt;
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Gemplus GemPC Twin 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 9 (0x9)
Current Reader ATR Value         : 3B 65 00 00 20 63 CB A6 A0 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.

PC/SC Test Completed Successfully !&lt;/pre&gt;&lt;br&gt;
You should note:&lt;br&gt;
&lt;ul&gt;&lt;li&gt;the reader name &lt;span style="background-color: yellow;"&gt;Gemplus GemPC Twin 00 00 &lt;/span&gt;&lt;br&gt;
&lt;/li&gt;
&lt;li&gt;the card ATR &lt;span style="background-color: yellow;"&gt;3B 65 00 00 20 63 CB A6 A0&lt;/span&gt;&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;In this case the reader is correctly found and the communication with the card is working.&lt;br&gt;
&lt;br&gt;
You can then use the online &lt;a href="http://smartcard-atr.appspot.com/"&gt;Smart card ATR parsing&lt;/a&gt; tool to check the ATR corresponds to the card you inserted. In the present case it is a &lt;a href="http://smartcard-atr.appspot.com/parse?ATR=3B6500002063CBA6A0"&gt;French banking card&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;No reader connected&lt;/h3&gt;&lt;pre&gt;$ &lt;span style="background-color: lime;"&gt;pcsctest&lt;/span&gt; 

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : &lt;span style="background-color: yellow;"&gt;Service not available.&lt;/span&gt;
&lt;/pre&gt;&lt;br&gt;
On Mac OS X the PC/SC service (in fact the &lt;code&gt;pcscd&lt;/code&gt; daemon) is started  by the securityd process at boot and when a USB smart card reader is connected.&lt;br&gt;
So if no reader is connected you get the error: "Service not available" because pcscd is not yet running.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;No smart card inserted&lt;/h3&gt;&lt;pre&gt;$ &lt;span style="background-color: lime;"&gt;pcsctest&lt;/span&gt; 

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: Gemplus GemPC Twin 00 00
Enter the reader number          : &lt;span style="background-color: lime;"&gt;1&lt;/span&gt;
&lt;span style="background-color: yellow;"&gt;Waiting for card insertion&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;
The program is then waiting for a card insertion.&lt;br&gt;
&lt;br&gt;
If you have a card inserted and you do not get the ATR or an error then you have a problem.&lt;br&gt;
&lt;br&gt;
If you insert a card and get the error "Card is unpowered" then you may have inserted the card the wrong way (or your card is dead).&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;System information&lt;/h2&gt;If your reader is connected but you can't see it with &lt;code&gt;pcsctest&lt;/code&gt; then maybe the USB device is not seen by Mac OS X.&lt;br&gt;
&lt;br&gt;
You can use the System Information application from the &lt;tt&gt;/Applications/Utilities/&lt;/tt&gt; directory.&lt;br&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://blog.apdu.fr/images/2014/03/systeminfo.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="https://blog.apdu.fr/images/2014/03/systeminfo.png"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;System Information icon&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;
&lt;br&gt;
In the application you select the USB subsection in the Hardware section and can see all the USB devices known by the system.&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blog.apdu.fr/images/2014/03/Screen+Shot.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blog.apdu.fr/images/2014/03/Screen+Shot.png"&gt;&lt;/a&gt;&lt;/div&gt;If you can't see your USB smart card reader then you have a USB issue, not a PC/SC issue.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;Command line&lt;/h3&gt;You can also use the equivalent command in the Terminal:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ system_profiler SPUSBDataType&lt;/pre&gt;&lt;br&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;These first steps are easy to execute on Mac OS X. If the &lt;code&gt;pcsctest&lt;/code&gt; test succeeds then you can be confident that the smart card reader and the PC/SC layer are working correctly.&lt;br&gt;
&lt;br&gt;
If the &lt;code&gt;pcsctest&lt;/code&gt; test fails then you need to go to a level 2 smart card support on Mac OS X.</description><category>debug</category><category>Mac OS X</category><category>pcsc-lite</category><guid>https://blog.apdu.fr/posts/2014/03/level-1-smart-card-support-on-mac-os-x/</guid><pubDate>Thu, 20 Mar 2014 15:03:00 GMT</pubDate></item><item><title>PCSC API spy, on Mac OS X</title><link>https://blog.apdu.fr/posts/2014/02/pcsc-api-spy-on-mac-os-x/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;In a previous article "&lt;a href="https://blog.apdu.fr/posts/2011/11/pcsc-api-spy-third-try/"&gt;PCSC API spy, third try&lt;/a&gt;" 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.&lt;br&gt;
&lt;br&gt;
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.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;code&gt;pcsc-spy&lt;/code&gt; is part of (the official) pcsc-lite. You can get it from the &lt;a href="https://pcsclite.apdu.fr/"&gt;PCSC lite project&lt;/a&gt; web page. The latest version of pcsc-lite as I write this blog entry is 1.8.10.&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ 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&lt;/pre&gt;
&lt;br&gt;
Now you can find a &lt;code&gt;PCSC.framework&lt;/code&gt; directory that is the equivalent of &lt;code&gt;libpcscspy.so&lt;/code&gt; on GNU/Linux.&lt;br&gt;
&lt;br&gt;
The installation is not automatic but very easy. You copy the &lt;code&gt;PCSC.framework&lt;/code&gt; directory in &lt;code&gt;/tmp&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ cp -a PCSC.framework /tmp&lt;/pre&gt;
&lt;br&gt;
Copy the official &lt;code&gt;PCSC.framework&lt;/code&gt; (binary only) in &lt;code&gt;/tmp&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ cp /System/Library/Frameworks/PCSC.framework/PCSC /tmp&lt;/pre&gt;
&lt;br&gt;
Since we use the temporary directory &lt;code&gt;/tmp&lt;/code&gt; the log/debug files will be automatically erased on the next system boot. No side effect.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Execution&lt;/h2&gt;
In a Terminal application window (shell) run the &lt;code&gt;pcsc-spy&lt;/code&gt; command:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ ./pcsc-spy&lt;/pre&gt;
&lt;br&gt;
In another Terminal application windows run the application you want to debug:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ 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 !&lt;/pre&gt;
&lt;br&gt;
In the first Terminal window you will get the colorfull (oh yeah!) log output:&lt;br&gt;
&lt;pre&gt;&lt;span style="color: #0000aa;"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o hContext: 0x0103253B&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000722]
&lt;span style="color: #0000aa;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwTimeout: 0xFFFFFFFF (4294967295)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i cReaders: 0&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000044]
&lt;span style="color: #0000aa;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o pcchReaders: 0x00000015&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: NULL&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000059]
&lt;span style="color: #0000aa;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o pcchReaders: 0x00000015&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: &lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000042]
&lt;span style="color: #0000aa;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwTimeout: 0xFFFFFFFF (4294967295)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i szReader: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; 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)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  Atr length: 0x00000012 (18)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  Atr: 00 00 00 00 68 70 E7 0D 01 00 00 00 01 00 00 00 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o szReader: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  Atr length: 0x0000000C (12)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000163]
&lt;span style="color: #0000aa;"&gt;SCardConnect&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i szReader Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwShareMode: SCARD_SHARE_SHARED (0x00000002)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwPreferredProtocols: 0x00000003 (T=0, T=1)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i phCard 0x00007FFF (32767)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pdwActiveProtocol 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o phCard 0x0001616A (90474)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwActiveProtocol: T=0 (0x00000001)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000411198]
&lt;span style="color: #0000aa;"&gt;SCardStatus&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hCard: 0x0001616A&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pcchReaderLen 0x00000034 (52)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pcbAtrLen 0x00000021 (33)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o cchReaderLen 0x00000014 (20)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaderName Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwState 0x00000034 (52)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwProtocol 0x00000001 (1)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o bAtrLen 0x0000000C (12)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000473]
&lt;span style="color: #0000aa;"&gt;SCardDisconnect&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hCard: 0x0001616A&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwDisposition: SCARD_UNPOWER_CARD (0x00000002)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000594971]
&lt;span style="color: #0000aa;"&gt;SCardReleaseContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x0103253B&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000209]
&lt;span style="color: #0000aa;"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o hContext: 0x01035D3C&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000541]
&lt;span style="color: #0000aa;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwTimeout: 0xFFFFFFFF (4294967295)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i cReaders: 0&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000033]
&lt;span style="color: #0000aa;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o pcchReaders: 0x00000015&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: NULL&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000034]
&lt;span style="color: #0000aa;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o pcchReaders: 0x00000015&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaders: &lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000039]
&lt;span style="color: #0000aa;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwTimeout: 0xFFFFFFFF (4294967295)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i szReader: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  Atr length: 0x0000000C (12)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o szReader: Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  Atr length: 0x0000000C (12)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000129]
&lt;span style="color: #0000aa;"&gt;SCardConnect&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i szReader Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwShareMode: SCARD_SHARE_SHARED (0x00000002)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwPreferredProtocols: 0x00000003 (T=0, T=1)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i phCard 0x0001616A (90474)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pdwActiveProtocol 0x00000001 (1)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o phCard 0x00011242 (70210)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwActiveProtocol: T=0 (0x00000001)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000411238]
&lt;span style="color: #0000aa;"&gt;SCardStatus&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hCard: 0x00011242&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pcchReaderLen 0x00000034 (52)&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i pcbAtrLen 0x00000021 (33)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o cchReaderLen 0x00000014 (20)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o mszReaderName Feitian bR301 00 00&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwState 0x00000034 (52)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o dwProtocol 0x00000001 (1)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o bAtrLen 0x0000000C (12)&lt;/span&gt;
&lt;span style="color: #aa00aa;"&gt; o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000465]
&lt;span style="color: #0000aa;"&gt;SCardDisconnect&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hCard: 0x00011242&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i dwDisposition: SCARD_UNPOWER_CARD (0x00000002)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000594863]
&lt;span style="color: #0000aa;"&gt;SCardReleaseContext&lt;/span&gt;
&lt;span style="color: #00aa00;"&gt; i hContext: 0x01035D3C&lt;/span&gt;
 =&amp;gt; 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
&lt;/pre&gt;
&lt;br&gt;
&lt;h3&gt;
Analysis&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PC/SC commands are in &lt;span style="color: blue;"&gt;blue&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Input arguments are in &lt;span style="color: green;"&gt;green&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Output arguments are in &lt;span style="color: purple;"&gt;mangenta&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Errors are in &lt;span style="color: red; font-weight: bold;"&gt;bold red&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The last part of the log contains some statistics about: functions called and times consumed by each of them&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;
Raw log file&lt;/h2&gt;
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:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ mkfifo ~/pcsc-spy
$ cat ~/pcsc-spy &amp;gt; logfile&lt;/pre&gt;
and run your PC/SC application.&lt;br&gt;
&lt;br&gt;
The API trace is stored in the file &lt;code&gt;logfile&lt;/code&gt;. It is displayed using:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ pcsc-spy.py logfile&lt;/pre&gt;
&lt;br&gt;
&lt;h2&gt;
Documentation&lt;/h2&gt;
The documentation is included with the pcsc-lite source code and is also available online at &lt;a href="http://pcsclite.alioth.debian.org/pcsc-spy.1.html"&gt;pcsc-spy.1&lt;/a&gt; manpage.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
It is easy to generate a nice PC/SC log on Mac OS X.</description><category>code</category><category>debug</category><category>Mac OS X</category><category>pcsc-lite</category><category>Python</category><guid>https://blog.apdu.fr/posts/2014/02/pcsc-api-spy-on-mac-os-x/</guid><pubDate>Sat, 08 Feb 2014 16:49:00 GMT</pubDate></item><item><title>PCSC API spy, third try</title><link>https://blog.apdu.fr/posts/2011/11/pcsc-api-spy-third-try/</link><dc:creator>Ludovic Rousseau</dc:creator><description>&lt;p&gt;&lt;b&gt;[UPDATE from 2022]&lt;/b&gt;: see also "&lt;a href="https://blog.apdu.fr/posts/2022/06/pcsc-api-spy-update/"&gt;PCSC API spy, update&lt;/a&gt;".&lt;br&gt;&lt;/p&gt;&lt;p&gt;I already blogged about how to spy the PCSC API in &lt;a href="https://blog.apdu.fr/posts/2010/08/pcsc-api-spy-for-gnu-systems/"&gt;PCSC API spy for GNU systems&lt;/a&gt; and &lt;a href="https://blog.apdu.fr/posts/2011/01/pcsc-api-spy-another-way/"&gt;PCSC API spy, another way&lt;/a&gt;. But I am still not happy with the limitations and side effects.&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;h2&gt;
 Limitations of previous solutions&lt;/h2&gt;
&lt;h3&gt;
 ltrace&lt;/h3&gt;
&lt;a href="https://blog.apdu.fr/posts/2010/08/pcsc-api-spy-for-gnu-systems/"&gt;ltrace&lt;/a&gt; is able to trace the calls to any library (including &lt;code&gt;libpcsclite.so.1&lt;/code&gt;). But one major limitation is that it does not work if the library is not linked to the executable. It does not work when:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;libpcsclite.so.1 is used by a library used by the executable (like a PKCS#11 library)&lt;/li&gt;
&lt;li&gt;libpcsclite.so.1 is dynamically loaded using &lt;code&gt;dlopen()&lt;/code&gt; as is done by OpenSC&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;
 Internal tracing&lt;/h3&gt;
&lt;a href="https://blog.apdu.fr/posts/2011/01/pcsc-api-spy-another-way/"&gt;Internal tracing&lt;/a&gt; do not have the limitations of ltrace. But one major drawback is the need to rebuild pcsc-lite with a specific configuration. This may be very difficult or impossible to do on a production system.&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
 Use an independent library&lt;/h2&gt;
The new idea is to &lt;i&gt;not&lt;/i&gt; need to rebuild pcsc-lite. Instead we will use a new library that will be placed between the PC/SC client and the PC/SC library. This new library will spy all the calls and send them to a pretty displayer.&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;+------------------+
|  PC/SC client    |
+------------------+
        |
+------------------+    +-------------+
| libpcscspy.so.0  | -&amp;gt; | pcsc-spy.py |
+------------------+    +-------------+
        |
+------------------+
| libpcsclite.so.1 |
+------------------+
&lt;/pre&gt;
&lt;br&gt;
&lt;h3&gt;
 Two configurations are available&lt;/h3&gt;
&lt;br&gt;
To be able to spy the PC/SC layer the application flow must be modified so that all PC/SC calls are redirected.&lt;br&gt;
&lt;br&gt;
&lt;h4&gt;
 Applications linked with libpcsclite.so.1&lt;/h4&gt;
&lt;br&gt;
We will use the standard &lt;code&gt;LD_PRELOAD&lt;/code&gt; loader option to load our spying library.&lt;br&gt;
&lt;br&gt;
Example:&lt;br&gt;
&lt;code&gt;LD_PRELOAD=/usr/lib/libpcscspy.so opensc-tool -a&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;h4&gt;
 Application loading libpcsclite.so.1&lt;/h4&gt;
&lt;br&gt;
This is the case for the PC/SC wrappers like pyscard (for Python) and pcsc-perl (for Perl). The &lt;code&gt;LD_PRELOAD&lt;/code&gt; mechanism can't be used. Instead we replace the &lt;code&gt;libpcsclite.so.1&lt;/code&gt; library by the spying one.&lt;br&gt;
&lt;br&gt;
Use &lt;code&gt;install_spy.sh&lt;/code&gt; and &lt;code&gt;uninstall_spy.sh&lt;/code&gt; to install and uninstall the spying library.&lt;br&gt;
&lt;br&gt;
Using the spying library without &lt;code&gt;pcsc-spy.py&lt;/code&gt; is not a problem but has side effects:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;a line "&lt;tt&gt;libpcsclite_nospy.so.1: cannot open shared object file: No such file or directory&lt;/tt&gt;" will be displayed&lt;/li&gt;
&lt;li&gt;some CPU time will be lost because of the PC/SC calls redirection&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;
 Starting the spy tool&lt;/h3&gt;
&lt;br&gt;
&lt;h4&gt;
 Direct output&lt;/h4&gt;
&lt;pre&gt;$ pcsc-spy.py&lt;/pre&gt;
&lt;br&gt;
&lt;h4&gt;
 Store for later use&lt;/h4&gt;
If a command argument is passed we use it instead of the default &lt;code&gt;~/pcsc-spy&lt;/code&gt; FIFO file. It is then possible to record an execution log and use &lt;code&gt;pcsc-spy.py&lt;/code&gt; multiple times on the same log.&lt;br&gt;
&lt;br&gt;
To create the log file just do:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;$ mkfifo ~/pcsc-spy
$ cat ~/pcsc-spy &amp;gt; logfile&lt;/pre&gt;
&lt;br&gt;
and run your PC/SC application. The API trace is stored in the file &lt;code&gt;logfile&lt;/code&gt;. It is displayed using:&lt;br&gt;
&lt;pre&gt;$ pcsc-spy.py logfile&lt;/pre&gt;
&lt;br&gt;
&lt;h2&gt;
 Example using OpenSC&lt;/h2&gt;
&lt;br&gt;
&lt;h3&gt;
 Executed command&lt;/h3&gt;
&lt;pre&gt;$ LD_PRELOAD=/usr/lib/libpcscspy.so opensc-tool -a
Using reader with a card: Gemalto GemPC Twin 00 00
3b:9f:95:81:31:fe:9f:00:65:46:53:05:30:06:71:df:00:00:00:81:61:0f:d9
&lt;/pre&gt;
&lt;br&gt;
&lt;h3&gt;
 API log&lt;/h3&gt;
&lt;pre&gt;$ pcsc-spy.py
&lt;span style="color: blue;"&gt;SCardEstablishContext&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwScope: SCARD_SCOPE_USER (0x00000000)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o hContext: 0x0103E68C&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000219919]
&lt;span style="color: blue;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o pcchReaders: 0x0000001A&lt;/span&gt;
&lt;span style="color: purple;"&gt; o mszReaders: NULL&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000128]
&lt;span style="color: blue;"&gt;SCardListReaders&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i mszGroups: (null)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o pcchReaders: 0x0000001A&lt;/span&gt;
&lt;span style="color: purple;"&gt; o mszReaders: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: purple;"&gt; o mszReaders: &lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000101]
&lt;span style="color: blue;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwTimeout: 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwCurrentState:  (0x00000000)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwEventState:  (0x00000000)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr length: 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr: &lt;/span&gt;
&lt;span style="color: purple;"&gt; o szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwCurrentState:  (0x00000000)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000184]
&lt;span style="color: blue;"&gt;SCardConnect&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwShareMode: SCARD_SHARE_SHARED (0x00000002)&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwPreferredProtocols: 0x00000003 (T=0, T=1)&lt;/span&gt;
&lt;span style="color: green;"&gt; i phCard 0x02432010 (37953552)&lt;/span&gt;
&lt;span style="color: green;"&gt; i pdwActiveProtocol 0x00000020 (32)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o phCard 0x00015425 (87077)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o dwActiveProtocol: T=1 (0x00000002)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000020242]
&lt;span style="color: blue;"&gt;SCarControl&lt;/span&gt;
&lt;span style="color: green;"&gt; i hCard: 0x00015425&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwControlCode: CM_IOCTL_GET_FEATURE_REQUEST (0x42000D48)&lt;/span&gt;
&lt;span style="color: green;"&gt; i bSendLength 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i bSendBuffer&lt;/span&gt;
&lt;span style="color: green;"&gt; i  NULL&lt;/span&gt;
&lt;span style="color: purple;"&gt; o bRecvLength 0x00000012 (18)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o bRecvBuffer&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  0000 0A 04 42 33 00 0A 12 04 42 33 00 12 13 04 42 00 ..B3....B3....B.&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  0010 00 01                                           ..&lt;/span&gt;
  parsing CM_IOCTL_GET_FEATURE_REQUEST results:
  Tag FEATURE_IFD_PIN_PROPERTIES is 0x4233000A
  Tag FEATURE_GET_TLV_PROPERTIES is 0x42330012
  Tag FEATURE_CCID_ESC_COMMAND is 0x42000001
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000130]
&lt;span style="color: blue;"&gt;SCarControl&lt;/span&gt;
&lt;span style="color: green;"&gt; i bSendBuffer&lt;/span&gt;
&lt;span style="color: green;"&gt; i  NULL&lt;/span&gt;
&lt;span style="color: purple;"&gt; o bRecvLength 0x00000004 (4)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o bRecvBuffer&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  0000 00 00 07 00                                     ....&lt;/span&gt;
  parsing FEATURE_IFD_PIN_PROPERTIES results:
  wLcdLayout: 0 0
  bEntryValidationCondition: 7
  bTimeOut2: 0
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000334]
&lt;span style="color: blue;"&gt;SCardDisconnect&lt;/span&gt;
&lt;span style="color: green;"&gt; i hCard: 0x00015425&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwDisposition: SCARD_LEAVE_CARD (0x00000000)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000362]
&lt;span style="color: blue;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwTimeout: 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwCurrentState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: purple;"&gt; o szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwCurrentState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwEventState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: red; font-weight: bold;"&gt; =&amp;gt; Command timeout. (SCARD_E_TIMEOUT [0x8010000A]) &lt;/span&gt; [0.000000352]
&lt;span style="color: blue;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwTimeout: 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwCurrentState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwEventState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: purple;"&gt; o szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwCurrentState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwEventState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: red; font-weight: bold;"&gt; =&amp;gt; Command timeout. (SCARD_E_TIMEOUT [0x8010000A]) &lt;/span&gt; [0.000000303]
&lt;span style="color: blue;"&gt;SCardGetStatusChange&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwTimeout: 0x00000000 (0)&lt;/span&gt;
&lt;span style="color: green;"&gt; i cReaders: 1&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwCurrentState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  dwEventState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: green;"&gt; i  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: purple;"&gt; o szReader: Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwCurrentState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  dwEventState: SCARD_STATE_PRESENT (0x00000020)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr length: 0x00000017 (23)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o  Atr: 3B 9F 95 81 31 FE 9F 00 65 46 53 05 30 06 71 DF 00 00 00 81 61 0F D9&lt;/span&gt;
&lt;span style="color: red; font-weight: bold;"&gt; =&amp;gt; Command timeout. (SCARD_E_TIMEOUT [0x8010000A]) &lt;/span&gt; [0.000000215]
&lt;span style="color: blue;"&gt;SCardConnect&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
&lt;span style="color: green;"&gt; i szReader Gemalto GemPC Twin 00 00&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwShareMode: SCARD_SHARE_SHARED (0x00000002)&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwPreferredProtocols: 0x00000003 (T=0, T=1)&lt;/span&gt;
&lt;span style="color: green;"&gt; i phCard 0x0243EA80 (38005376)&lt;/span&gt;
&lt;span style="color: green;"&gt; i pdwActiveProtocol 0x7FFEE90B2420 (140732808242208)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o phCard 0x000104C4 (66756)&lt;/span&gt;
&lt;span style="color: purple;"&gt; o dwActiveProtocol: T=1 (0x00000002)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000142]
&lt;span style="color: blue;"&gt;SCardBeginTransaction&lt;/span&gt;
&lt;span style="color: green;"&gt; i hCard: 0x000104C4&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000070]
&lt;span style="color: blue;"&gt;SCardEndTransaction&lt;/span&gt;
&lt;span style="color: green;"&gt; i hCard: 0x000104C4&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwDisposition: SCARD_LEAVE_CARD (0x00000000)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000002802]
&lt;span style="color: blue;"&gt;SCardDisconnect&lt;/span&gt;
&lt;span style="color: green;"&gt; i hCard: 0x000104C4&lt;/span&gt;
&lt;span style="color: green;"&gt; i dwDisposition: SCARD_RESET_CARD (0x00000001)&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000058724]
&lt;span style="color: blue;"&gt;SCardReleaseContext&lt;/span&gt;
&lt;span style="color: green;"&gt; i hContext: 0x0103E68C&lt;/span&gt;
 =&amp;gt; Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000204]

Results sorted by total execution time
total time: 0.304753 sec
0.219919 sec (  1 calls) 72.16% SCardEstablishContext
0.059086 sec (  2 calls) 19.39% SCardDisconnect
0.020384 sec (  2 calls)  6.69% SCardConnect
0.002802 sec (  1 calls)  0.92% SCardEndTransaction
0.001054 sec (  4 calls)  0.35% SCardGetStatusChange
0.000464 sec (  2 calls)  0.15% SCardControl
0.000229 sec (  2 calls)  0.08% SCardListReaders
0.000204 sec (  1 calls)  0.07% SCardReleaseContext
0.000070 sec (  1 calls)  0.02% SCardBeginTransaction
&lt;/pre&gt;
&lt;br&gt;
&lt;h3&gt;
 Analysis&lt;/h3&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;PC/SC commands are in &lt;span style="color: blue;"&gt;blue&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Input arguments are in &lt;span style="color: green;"&gt;green&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Output arguments are in &lt;span style="color: purple;"&gt;mangenta&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Errors are in &lt;span style="color: red; font-weight: bold;"&gt;bold red&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The last part of the log contains some statistics about: functions called and times consumed by each of them&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;
 Next steps&lt;/h2&gt;
Some ideas for the future:&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
 Parse the APDU&lt;/h3&gt;
For now the APDUs are displayed as a buffer of bytes. It would be great to display the command name corresponding to an INS byte. For example "SELECT FILE" is easier to read than "A4".&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
 Smart card activity live monitoring&lt;/h3&gt;
I often run pcscd in debug mode to know if something is happening at the PC/SC layer. I then know if the application is doing a lot of smart card accesses and I will just wait or if the application is locked somewhere and I should kill/debug it.&lt;br&gt;
&lt;br&gt;
The idea is to send the PC/SC API log stream to a "live monitor" able to display a status using colors for example. The GUI still has to be designed. Please propose ideas.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
 PC/SC calls correctness&lt;/h3&gt;
With all the PC/SC API calls you can check your application is using the API correctly. For example you should have the same number of &lt;code&gt;SCardEstablishContext()&lt;/code&gt; and &lt;code&gt;SCardReleaseContext()&lt;/code&gt; calls.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
 Mac OS X support&lt;/h3&gt;
Logs from pcscd are very difficult to read. See &lt;a href="https://blog.apdu.fr/posts/2011/07/pcscd-debug-output-on-mac-os-x/"&gt;pcscd debug output on Mac OS X&lt;/a&gt;. A clear PCSC API spy tool would be a real plus.&lt;br&gt;
&lt;br&gt;
I do plan to work on porting the spying layer but I don't know when I will work on it. You can work on it and provide patches and ideas.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
 Windows support?&lt;/h3&gt;
I do not plan to work on a Windows port myself. At least not without a very big amount of money :-).&lt;br&gt;
&lt;br&gt;
If you want to work on this please do. I may integrate your changes if they do not break GNU/Linux and Mac OS X supports.&lt;br&gt;
&lt;br&gt;
[UPDATE] Petr Svenda wrote a PC/SC API spy for Windows: &lt;a href="http://www.fi.muni.cz/~xsvenda/apduinspect.html"&gt;PC/SC APDU inspection and manipulation tool (APDUPlay)&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;
 Conclusion&lt;/h2&gt;
I hope this API spy feature will work in the long term. It is already the 3rd iteration of API log.&lt;br&gt;
&lt;br&gt;
The displayer program (&lt;code&gt;pcsc-spy.py&lt;/code&gt;) is written in Python. It should be easy to extend and make it do some complex tasks.</description><category>code</category><category>debug</category><category>pcsc-lite</category><category>Python</category><guid>https://blog.apdu.fr/posts/2011/11/pcsc-api-spy-third-try/</guid><pubDate>Fri, 18 Nov 2011 08:52:00 GMT</pubDate></item></channel></rss>