Git Product home page Git Product logo

rappel's Introduction

rappel

Build Status

Rappel is a pretty janky assembly REPL. It works by creating a shell ELF, starting it under ptrace, then continiously rewriting/running the .text section, while showing the register states. It's maybe half done right now, and supports Linux x86, amd64, armv7 (no thumb), and armv8 at the moment.

  • If you're looking for a Windows version, please see @zerosum0x0's WinREPL (archived)
  • If you're looking for a macOS version, please see @tyilol's asm_repl
  • If you're looking for a hacked together with gdb and Python version, please see amtal's rappel.py

Install

The only dependencies are libedit and an assembler (nasm on x86/amd64, as on ARM) , which on Debian can be installed with the libedit-dev and nasm/binutils packages. Please note, as rappel requires the ability to write to executable memory via ptrace, the program is broken under PAX_MPROTECT on grsec kernels (see #2).

$ CC=clang make

It should work fine with gcc, albeit with a few more warnings.

By default rappel is compiled with your native architecture. If you're on amd64 and want to target x86 you can do this with

$ ARCH=x86 CC=clang make

In theory you can also compile an armv7 binary this way, but I really doubt it will work. For rappel to function, the architecture of the main rappel binary must match that of the process it creates, and the host must be able to run binaries of this architecture.

Running

Rappel has two modes it can operate in. A pipe mode for one off things, a la

$ echo "inc eax" | bin/rappel
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400004 rsp=00007ffc73019c20 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
$

Or an interactive mode:

$ bin/rappel
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400001 rsp=00007ffdedb264a0 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
> inc rax
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400004 rsp=00007ffdedb264a0 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
> push rax
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400002 rsp=00007ffdedb26498 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
> pop rbx
rax=0000000000000001 rbx=0000000000000001 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400002 rsp=00007ffdedb264a0 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
> cmp rax, rbx
rax=0000000000000001 rbx=0000000000000001 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400004 rsp=00007ffdedb264a0 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:1, of:0, sf:0, pf:1, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000246
> ^D
$

x86 looks like:

$ echo "nop" | bin/rappel
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=00400002 esp=ffc67240 ebp=00000000 [cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0023  ss=002b  ds=002b  es=002b  fs=0000  gs=0000            efl=00000202
$

ARMv7 looks like:

$ echo "nop" | bin/rappel
R0 :0x00000000	R1 :0x00000000	R2 :0x00000000	R3 :0x00000000
R4 :0x00000000	R5 :0x00000000	R6 :0x00000000	R7 :0x00000000
R8 :0x00000000	R9 :0x00000000	R10:0x00000000
FP :0x00000000	IP :0x00000000
SP :0xbe927f30	LR :0x00000000	PC :0x00400004
APSR:0x00000010
$

ARMv8 looks like:

$ echo "nop" | bin/rappel
X0:  0x0000000000000000	X1:  0x0000000000000000	X2:  0x0000000000000000	X3:  0x0000000000000000
X4:  0x0000000000000000	X5:  0x0000000000000000	X6:  0x0000000000000000	X7:  0x0000000000000000
X8:  0x0000000000000000	X9:  0x0000000000000000	X10: 0x0000000000000000	X11: 0x0000000000000000
X12: 0x0000000000000000	X13: 0x0000000000000000	X14: 0x0000000000000000	X15: 0x0000000000000000
X16: 0x0000000000000000	X17: 0x0000000000000000	X18: 0x0000000000000000	X19: 0x0000000000000000
X20: 0x0000000000000000	X21: 0x0000000000000000	X22: 0x0000000000000000	X23: 0x0000000000000000
X24: 0x0000000000000000	X25: 0x0000000000000000	X26: 0x0000000000000000	X27: 0x0000000000000000
X28: 0x0000000000000000	X29: 0x0000000000000000	X30: 0x0000000000000000
PC:  0x0000000000400004	SP:  0x0000007fedb9be40	PS:  0x0000000000000000

Notes

Someone asked about xmm registers. If you pass -x it will dump out quite a bit of info.

GP Regs:
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400001 rsp=00007ffca03d9370 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf:0, zf:0, of:0, sf:0, pf:0, af:0, df:0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
FP Regs:
rip: 0000000000000000   rdp: 0000000000000000   mxcsr: 00001f80 mxcsr_mask:0000ffff
cwd: 037f       swd: 0000       ftw: 0000       fop: 0000
st_space:
0x00:   00000000        00000000        00000000        00000000
0x10:   00000000        00000000        00000000        00000000
0x20:   00000000        00000000        00000000        00000000
0x30:   00000000        00000000        00000000        00000000
0x40:   00000000        00000000        00000000        00000000
0x50:   00000000        00000000        00000000        00000000
0x60:   00000000        00000000        00000000        00000000
0x70:   00000000        00000000        00000000        00000000
xmm_space:
0x00:   00000000        00000000        00000000        00000000
0x10:   00000000        00000000        00000000        00000000
0x20:   00000000        00000000        00000000        00000000
0x30:   00000000        00000000        00000000        00000000
0x40:   00000000        00000000        00000000        00000000
0x50:   00000000        00000000        00000000        00000000
0x60:   00000000        00000000        00000000        00000000
0x70:   00000000        00000000        00000000        00000000
0x80:   00000000        00000000        00000000        00000000
0x90:   00000000        00000000        00000000        00000000
0xa0:   00000000        00000000        00000000        00000000
0xb0:   00000000        00000000        00000000        00000000
0xc0:   00000000        00000000        00000000        00000000
0xd0:   00000000        00000000        00000000        00000000
0xe0:   00000000        00000000        00000000        00000000
0xf0:   00000000        00000000        00000000        00000000

There are some other regsets the kernel exports via ptrace(), but they're dependent on kernel version, and I didn't want to try to detect and adjust at runtime. If you want them, you should just need to add the storage in proc_info_t, edit ptrace_collect_regs_<arch>(), then add the display in the relevant display function.

Right now supported platforms are determined by what hardware I own. Adding a new architecture shouldn't be too difficult, as most of the code can be adapted from existing archs.

Docs

You can get pretty much all the documentation with either -h from the command line, or .help from the interactive bit.

rappel's People

Contributors

disconnect3d avatar jonringer avatar leongross avatar nanxiao avatar pmeerw avatar unavaliabl3 avatar yrp604 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rappel's Issues

.write does not seem to work

Say I'm in an interactive session and run .showmap which returns the following

f7fd8000-f7fdb000 r--p 00000000 00:00 0                                  [vvar]
f7fdb000-f7fdc000 r-xp 00000000 00:00 0                                  [vdso]
ff8aa000-ff8cd000 rwxp 00000000 00:00 0                                  [stack]

Why doesn't .write 0xff8aa000 0x7f and then reading it .read 0xff8ea000 0x1 show 7f?

If I instead do
mov dword [0xff8aa000], 0x7f and follow up with .read 0xff8ea000 0x1 it does show that 7f has been written.

P.S. What does [vvar] and [vdso] mean?

ESP not changing on PUSH/POP

Hi I was trying the same exact example as the README.md and my esp just stays at 0x30 for any PUSH and POP operations

rsp is always 33

on ubuntu(Linux ubuntu 5.15.0-91-generic ) amd64, after 'push rax', the rsp is always 33:

> inc rax
rax=0000000000000002 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400004 rsp=0000000000000033 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf=0, zf=0, of=0, sf=0, pf=0, af=0, df=0]
cs=002b  ss=0000  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202
> push rax
rax=0000000000000002 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400002 rsp=0000000000000033 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf=0, zf=0, of=0, sf=0, pf=0, af=0, df=0]
cs=002b  ss=0000  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202

