rev.ng logo
features

Not just a new UI.

Automatic data structure detection

Detect data structure automatically exploiting interprocedural information. We can detect: linked lists, structs, arrays, arrays of structs and so on.

Original code
1struct node {
2  int64_t data[5];
3  struct node *next;
4};
5
6int64_t compute(struct node *n) {
7  int64_t result = 0;
8  while (n) {
9    result += sum(n);
10    n = n->next;
11  }
12  return result;
13}
14
Code decompiled by rev.ng
1typedef struct _PACKED {
2  generic64_t _offset_0[5];
3  _struct_1876 *_offset_40;
4} _struct_1876;
5
6_ABI(SystemV_x86_64)
7generic64_t compute(_struct_1876 *_argument0) {
8  _struct_1876 *_var_0 = _argument0;
9  generic64_t _var_1 = 0, _var_2 = 0;
10  do {
11    _var_2 = sum(_var_0);
12    _var_1 = _var_1 + _var_2;
13    _var_0 = _var_0->_offset_40;
14  } while (_var_0);
15  return _var_1;
16}
17

Based on battle-proven open source technologies

LLVM enables us to perform aggressive analyses and optimizations in scalable way.

QEMU enables us to easily add support the more than 20 architectures it can emulate.

1Functions:
2  - Entry: "0x401020:Code_x86_64"
3    CustomName: "main"
4    OriginalName: main
5    Prototype: "/Types/1814-CABIFunctionType"
6    ExportedNames:
7      - main
8Types:
9  - ID: 1814
10    Kind: CABIFunctionType
11    ABI: SystemV_x86_64
12    ReturnType:
13      UnqualifiedType: "/Types/1540-PrimitiveType"
14    Arguments:
15      - Index: 0
16        Type:
17          UnqualifiedType: "/Types/1540-PrimitiveType"
18        CustomName: "argc"
19        OriginalName: argc
20      - Index: 1
21        Type:
22          UnqualifiedType: "/Types/1537-PrimitiveType"
23          Qualifiers:
24            - Kind: Pointer
25              Size: 8
26            - Kind: Pointer
27              Size: 8
28        CustomName: "argv"
29        OriginalName: argv
30ImportedLibraries:
31  - libc.so.6
32

Easily import .idb and debug info

Also, writing your own importer is as easy as editing a YAML document.

No goto’s

Typically rev.ng duplicates a bit of code in order to avoid emitting hard-to-read gotos.

Others
1__int64 __fastcall f(unsigned __int64 a1,
2                     unsigned __int64 a2) {
3  _QWORD *v2; // rax
4  void *v3; // rbp
5  __int64 v4; // rax
6
7  v2 = calloc(0xAuLL, 8uLL);
8  v3 = v2;
9  if ( !v2 ) {
10    perror("Cannot allocate buffer");
11    goto LABEL_5;
12  }
13  if ( a1 > 0xA ) {
14    perror("Boundaries exceeds lower limit");
15    free(v3);
16    return 0LL;
17  } else {
18    if ( a2 <= 0x14 ) {
19      use(v2);
20      if ( v4 )  {
21LABEL_6:
22        free(v3);
23        return 0LL;
24      }
25LABEL_5:
26      report(a1 + a2);
27      goto LABEL_6;
28    }
29    perror("Boundaries exceeds upper limit");
30    free(v3);
31    return 0LL;
32  }
33}
34
rev.ng
1generic64_t f(generic64_t _argument0,
2              generic64_t _argument1) {
3  generic64_t _var_0;
4  void *_var_1;
5  _var_1 = calloc_((size_t) 10, (size_t) 8);
6  if (!_var_1) {
7    perror_("Cannot allocate buffer");
8    report(_argument1 + _argument0);
9  } else {
10    if (_argument0 > 10) {
11      perror_("Boundaries exceeds lower limit");
12      free_(_var_1);
13      return 0;
14    }
15    if (_argument1 > 20) {
16      perror_("Boundaries exceeds upper limit");
17      free_(_var_1);
18      return 0;
19    }
20    _var_0 = use((generic64_t *) _var_1);
21    if (!_var_0) {
22      report(_argument1 + _argument0);
23    }
24  }
25  free_(_var_1);
26  return 0;
27}
28

Wide architectures support

x86, x86-64, ARM, AArch64, MIPS, S390X, all included by default, and more to come.

Easily interact through HTTP API

Effortless automation thanks to our client-server architecture.

Emit valid C

The rev.ng decompiler only emits syntactically valid, standard-compliant C code.

Others
1typedef long long __int64;
2
3signed __int64 __usercall call@<rax>(__int64 a1@<rax>)
4{
5  __int64 result; // rax
6
7  result = a1 + 1;
8    if ( result )
9      result = call();
10  return result;
11}
12

$ gcc others.c -c
others.c:3:16: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__usercall’
    3 | signed __int64 __usercall call@<rax>(__int64 a1@<rax>)
    |                  ^~~~~~~~~~
others.c:3:16: error: unknown type name ‘__usercall’
others.c:3:31: error: stray ‘@’ in program
    3 | signed __int64 __usercall call@<rax>(__int64 a1@<rax>)
    |                                 ^
others.c:3:48: error: stray ‘@’ in program
    3 | signed __int64 __usercall call@<rax>(__int64 a1@<rax>)
    |                                                  ^
rev.ng
1#include <stdint.h>
2
3int64_t call(int64_t a1)
4{
5  int64_t result = a1 + 1;
6  if (result)
7    result = call(result);
8  return result;
9}
10

$ gcc revng.c -c
$
Hub illustration

Explore what others are doing and collaborate

Thanks to Hub, you can see what the rev.ng community is working on and easily collaborate on the same project. Think GitHub, for reverse engineering.

Go to Hub

Register to the UI closed beta!

Want to try the UI? We're now inviting people on a FIFO basis.