Chip & System Security Testing 
Mobile & Backend Security Testing 
Our Company 
Contact us
Back to all articles
Vulnerability Analysis

Announcing esReven version 2023.01

9 min read
Edit by Mathieu Favréaux • Jan 12, 2023

eShard is pleased to announce the release of esReven version 2023.01! It is the first version released by eShard, and a major step forward in the life of the product.

esReven is a Timeless Debugging and Analysis (TDnA) platform for experts in reverse engineering. Technically, esReven captures a time slice of a full system execution (CPU, memory, hardware events from a virtual machine), then provides a trace of that recording for analysis. It comes batteries-included:

  • Fully UI-enabled workflow, from environment preparation to recording to analysis.
  • Unique analysis features such as Memory History or forward & backward data flow tainting, that speed up and scale the reverse engineering process.
  • Comprehensive APIs to speed up and automate your analysis & power your algorithms.
  • Knowledge-base platform to guide you all the way by providing theoretical knowledge and practical know-how.

This article covers the other important changes introduced in this release. Here is a summary:

  • Reven is now esReven, and leverages eShard's platform. What changed?
    • Expertise modules: following eShard's strengths and practices, esReven provides more knowledge & practical know-how about its usage and use cases. Two knowledge-base modules now come bundled with esReven: "Getting Started" and "Vulnerability Analysis". Read more below.
    • A more comprehensive web platfrom, which brings JupyterLab and other improvements, and includes the existing Project Manager. Read more below.
    • Deployment is now based on Docker Compose, for a simplified installation on any Linux distribution - see the online documentation.
    • Finally, versioning is now calendar based, following the "Year.Month" scheme.
  • API improvements: to even better support the JupyterLab environment, and following the trend set by the previous 2.11.0 version, multiple API objects have been introduced: you can now easily parse the call tree, or display the framebuffer, among others. Read more below.

Note: esReven applies to the Enterprise license only - read more at the end.


Reven is now esReven

With esReven, we strive to make the product even more usable and accessible than before.

Knowledge modules

This is a very important direction for us.

eShard has a history of providing both the platform for studying targets (hardware & software) and the knowledge & experience for doing so. This expertise is then packaged to be provided to our customers as knowledge modules.

Each knowledge module is a set of interactive JupyterLab notebooks produced by experts that mixes theoretical knowledge, tutorials and practical guides about a subject. What they cover can vary from basic tooling tutorials, to introductions about a topic, to practical how-to guides about a specific attack or vulnerability.

Example of a module

This approach has been very successful, and we are working on bringing it to esReven as well.

The result of this work so far is a set of two modules that we decided to include with this version of esReven for free:

  • The "Getting started" module to on-board new (or existing, but rusty!) users.
  • A "Vulnerability Analysis" module, which takes the user on the ride of recording and analyzing a CVE in Google Chrome.

We want to continue on this path: expect more work on this side in the future!


A more comprehensive web platform

This is of course the most visible element - esReven implements eShard's platform for a better web interface.

eShard framework

The existing Reven components have been integrated in the more generic eShard framework, which is now the top-most UI. It gracefully integrates the following elements:

  • My notebooks icon The My notebooks app, a JupyterLab instance, which replaces Reven's Jupyter and powers the knowledge modules.
  • Project Manager icon The existing Project Manager.
  • Offline doc icon The searchable offline documentation, for a better experience on air-gapped servers.

Existing Reven users need not worry, they will feel right at home!

Familiar UI


New APIs

Following the trend set by the previous 2.11.0 version, we kept on improving working from the Python API, making algorithms easier to build, and in general making the experience of exploring a trace from Python smoother. For this, we strive to make APIs that provide access to high-level objects while keeping the complexity as low as possible.

Type API

First of all, we have improved our Type API, which allows a user to parse high-level data in the target's memory such as typed structures, arrays, etc.:

  • It is now easier to browse the content of instances of typed object in memory:
    • using StructInstance.fields() we can now parse all members of a struct without having to fetch member's names first.
    • ArrayInstance now reliably contains PointerInstance objects, while they would sometimes contain addresses instead.
  • There is now a dedicated __format__ method for StructInstance objects. Supported by proper format methods in all objects that can be contained (FieldInstance, ArrayInstance, etc.), this allows for very straightforward formatting:
    • Here is an example of the default formatting:
      >>> print(f"{instance}") struct _RTL_AVL_TREE /* 0x8 */ { /* 0x0 */ Root : _RTL_BALANCED_NODE* = (...)* @ds:0xffffe00013174e80, }
    • Alternatively, you can choose to display the inner structures, up to a certain depth (default is 1):
      >>> print(f"{instance:max_depth=2}") struct _RTL_AVL_TREE /* 0x8 */ { /* 0x0 */ Root : _RTL_BALANCED_NODE* = (struct _RTL_BALANCED_NODE /* 0x18 */ { /* 0x0 */ Children : [_RTL_BALANCED_NODE*; 2] = [...], /* 0x0 */ Left : _RTL_BALANCED_NODE* = (...)* @ds:0xffffe000138fa510, /* 0x8 */ Right : _RTL_BALANCED_NODE* = (...)* @ds:0xffffe00012818bc0, /* 0x10 */ Red : U8[0..1] = 0, /* 0x10 */ Balance : U8[0..2] = 0, /* 0x10 */ ParentValue : U64 = 0, })* @ds:0xffffe00013174e80, }
  • If more than one type share an identical name, we can now get them all by using the Binary.types method. Notably, this allows fetching the proper _KPCR structure type on Windows 11.