Add history

Hey,

Can we have a history feature in the REPL? So when I relaunch ./rappel I can use arrow up to get previous input.

make error using libedit-dev 3.1-20130712-2

Thanks for this, I love REPLs!

I encountered a 'make' error when using an old version of libedit-dev (3.1-20130712) on my Ubuntu Trusty box.

I am new to C, my newb question is: how are library version requirements specified?.

Details:
the commit requiring a newer version is c8aeae9 ; it uses an identifier (H_SAVE_FP) that is not present in libedit-dev 3.1-20130712-2 (latest on Ubuntu Trusty).

make fails on trusty (libedit-dev 3.1-20130712-2): https://travis-ci.org/emig/rappel/builds/544237957#L481-L488
make builds on xenial (3.1-20150325-1ubuntu2): https://travis-ci.org/emig/rappel/builds/544237957#L481-L488

I wasn't able to find the precise version of libedit-dev that starts working with the code. The closer I got is the change on the libedit history.c file that brings the new identifier http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/history.c.diff?r1=1.46&r2=1.47&sortby=date&f=h
since the header file wasn't on this repository, I assume it is generated from it.

Cannot find -ledit

I've installed libedit-dev on debian buster and tried following the steps of running CC=clang make and get the following error:

/usr/bin/ld: skipping incompatible //usr/lib/x86_64-linux-gnu/libedit.so when searching for -ledit
/usr/bin/ld: skipping incompatible //usr/lib/x86_64-linux-gnu/libedit.a when searching for -ledit
/usr/bin/ld: cannot find -ledit

