The Official Radare2 Book — страница 45 из 64

sub.setlocale_fa0 64 0x3fa0 | UNMATCH (0.104651) | 0x3fb0 64 sub.setlocale_fb0

fcn.00003a50 120 0x3a50 | UNMATCH (0.125000) | 0x3a60 120 fcn.00003a60

And now a cool feature : radare2 supports graph-diffing, à la DarunGrim, with the -g option. You can either give it a symbol name, of specify two offsets, if the function you want to diff is named differently in compared files. For example, radiff2 -md -g main /bin/true /bin/false | xdot - will show differences in main() function of Unix true and false programs. You can compare it to radiff2 -md -g main /bin/false /bin/true | xdot - (Notice the order of the arguments) to get the two versions. This is the result:

Parts in yellow indicate that some offsets do not match. The grey piece means a perfect match. The orange one highlights a strong difference. If you look closely, you will see that the left part of the picture has mov eax, 0x1; pop rbx; pop rbp; ret, while the right one has xor edx, edx; pop rbx; pop rbp; ret.

Binary diffing is an important feature for reverse engineering. It can be used to analyze security updates, infected binaries, firmware changes and more...

We have only shown the code analysis diffing functionality, but radare2 supports additional types of diffing between two binaries: at byte level, deltified similarities, and more to come.

We have plans to implement more kinds of bindiffing algorithms into r2, and why not, add support for ASCII art graph diffing and better integration with the rest of the toolkit.

Rasm2

rasm2 is an inline assembler/disassembler. Initially, rasm tool was designed to be used for binary patching. Its main function is to get bytes corresponding to given machine instruction opcode.

$ rasm2 -h

Usage: rasm2 [-ACdDehLBvw] [-a arch] [-b bits] [-o addr] [-s syntax]

[-f file] [-F fil:ter] [-i skip] [-l len] 'code'|hex|-

-a [arch] Set architecture to assemble/disassemble (see -L)

-A Show Analysis information from given hexpairs

-b [bits] Set cpu register size (8, 16, 32, 64) (RASM2_BITS)

-B Binary input/output (-l is mandatory for binary input)

-c [cpu] Select specific CPU (depends on arch)

-C Output in C format

-d, -D Disassemble from hexpair bytes (-D show hexpairs)

-e Use big endian instead of little endian

-E Display ESIL expression (same input as in -d)

-f [file] Read data from file

-F [in:out] Specify input and/or output filters (att2intel, x86.pseudo, ...)

-h, -hh Show this help, -hh for long

-i [len] ignore/skip N bytes of the input buffer

-j output in json format

-k [kernel] Select operating system (linux, windows, darwin, ..)

-l [len] Input/Output length

-L List Asm plugins: (a=asm, d=disasm, A=analyze, e=ESIL)

-o [offset] Set start address for code (default 0)

-O [file] Output file name (rasm2 -Bf a.asm -O a)

-p Run SPP over input for assembly

-q quiet mode

-r output in radare commands

-s [syntax] Select syntax (intel, att)

-v Show version information

-w What's this instruction for? describe opcode

If '-l' value is greater than output length, output is padded with nops

If the last argument is '-' reads from stdin

Environment:

RASM2_NOPLUGINS do not load shared plugins (speedup loading)

RASM2_ARCH same as rasm2 -a

RASM2_BITS same as rasm2 -b

R_DEBUG if defined, show error messages and crash signal


Plugins for supported target architectures can be listed with the -L option. Knowing a plugin name, you can use it by specifying its name to the -a option

$ rasm2 -L

_dAe 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU

_dAe 8 8051 PD 8051 Intel CPU

_dA_ 16 32 arc GPL3 Argonaut RISC Core

a___ 16 32 64 arm.as LGPL3 as ARM Assembler (use ARM_AS environment)

adAe 16 32 64 arm BSD Capstone ARM disassembler

_dA_ 16 32 64 arm.gnu GPL3 Acorn RISC Machine CPU

_d__ 16 32 arm.winedbg LGPL2 WineDBG's ARM disassembler

adAe 8 16 avr GPL AVR Atmel

adAe 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0

_dA_ 32 chip8 LGPL3 Chip8 disassembler

_dA_ 16 cr16 LGPL3 cr16 disassembly plugin

_dA_ 32 cris GPL3 Axis Communications 32-bit embedded processor

adA_ 32 64 dalvik LGPL3 AndroidVM Dalvik

ad__ 16 dcpu16 PD Mojang's DCPU-16

_dA_ 32 64 ebc LGPL3 EFI Bytecode

adAe 16 gb LGPL3 GameBoy(TM) (z80-like)

_dAe 16 h8300 LGPL3 H8/300 disassembly plugin

_dAe 32 hexagon LGPL3 Qualcomm Hexagon (QDSP6) V6

_d__ 32 hppa GPL3 HP PA-RISC

_dAe i4004 LGPL3 Intel 4004 microprocessor

_dA_ 8 i8080 BSD Intel 8080 CPU

adA_ 32 java Apache Java bytecode

_d__ 32 lanai GPL3 LANAI

_d__ 8 lh5801 LGPL3 SHARP LH5801 disassembler

_d__ 32 lm32 BSD disassembly plugin for Lattice Micro 32 ISA

_dA_ 16 32 m68k BSD Capstone M68K disassembler

