Redress v1.0.0 Released
It’s been over two years since the first public release of redress and a lot has changed since then. Redress has finally reached version 1.0. This release includes many surface and under the hood changes. One of the obvious changes is the user interface which has been rewritten to make it easier to use.
The Go Reverse Engineering Tool Kit (GoRE) has had a lot of improvements during the last few months and redress is taking advantage of these improvements. Some of these improvements are:
- Improved compiler version detection.
- A rewritten type parser.
- Improved package type classification (part of the main module vs a 3rd party module).
- Support for position-independent executables (PIE).
- Improved source code line number estimation and performance improvements.
- Extraction of GoRoot.
Some of the major changes in redress are described in more detail below. If you instead just want to download the latest release and get started on analyzing Go binaries, you can download it from the Github release page.
New CLI Interface
The biggest change introduced in version 1.0.0 is the new command-line interface (CLI). The new CLI uses github.com/spf13/cobra
which is a very powerful CLI library. Instead of using flags to invoke different actions, redress now uses subcommands. A list of available commands is shown by running redress help
.
______ _
| ___ \ | |
| |_/ /___ __| |_ __ ___ ___ ___
| // _ \/ _ | '__/ _ / __/ __|
| |\ | __| (_| | | | __\__ \__ \
\_| \_\___|\__,_|_| \___|___|___/
Usage:
redress [command]
Available Commands:
completion generate the autocompletion script for the specified shell
help Help about any command
info Print summary information.
packages List packages.
r2 Use redress with in r2.
source Source Code Projection.
types List types.
version Display redress version information.
Flags:
-h, --help help for redress
Use "redress [command] --help" for more information about a command.
The new version command has been updated to also include the version of GoRE used and which Go compiler compiled redress.
% redress version
______ _
| ___ \ | |
| |_/ /___ __| |_ __ ___ ___ ___
| // _ \/ _ | '__/ _ / __/ __|
| |\ | __| (_| | | | __\__ \__ \
\_| \_\___|\__,_|_| \___|___|___/
Version: v1.0.0
GoRE: v0.10.0
Go: go1.16.9
Cobra has built-in support to generate autocompletion scripts for different shells. Redress is taking advantage of this feature to allow users to improve their workflow. The redress completion
command has documentation for generating the scripts for bash, fish, PowerShell and, zsh shells.
% redress completion
Generate the autocompletion script for redress for the specified shell.
See each sub-command's help for details on how to use the generated script.
Usage:
redress completion [command]
Available Commands:
bash generate the autocompletion script for bash
fish generate the autocompletion script for fish
powershell generate the autocompletion script for powershell
zsh generate the autocompletion script for zsh
Flags:
-h, --help help for completion
Use "redress completion [command] --help" for more information about a command.
New Info Command
A new info
command has been added to provide a summary of the Go binary. In addition to OS, architecture, and compiler version used, it will also list the number of packages found in the main module, standard library, and 3rd party (vendor) modules.
% redress info ./redress
OS macOS
Arch amd64
Compiler 1.16.9 (2021-10-07)
Build ID zgmd-lmQA6Ipziftv7si/mBDAfSgMYd1EfQtEsCeH/z4f6fjE_ip0456wW0XaI/ySyk1vcbXU33XMpfZJx3
GoRoot go
Main root github.com/goretk/redress
# main 1
# std 63
# vendor 8
Package and Type Information
The package
flag has been moved to a subcommand.
% redress pkg ./redress -v
Packages:
Name Version
---- -------
main
Vendors:
Name Version
---- -------
github.com/TcM1911/r2g2 v0.3.2
github.com/cheynewallace/tabby v1.1.1
github.com/goretk/gore v0.10.0
github.com/goretk/gore/extern v0.10.0
github.com/spf13/cobra v1.2.1
github.com/spf13/pflag v1.0.5
golang.org/x/arch/x86/x86asm v0.0.0-20210923205945-b76863e36670
golang.org/x/mod/semver v0.5.1
Same with the type
flag.
% redress types -h
List Types
Redress can display different type data found in the binary. Interfaces can be
extracted with the "interface" argument while structures can be extracted with
the "struct" argument.
By default, standard library types are filtered out. These can be included
by also providing the standard library flag.
Method definitions for types can be included by using the method flag.
It is also possible to print all types in the binary by using the "all"
argument.
Redress tries to detect the version of the compiler that produced the binary.
If this process fails, a fallback version can be provided.
Usage:
redress types {struct|interface|all} path/to/go/file [flags]
Aliases:
types, type, typ, t
Flags:
-h, --help help for types
-m, --methods Include method definitions.
-s, --std Include standard library packages.
-v, --vendor Include 3rd party/vendor packages.
--version string Fallback compiler version. (default "go1.16")
Source Code Projection
The source projection functionality has been moved under the source
command. As part of this move, a new flag (include
) was added. With this flag, a user can tell redress to include the given packages in addition to the main module packages in the output. This is a good flag to use when redress has a hard time identifying if a package is part of a vendor module or the main module. In this scenario, it will usually get classified as an unknown
package.
% redress src -h
Source Code Projection
Construct a source code tree layout based on the metadata found in the binary.
The output includes the package name and its folder location at compile time.
For each file, the functions defined within are printed. The output also
includes auto generated functions produced by the compiler. For each function,
redress tries to guess the starting and ending line number.
Folder -> File -> Function -> Line
By default, standard library and 3rd party packages are excluded but can be
included by providing the flags "std", "vendor", and/or "unknown". It is also
possible to include individual packages with the "include" flag.
Usage:
redress source path/to/go/file [flags]
Aliases:
source, src, s
Flags:
-h, --help help for source
-i, --include strings Include the following packages. Can be provided as a comma-separated list or via providing the flag multiple times.
-s, --std Include standard library packages.
-u, --unknown Include unidentified packages.
-v, --vendor Include 3rd party/vendor packages.
Radare2 Integration
The radare2 integration has also been improved. Before this release, redress had different behavior if it was running from within radare2 or standalone. This has now changed and all the subcommands are available all the time. If an r2
command is executed when not from within radare2, redress will print out a warning that the command needs to be executed from within a radare2 instance.
% redress r2 -h
Use redress with in r2.
Usage:
redress r2 [command]
Aliases:
r2, radare, radare2, r
Available Commands:
init Perform the initial analysis
line Annotate function with source lines.
strarr Print string array.
type Print type definition.
Flags:
-h, --help help for r2
Use "redress r2 [command] --help" for more information about a command.
To use redress from within radare2, execute it via the #!pipe
command. A recommendation is to run #!pipe redress r2 init
when first opening a Go file. This command will mark and name all the functions, add types as symbols and analyze the main.main
and all init functions recursively. With Go binaries having a lot of functions, redress tries to only analyze the most important functions to speed up the process.
[0x01069740]> #!pipe redress r2 init
Compiler version: go1.16.9 (2021-10-07T19:49:45Z)
73 packages found.
5198 function symbols found
Analyzing all init functions.
Analyzing all main.main.
2886 type symbols found
Source Line Annotation
One of the powerful annotations that redress can add is the source line information. This command will annotate which source code file and line number the instructions were generated from. It will only show when either the file or line number is changed to reduce the number of annotations. Here is an example below of redress’s main function.
#!pipe redress r2 line
:> pdf
;-- fcn.main.main:
; CODE XREF from sym._main.main @ 0x12553d4
┌ 185: sym._main.main ();
│ ; var int64_t var_8h @ rsp+0x8
│ ; var int64_t var_10h @ rsp+0x10
│ ; var int64_t var_18h @ rsp+0x18
│ ; var int64_t var_20h @ rsp+0x20
│ ; var int64_t var_40h @ rsp+0x40
│ ; var int64_t var_48h @ rsp+0x48
│ ; var int64_t var_50h @ rsp+0x50
│ ┌─> 0x01255320 65488b0c2530. mov rcx, qword gs:[0x30]
│ ╎ 0x01255329 483b6110 cmp rsp, qword [rcx + 0x10]
│ ┌──< 0x0125532d 0f869c000000 jbe github.com_goretk_redress_main.go:24
│ │╎ 0x01255333 4883ec58 sub rsp, 0x58
│ │╎ 0x01255337 48896c2450 mov qword [var_50h], rbp
│ │╎ 0x0125533c 488d6c2450 lea rbp, [var_50h]
│ │╎ 0x01255341 488b0580c623. mov rax, qword [sym._main.rootCmd] ; [0x14919c8:8]=0x1498ac0
│ │╎ ;-- github.com_spf13_cobra_v1.2.1_command.go:902:
│ │╎ 0x01255348 48890424 mov qword [rsp], rax
│ │╎ 0x0125534c e82fadf0ff call sym._github.com_spf13_cobra._Command_.ExecuteC
│ │╎ 0x01255351 488b442410 mov rax, qword [var_10h]
│ │╎ 0x01255356 488b4c2418 mov rcx, qword [var_18h]
│ │╎ ;-- github.com_goretk_redress_main.go:25:
│ │╎ 0x0125535b 48837c241000 cmp qword [var_10h], 0
│ ┌───< 0x01255361 7462 je 0x12553c5
│ ││╎ ;-- github.com_goretk_redress_main.go:26:
│ ││╎ 0x01255363 0f57c0 xorps xmm0, xmm0
│ ││╎ 0x01255366 0f11442440 movups xmmword [var_40h], xmm0
│ ││╎ 0x0125536b 4885c0 test rax, rax
│ ┌────< 0x0125536e 7404 je 0x1255374
│ │││╎ 0x01255370 488b4008 mov rax, qword [rax + 8]
│ └────> 0x01255374 4889442440 mov qword [var_40h], rax
│ ││╎ 0x01255379 48894c2448 mov qword [var_48h], rcx
│ ││╎ 0x0125537e 488b051b8f24. mov rax, qword [sym._os.Stderr] ; [0x149e2a0:8]=0
│ ││╎ 0x01255385 488d0d2c790e. lea rcx, sym._go.itab.os.File_io.Writer ; 0x133ccb8 ; " \x99)\x01"
│ ││╎ 0x0125538c 48890c24 mov qword [rsp], rcx
│ ││╎ 0x01255390 4889442408 mov qword [var_8h], rax
│ ││╎ 0x01255395 488d442440 lea rax, [var_40h]
│ ││╎ 0x0125539a 4889442410 mov qword [var_10h], rax
│ ││╎ 0x0125539f 48c744241801. mov qword [var_18h], 1
│ ││╎ 0x012553a8 48c744242001. mov qword [var_20h], 1
│ ││╎ 0x012553b1 e88abce7ff call sym._fmt.Fprintln
│ ││╎ ;-- github.com_goretk_redress_main.go:27:
│ ││╎ 0x012553b6 48c704240100. mov qword [rsp], 1
│ ││╎ 0x012553be 6690 nop
│ ││╎ 0x012553c0 e8db6de7ff call sym._os.Exit
│ └───> 0x012553c5 488b6c2450 mov rbp, qword [var_50h]
│ │╎ 0x012553ca 4883c458 add rsp, 0x58
│ │╎ 0x012553ce c3 ret
│ │╎ ;-- github.com_goretk_redress_main.go:24:
│ └──> 0x012553cf e8cc11e1ff call sym._runtime.morestack_noctxt
└ └─< 0x012553d4 e947ffffff jmp sym._main.main
Other Changes
Redress 1.0.0
uses GoRE version 0.10.0
which also has had a lot of changes since it was initially released. The type parsing has been completely rewritten to improve performance and accuracy. The detection of which compiler version has been used has also been improved.
Redress has new functionality for new experimental commands. These are under the experimental
subcommand, which is not shown in the help printout. These commands are not covered by the 1.0
guarantee and can change between versions.
% redress experiment
Experimental functionality
The following commands are experimental and may change or removed
in the future.
Usage:
redress experiment [command]
Aliases:
experiment, exp, x
Available Commands:
mod Display go mod info.
Flags:
-h, --help help for experiment
Use "redress experiment [command] --help" for more information about a command.
One experimental function that is included in this release is the functionality to list the go.mod
information, it is available in the binary. The following code snippet shows an example of what the output can look like.
% redress x mod redress
Type Name Version Replaced by Hash
---- ---- ------- ----------- ----
main github.com/goretk/redress (devel)
dep github.com/TcM1911/r2g2 v0.3.2 h1:v+MaRN0sAGZsVP3+CC8WlL1psWZfAQwL5oTzSeF0K0s=
dep github.com/cheynewallace/tabby v1.1.1 h1:JvUR8waht4Y0S3JF17G6Vhyt+FRhnqVCkk8l4YrOU54=
dep github.com/goretk/gore v0.10.0 h1:ewk402Z0cBTSe+DB5ooBa8CsEAnEWE+E8cbJS7heqyM=
dep github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
dep github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
dep golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
dep golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
Where to Get
Get released binaries for Linux, macOS, and Windows on the Github Release page.