what could be causing this?

ATT-style for x86_64?

Thanks for the great work! The tool works just as I've imagined of an ASM REPL. I'm learning x86_64 assembly, but started with ATT style and can hardly read Intel ones, let alone writing them. Is there a way to switch to ATT syntax?

Pid 8 got signal 11, not delivering on numerous opcodes

I've been using this for an implementation of a vm I've been working on to debug and get proper test results but I'm starting to come into problems particularly with the string operations movs and cmps as well as anything that loops or uses subroutines. Is there a particular way I should be using this to unlock these capabilities or am I screwed?

Fail to execute

When I try to execute any instruction (for example, inc rax), I get the following output before the list of registers (which do not change).

ptrace() - failed to write value 0xccccccccccc0ff48 to 0x0000000000400000

When executing with -v, I get the following:

Trying to assemble(8):
inc rax
@nasm is pid 6057
Process 6057 has exited with status 0
Got asm(3):
48 ff c0                                                H..
ptrace_write: 0x0000000000400000 = 0xccccccccccc0ff48
ptrace() - failed to write value 0xccccccccccc0ff48 to 0x0000000000400000

I am wondering if this is because of Grsec's PaX, but if it is, there was nothing registered in dmesg as there usually is. Any idea what might be going wrong?

Invalid instruction is executed

After:

> mov qword [rsp-0x1234], 0x1122334455667788
> mov qword rbx, [rsp-0x1234]

The result in rbx is:

rbx: 0x0000000055667788

The fact is that the first instruction is not really valid as the operand size is too big. Actually it prints out a warning about it, but it is super easy to miss it:

> mov qword [rsp-0x1234], 0x1122334455667788
/dev/fd/3:3: warning: signed dword immediate exceeds bounds [-w+number-overflow]
/dev/fd/3:3: warning: dword data exceeds bounds [-w+number-overflow]

Can we make this warning an error and not continue on that?

execlp: No such file or directory

Ran sudo apt-get install libedit-dev followed by make.

Then I ran bin/rappel on a Linux based x86 system.

Received the following error:

> nop
Trying to assemble(4):
nop
nasm is pid 5678
execlp: No such file or directory
nasm exited 1.
Got asm(0):
'' assembled to 0 length bytecode
> 

make error

โžœ rappel git:(master) make ARCH=x86

/usr/bin/ld: cannot find -ledit
collect2: error: ld returned 1 exit status
Makefile:52: recipe for target 'bin/rappel' failed
make: *** [bin/rappel] Error 1

OS: Linux 4.4.0-75-generic #96-Ubuntu SMP Thu Apr 20 09:56:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
cc: gcc

License terms

I'd like to contribute but I would like a clear indication for the license under which a contribution would be accepted. I didn't see a COPYING or LICENSE in the repo.

As a teaser: I have a working but currently memory-leaky port of assemble_intel to use the LLVM MC assembler instead of shelling out to nasm. It definitely still needs some clean-up, and it'd probably be nice if I figure out how to support both with user choice.

Enable and disable display of XMM registers on demand

Someone asked about xmm registers. If you pass -x it will dump out quite a bit of info.

This is pretty cool. However, since the display is huge, it would be nice to be able to invoke a special command, that would switch the display of XMM registers.

This might be useful for making screenshots of rappel ๐Ÿคท

Only show changed registers

I think it would be better by default if only registers which had changed value were displayed, and this may be none.โ€‚ That would save me having to hunt for the ones I expect to change, and also highlight if unexpected ones had altered.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.