_dA_ 32 malbolge LGPL3 Malbolge Ternary VM

_d__ 16 mcs96 LGPL3 condrets car

adAe 16 32 64 mips BSD Capstone MIPS disassembler

adAe 32 64 mips.gnu GPL3 MIPS CPU

_dA_ 16 msp430 LGPL3 msp430 disassembly plugin

_dA_ 32 nios2 GPL3 NIOS II Embedded Processor

_dAe 8 pic LGPL3 PIC disassembler

_dAe 32 64 ppc BSD Capstone PowerPC disassembler

_dA_ 32 64 ppc.gnu GPL3 PowerPC

_d__ 32 propeller LGPL3 propeller disassembly plugin

_dA_ 32 64 riscv GPL RISC-V

_dAe 32 rsp LGPL3 Reality Signal Processor

_dAe 32 sh GPL3 SuperH-4 CPU

_dA_ 8 16 snes LGPL3 SuperNES CPU

_dAe 32 64 sparc BSD Capstone SPARC disassembler

_dA_ 32 64 sparc.gnu GPL3 Scalable Processor Architecture

_d__ 16 spc700 LGPL3 spc700, snes' sound-chip

_d__ 32 sysz BSD SystemZ CPU disassembler

_dA_ 32 tms320 LGPLv3 TMS320 DSP family (c54x,c55x,c55x+,c64x)

_d__ 32 tricore GPL3 Siemens TriCore CPU

_dAe 32 v810 LGPL3 v810 disassembly plugin

_dAe 32 v850 LGPL3 v850 disassembly plugin

_dAe 8 32 vax GPL VAX

adA_ 32 wasm MIT WebAssembly (by cgvwzq) v0.1.0

_dA_ 32 ws LGPL3 Whitespace esotheric VM

a___ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler

_dAe 16 32 64 x86 BSD Capstone X86 disassembler

a___ 16 32 64 x86.nasm LGPL3 X86 nasm assembler

a___ 16 32 64 x86.nz LGPL3 x86 handmade assembler

_dA_ 16 xap PD XAP4 RISC (CSR)

_dA_ 32 xcore BSD Capstone XCore disassembler

_dAe 32 xtensa GPL3 XTensa CPU

adA_ 8 z80 GPL Zilog Z80

Note that "ad" in the first column means both assembler and disassembler are offered by a corresponding plugin. "d" indicates disassembler, "a" means only assembler is available.

Assembler

Assembling is the action to take a computer instruction in human readable form (using mnemonics) and convert that into a bunch of bytes that can be executed by a machine.

In radare2, the assembler and disassembler logic is implemented in the r_asm_* API, and can be used with the pa and pad commands from the commandline as well as using rasm2.

Rasm2 can be used to quickly copy-paste hexpairs that represent a given machine instruction. The following line is assembling this mov instruction for x86/32.

$ rasm2 -a x86 -b 32 'mov eax, 33'

b821000000

Apart from the specifying the input as an argument, you can also pipe it to rasm2:

$ echo 'push eax;nop;nop' | rasm2 -f -

5090

As you have seen, rasm2 can assemble one or many instructions. In line by separating them with a semicolon ;, but can also read that from a file, using generic nasm/gas/.. syntax and directives. You can check the rasm2 manpage for more details on this.

The pa and pad are a subcommands of print, what means they will only print assembly or disassembly. In case you want to actually write the instruction it is required to use wa or wx commands with the assembly string or bytes appended.

The assembler understands the following input languages and their flavors: x86 (Intel and AT&T variants), olly (OllyDBG syntax), powerpc (PowerPC), arm and java. For Intel syntax, rasm2 tries to mimic NASM or GAS.

There are several examples in the rasm2 source code directory. Consult them to understand how you can assemble a raw binary file from a rasm2 description.

Lets create an assembly file called selfstop.rasm:

;

; Self-Stop shellcode written in rasm for x86

;

; --pancake

;


.arch x86

.equ base 0x8048000

.org 0x8048000  ; the offset where we inject the 5 byte jmp


selfstop:

push 0x8048000

pusha

mov eax, 20

int 0x80


mov ebx, eax

mov ecx, 19

mov eax, 37

int 0x80

popa

ret

;

; The call injection

;


ret

Now we can assemble it in place:

[0x00000000]> e asm.bits = 32

[0x00000000]> wx `!rasm2 -f a.rasm`

[0x00000000]> pd 20

0x00000000 6800800408 push 0x8048000 ; 0x08048000

0x00000005 60 pushad

0x00000006 b814000000 mov eax, 0x14 ; 0x00000014

0x0000000b cd80 int 0x80

syscall[0x80][0]=?

0x0000000d 89c3 mov ebx, eax

0x0000000f b913000000 mov ecx, 0x13 ; 0x00000013

0x00000014 b825000000 mov eax, 0x25 ; 0x00000025

0x00000019 cd80 int 0x80

syscall[0x80][0]=?

0x0000001b 61 popad

0x0000001c c3 ret

0x0000001d c3 ret

Visual mode

Assembling also is accessible in radare2 visual mode through pressing A key to insert the assembly in the current offset.

The cool thing of writing assembly using the visual assembler interface that the changes are done in memory until you press enter.

So you can check the size of the code and which instructions is overlapping before commiting the changes.

Disassembler