This is the first digest of what happened to the the development of Chrysalide during the last month.
It gives details about some of the main new features or about the fixed bugs for all of those who are interested in the project.
The following news is based on commit 537ed96, so you can give this version of Chrysalide a try by running:
git clone http://git.0xdeadc0de.fr/chrysalide.git cd chrysalide git checkout 537ed96
And then follow the installation procedure.
The graphical editor is the main way to use Chrysalide, so the GUI has been improved a little bit!
In the disassembly view, each routine now ends with a special mark. This helps a lot to distinguish the code area among the binary data (commit e2bce99).
Labels for Android routines now include all the owners (classes or packages) (commit 7972f2d).
Access to menus have been updated (commit 34db987). That was urgent as some key bindings without modifier prevented to type some letters in all other active text entries.
The symbols panel has been refreshed. The tree view is back, and looking for symbols now highlights the matching strings (commit 7b99c25).
The old non-working Python plugin 'welcome' has been replaced by an internal native Welcome panel (commit b6afbe8).
It was too hard to discover how to load PNG pictures with Cairo and the GObject introspection for Python.
Automatic checks for newer versions is disabled by default, and the panel is displayed at startup or if there is no more content to show in the main area of Chrysalide.
Whereas the focus was given to the ARM support in the previous months, this time efforts were brought to Dalvik!
Big APKs from the Google Play Store were helpful to track bugs, and that leaded to major improvements for the Dex file format handling.
For instance, empty classes with virtual methods (interfaces) are now supported (commit 29f3cf8) and 0 is not a valid position for class data anymore: that was the beginning of the Dex file which was processed until now (commit 3ea1d4c).
A subtle bug in the decoding of exceptions handlers has been fixed (commit fe39a48) and two others bugs have been fixed in the same domain, too (commit 680a2ea). Lesson learned: read the Dalvik specifications carefully!
Moreover, readdex, the plugin adding annotations for most of the fields defined in the Dex format, now displays its progression in the status bar (commit 0f1473c).
The opcodes with operands following the '3rc/3rms/3rmi' format are also now properly decoded (commit fb6454b).
Others noticeable improvements:
- Dalvik empty strings do not make the program crash anymore (commit f4703b2).
- a typo in the hooks defined for decoding the 'if' statements was fixed, avoiding once again Chrysalide to crash (commit 291968f).
- a partial support of MUTF-8 encodings allows to load more Dex files without failure (commit 537ed96).
The Python bindings now allow the user to load Elf and Dex files from scripts. Errors due to bad arguments are handled properly with Python exceptions (commit 49f75f2).
Some symbols used in the GUI have been defined as 'weak' symbols in the Python plugin. This allows to load binaries from scripts without the graphical editor and its progress bar for instance (commit aab9705).
So the bindings get now usable for a standalone usage and get useful to quickly debug Chrysalide.
Here is a sample script showing the list of longest opcodes:
#!/usr/bin/python3-dbg # -*- coding: utf-8 -*- import pychrysalide from pychrysalide.analysis.contents import FileContent from pychrysalide.analysis import LoadedBinary from pychrysalide.format.dex import DexFormat from threading import Event cnt = FileContent('/path/to/classes.dex') binary = LoadedBinary(cnt) def disass_done(binary): worker.set() binary.connect('disassembly-done', disass_done) worker = Event() binary.analyse() worker.wait() print('disassembly done!') proc = binary.processor ins = proc.disass_instrs while ins != None: if ins.range.length > 10: print(' | 0x%08x | ' % ins.range.addr.virt + ins.keyword + ': %d' % ins.range.length) ins = proc.get_next_instr(ins)
An iterator for instructions is still lacking, but the bindings remain usable!
For some unknown reasons, the GLib g_atomic_pointer_or() function sometimes does not update its values.
It was impossible to reproduce the issue with a simple proof of concept, so a workaround with a mutex is currently used (commit 65a4b8d).
On the file format parsing side, moving the reading cursor now relies on a 'seek' function, which can be constrained to a specific area (commit 3c970a0).
This prevents out of bounds access, and parsing gets stronger.
Last words about Debian packaging: so far, there are plenty of things to fix before being able to comply with the Debian check points:
- compilation warnings: 299.
- deprecated used items: 21.
- 'TODO' marks: 344.
- 'FIXME' marks: 135.
- C++ comment: 470.
Work in progress!
Posted on September 29, 2016 at 23:48.