Analysing libreaderex - HinTak/caj2pdf GitHub Wiki

Analysing libreaderex

It is possible to mount and examine the Ubuntu AppImage with:

mount -o ro,loop,offset=187784 CAJViewer-x86_64-buildubuntu1604-201021.AppImage /mnt

Tracing runtime execution

One might like to know how Linux CAJViewer move around and reading a file. This can be achieved by tracing 'seek' and 'read' with the ltrace utility:

ltrace -C -L -x *CAJ*+\*seek\*+*read*@libreaderex_x64.so -o trace-log /mnt/usr/bin/cajviewer

To trace commmunications between the main executables and dll's of the Windows verson of CAJViewer in Wine, set the environmental variable WINEDEBUG=relay .

Be warned that the logs are huge!

The Linux shared library, static analysis

For example, we'd like to see a list of destructors of *Reader classes:

$ nm -C -D /mnt/usr/lib/libreaderex_x64.so  | grep ' T ' | grep Reader::~  | uniq
00000000004b286e T CCAJReader::~CCAJReader()
00000000004b27e8 T CCAJReader::~CCAJReader()
00000000005d9c58 T CKDHReader::~CKDHReader()
00000000005d9bd2 T CKDHReader::~CKDHReader()
0000000000671fc0 T FileReader::~FileReader()
0000000000671f6e T FileReader::~FileReader()
0000000000534ca6 T ImageReader::~ImageReader()
0000000000534c52 T ImageReader::~ImageReader()
00000000004ed5c8 T CCAJSEReader::~CCAJSEReader()
00000000004ed542 T CCAJSEReader::~CCAJSEReader()
00000000006725f4 T StreamReader::~StreamReader()
00000000006725b2 T StreamReader::~StreamReader()
00000000006d7600 T TEBDocReader::~TEBDocReader()
00000000006d74ce T TEBDocReader::~TEBDocReader()
00000000004728c0 T CReader::~CReader()
0000000000472796 T CReader::~CReader()
0000000000671b3a T MemReader::~MemReader()
0000000000671af8 T MemReader::~MemReader()

Or any Decode* methods:

$ nm -C -D /mnt/usr/lib/libreaderex_x64.so  | grep ' T ' | grep ::Decode  | uniq
00000000006bff76 T CParseRigths::DecodeRights(char*, int&)
00000000008138bc T CMd5::Decode(unsigned int*, unsigned char*, unsigned int)
00000000004a6d72 T CAJDoc::DecodeShort(char*, char*)
0000000000530cf2 T CImage::DecodeJbig(void*, unsigned int, unsigned int*)
0000000000530be6 T CImage::DecodeJpeg(char*, int, unsigned int*, int, int, int)
000000000053252a T CImage::DecodeJbig2(void*, unsigned int, unsigned int*)
00000000005326ae T CImage::DecodeJpeg2000(void*, unsigned int, unsigned int*, int, int)
00000000006a7e72 T CMarkup::DecodeCharUTF8(char const*&, char const*)
00000000006a802e T CMarkup::DecodeCharUTF16(unsigned short const*&, unsigned short const*)
00000000005357da T JBigCodec::Decode(int)
0000000000535fbe T JBigCodec::Decode(char*, unsigned int, unsigned int, unsigned int, unsigned int, char*)
0000000000535400 T JBigCodec::Decode1(int)

Of primary interests are perhaps the CImageAutoLoad class and CImage. We can look at them in further details with (requires binutils 2.32+ Feb 2019):

$ objdump -C --disassemble="CImageAutoLoad::PrepareImage()"  /mnt/usr/lib/libreaderex_x64.so
$ objdump -C --disassemble="CImage::DecodeJbig(void*, unsigned int, unsigned int*)"  /mnt/usr/lib/libreaderex_x64.so

Licensing issues?

The Linux shared library contains 8716 public symbols (30 times more than, and unlike the only ~300 in the Windows version). It appears to contain a significant part of Xpdf/libpoppler (many class names prepended with "G" to hide their similarity), FreeType, Zlib, LittleCMS, libiconv, libjpeg, Openssl, Kakadu, to name a few; without acknowledging them.

It is also interesting that there are a few spelling mistakes in C++ class names: CArrawCmdObj / CArrawLineCmdObj / CParseRigths (should be Arrow and Rights).

The windows DLL, static analysis

The Windows CAJViewer is rather less interesting, as it uses import libraries and ordinals. The viewer only uses 93 of the 343 and 356 public symbols in the two versions respectively. winedump -j import ... and winedump -j export looks at the import and export tables respectively:

$ winedump -j import ".../drive_c/Program Files/TTKN/CAJViewer 7.2/CAJVieweru.exe" | grep offset
...
  grAttrs 00000001 offset 000bec1c ReaderEx.dll
  grAttrs 00000001 offset 000bec3c sysinfo.dll
  grAttrs 00000001 offset 000bec5c d2d1.dll
$ winedump -j export ".../drive_c/Program Files/Common Files/TTKN/Bin/ReaderEx.dll"  | grep -v 'by ordinal'
...
  Entry Pt  Ordn  Name
  00123380   161 ?DecodeJpeg2000@CImage@@SAPAV1@PAXKPAKHH@Z
  00123480   162 ?DecodeJpeg@CImage@@SAPAV1@PADHPAKHHH@Z
  00052350   166 DecryptCacheFile
  0005B1F0   308 DumpGetPageInfo
  00083E00   341 SetFontMetric
  000529C0   342 _Java_ReaderEx_CreateRequest@20
$ winedump -j import ".../drive_c/Program Files/TTKN/CAJViewer 7.3/CAJVieweru.exe" | grep offset
...
  grAttrs 00000001 offset 000d3070 ReaderEx.dll
  grAttrs 00000001 offset 000d3090 sysinfo.dll
  grAttrs 00000001 offset 000d30b0 d2d1.dll
$ winedump -j export ".../drive_c/Program Files/Common Files/TTKN/Bin/ReaderEx.dll"  | grep -v 'by ordinal'
...
  Entry Pt  Ordn  Name
  00057080   161 CAJFILE_CombineGetMessage
  0005CB00   162 CAJFILE_SetCombine
  0012E9A0   166 ?DecodeJpeg2000@CImage@@SAPAV1@PAXKPAKHH@Z
  0012EAA0   308 ?DecodeJpeg@CImage@@SAPAV1@PADHPAKHHH@Z
  00053680   345 DecryptCacheFile
  0005D1E0   352 DumpGetPageInfo
  0005F5A0   353 JReaderExLib_UnZip
  0008BF50   354 SetFontMetric
  00062130   355 TestPrinter