Stack Events and Call Tree

We have introduced the "Stack Events" data into the Python API under the reven2.stack objects (accessible through ctx.ossi.stack). In this API, a Frame represents the time span one function call lives in, and what it does.

  • stack.frame gives access to the current StackFrame, while stack.frames() still gives all parent frames as was the case in previous version.
  • Each frame's exact time boundaries are explicit, and allow not only a display that is on-par with Axion, but precise control for your algorithms:
    • first_context and last_context give you the natural start and stop of the frame. However, there are plenty of edge-cases possible, so we also added:
    • first_executed_context gives the first time a frame appears if it has started before the beginning of the trace
    • function_start and function_location gives the resolved function start (in time) and location (in memory) (taking everything into account, such as trampolines or out-of-trace starts).
  • You can easily parse all calls made in a Frame with children, or access the Frame's parents with ancestors. Using this API recursively is possible, so you can imagine displaying a call tree as such:
    >>> def print_children(ctx: reven2.trace.Context) -> None: ... active_frame: reven2.stack.StackFrame = ctx.stack.frame() ... print(active_frame) ... for child in active_frame.children(): ... print(f"|- {child}") ... >>> print_children(server.trace.first_context + 200_000) #199862 - usbhub!UsbhDecHubBusy |- #199886 - ntoskrnl!KeWaitForSingleObject |- #200032 - ntoskrnl!ExFreePoolWithTag |- #200239 - ntoskrnl!KiAcquireKobjectLockSafe |- #200269 - ntoskrnl!KiExitDispatcher
  • Moreover, we need to handle the fact that there can be many different situations when analyzing a function: we might be interested in its own code only, skipping its children. Or we might want the children's code, up to certain binaries. Finally, we often want to skip external code such as kernel code, or of other processes that might get scheduled between first_context and last_context. In order to handle all these various situations easily, we introduced another call: descendant_events. It yields all the relevant events from a frame:
    • FrameStart: a child frame starts. From this point, I can check the child's symbol, binary, etc.
    • FrameEnd: a child frame end, allowing me to resume my analysis if I skipped over the child call.
    • StackLeave: I am entering a portion of the trace where I'm no longer executing from on this particular Stack, for instance I've entered kernel code, or another process. I should really ignore everything that is going on.
    • StackEnter: I am back into my stack, so into my frame or a child.
  • We also know that the complexity of this call tree can rapidly grow out of control, so for these situations we ensure the iterator from descendant_events could skip entire frames with skip_children(). For example, you can control the display depth as such:
    >>> def print_descendants(ctx: reven2.trace.Context) -> None: ... depth = 0 ... it = ctx.stack.frame().descendant_events() ... for event in it: ... if isinstance(event, reven2.stack.FrameStart): ... # [...] Do something ... depth += 1 ... if depth >= 3: ... # Skip any child this call may have and skip to its return ... it.skip_children() ... elif isinstance(event, reven2.stack.FrameEnd): ... depth -= 1


Framebuffer API

There is now a framebuffer entry point in the Context object! Use it to get a straight PIL.Image object representing the VM screen at this point in time. For example, fetch the screen at the start of the trace with: server.trace.first_context.framebuffer.image().

This is also very convenient to use in notebooks, as you can for instance constraint the resulting image's size with resize((width, height)):

Showing the framebuffer



You can now access information about the OS running in the trace from server.ossi.os(). For instance:

>>> print(server.ossi.os()) Windows x64 10.0.17763 (Windows 10)


Workflow API

Finally, there have been improvements on the side of managing scenarios and archives:

  • You can now open a scenario by uuid or by name, using ProjectManager.get_server_by and specifying either name or uuid argument.
  • You can now upload a scenario archive from the API with ProjectManager.upload_scenario



esReven covers the Enterprise license only. While the REVEN Professional & REVEN Free Editions stills exist for the moment, they are likely to be deprecated in the coming months. Other options may replace them in the future.


And what now?

And that's it for this release! You can find the full list of improvements and fixes in the version's release notes.

Want to try the product?

  • We provide an extensive set of online demos, which constitute a good first step with tutorials available in most. However, they are based on the previous REVEN version for the time being.
  • Want to try the new esReven? Contact us!


All articles
Chip Security
Mobile App Security
Vulnerability Analysis

you might also be interested in

Chip Security

MCUBoot Under (good) Pressure | Part 1: Walk Around the Code

10 min read
Edit by Guillaume Vinet • Mar 3, 2023
CopyRights eShard 2023.
All rights reserved
Privacy policy | Legal Notice
Side Channel AnalysisLaser & EM Fault InjectionFirmware Security AnalysisSecurity Failure AnalysisVulnerability ResearchMAST: Mobile Application Security Testing