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
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.
Disassembling is the inverse action of assembling. Rasm2 takes hexpair as an input (but can also take a file in binary form) and show the human readable form.
To do this we can use the -d option of rasm2 like this:
$ rasm2 -a x86 -b 32 -d '90'
nop
Rasm2 also have the -D flag to show the disassembly like -d does, but includes offset and bytes.
In radare2 there are many commands to perform a disassembly from a specific place in memory.
You might be interested in trying if you want different outputs for later parsing with your scripts, or just grep to find what you are looking for:
Disassemble N instructions
Disassemble N bytes
Disassemble all instructions (seeking 1 byte, or the minimum alignment instruction size), which can be useful for ROP
Same as pd and pD, but using a simpler output.
The assembler and disassembler have many small switches to tweak the output.
Those configurations are available through the e command. Here there are the most common ones:
• asm.bytes - show/hide bytes
• asm.offset - show/hide offset
• asm.lines - show/hide lines
• asm.ucase - show disasm in uppercase
• ...
Use the e??asm. for more details.
ragg2 stands for radare2 egg, this is the basic block to construct relocatable snippets of code to be used for injection in target processes when doing exploiting.
ragg2 compiles programs written in a simple high-level language into tiny binaries for x86, x86-64, and ARM.
By default it will compile it's own ragg2 language, but you can also compile C code using GCC or Clang shellcodes depending on the file extension. Lets create C file called a.c:
int main() {
write(1, "Hello World\n", 13);
return 0;
}
$ ragg2 -a x86 -b32 a.c
e900000000488d3516000000bf01000000b80400000248c7c20d0000000f0531c0c348656c6c6f20576f726c640a00
$ rasm2 -a x86 -b 32 -D e900000000488d3516000000bf01000000b80400000248c7c20d0000000f0531c0c348656c6c6f20576f726c640a00
0x00000000 5 e900000000 jmp 5
0x00000005 1 48 dec eax
0x00000006 6 8d3516000000 lea esi, [0x16]
0x0000000c 5 bf01000000 mov edi, 1
0x00000011 5 b804000002 mov eax, 0x2000004
0x00000016 1 48 dec eax
0x00000017 6 c7c20d000000 mov edx, 0xd
0x0000001d 2 0f05 syscall
0x0000001f 2 31c0 xor eax, eax
0x00000021 1 c3 ret
0x00000022 1 48 dec eax
0x00000023 2 656c insb byte es:[edi], dx
0x00000025 1 6c insb byte es:[edi], dx
0x00000026 1 6f outsd dx, dword [esi]
0x00000027 3 20576f and byte [edi + 0x6f], dl
0x0000002a 2 726c jb 0x98
0x0000002c 3 640a00 or al, byte fs:[eax]
$ cat hello.r
exit@syscall(1);
main@global() {
exit(2);
}
$ ragg2 -a x86 -b 64 hello.r
48c7c00200000050488b3c2448c7c0010000000f054883c408c3
0x00000000 1 48 dec eax
0x00000001 6 c7c002000000 mov eax, 2
0x00000007 1 50 push eax
0x00000008 1 48 dec eax
0x00000009 3 8b3c24 mov edi, dword [esp]
0x0000000c 1 48 dec eax
0x0000000d 6 c7c001000000 mov eax, 1
0x00000013 2 0f05 syscall
0x00000015 1 48 dec eax
0x00000016 3 83c408 add esp, 8
0x00000019 1 c3 ret
$ rasm2 -a x86 -b 64 -D 48c7c00200000050488b3c2448c7c0010000000f054883c408c3
0x00000000 7 48c7c002000000 mov rax, 2
0x00000007 1 50 push rax
0x00000008 4 488b3c24 mov rdi, qword [rsp]