* Add doc.sw documentation (wip)
* Add missing parenthesis in p command's help * Some code enhacements for r_sys_cmd_str_full
This commit is contained in:
parent
9ae4ba7cc8
commit
329ea07ec1
|
@ -0,0 +1,4 @@
|
|||
# http://nibble.develsec.org/sw.cgi/projects/sw.md
|
||||
|
||||
all:
|
||||
sw.gen site
|
|
@ -0,0 +1,2 @@
|
|||
Analysis
|
||||
========
|
|
@ -0,0 +1,2 @@
|
|||
Commands
|
||||
========
|
|
@ -0,0 +1,2 @@
|
|||
Debugging
|
||||
=========
|
|
@ -0,0 +1,2 @@
|
|||
Disassembler
|
||||
============
|
|
@ -0,0 +1,2 @@
|
|||
Edition
|
||||
=======
|
|
@ -0,0 +1,71 @@
|
|||
Flags
|
||||
=====
|
||||
|
||||
Flags are used to specify bookmarks inside radare, they are store the following data:
|
||||
|
||||
* name
|
||||
* offset
|
||||
* size
|
||||
* flagspace
|
||||
|
||||
The command 'f' is responsible to manage the flag list.
|
||||
|
||||
> fs imports # select flagspace 'imports'
|
||||
> f # list flags
|
||||
> f * # list all flags in radare commands
|
||||
> fs * # select no flagspace
|
||||
> f target @ 10 # create/set flag 'target' at offset 10
|
||||
> f-target # remove flag named 'target'
|
||||
|
||||
Sorting flags
|
||||
-------------
|
||||
|
||||
r2 have a new command named 'fS' which is used to sort flags by name (fSn) or offset (fSo).
|
||||
|
||||
In 'Vt' you can sort the flags using 'o' and 'n' keys.
|
||||
|
||||
> f alice @ 0x20
|
||||
> f bob @ 0x10
|
||||
> fSn
|
||||
> f
|
||||
0x00000020 0 alice
|
||||
0x00000010 0 bob
|
||||
> fSo
|
||||
> f
|
||||
0x00000010 0 bob
|
||||
0x00000020 0 alice
|
||||
|
||||
|
||||
Visual mode
|
||||
-----------
|
||||
|
||||
Vt command from shell will emulate typing 't' in 'V'isual mode, so you get the same menu which allows you list, add and remove flags and flagspaces.
|
||||
|
||||
Press '?' to get help of keybindings.
|
||||
|
||||
> Vt
|
||||
|
||||
Flag spaces:
|
||||
|
||||
00 sections
|
||||
01 * symbols
|
||||
> 02 imports
|
||||
03 functions
|
||||
04 *
|
||||
|
||||
<enter>
|
||||
|
||||
Flags in flagspace 'imports'. Press '?' for help.
|
||||
|
||||
> 000 0x080496f4 0 imp.malloc
|
||||
001 0x080494b4 0 imp.free
|
||||
002 0x08049884 0 imp.cap_get_file
|
||||
003 0x08049874 0 imp.exit
|
||||
...
|
||||
|
||||
Selected: imp.malloc
|
||||
|
||||
|||| 0x080496f4 *[ fcn.imp.malloc] jmp dword near [0x805e82c]
|
||||
|||| 0x080496fa 6828020000 push dword 0x228
|
||||
|||`=< 0x080496ff e990fbffff jmp section..plt
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Description
|
||||
===========
|
||||
|
||||
This directory aims to provide helpful documentation tips for radare2.
|
||||
|
||||
--pancake
|
|
@ -0,0 +1,18 @@
|
|||
Compilation instructions
|
||||
========================
|
||||
|
||||
To get python bindings for radare2 you need to install the following dependencies:
|
||||
|
||||
* swig
|
||||
* svn co https://swig.svn.sourceforge.net/svnroot/swig/trunk
|
||||
* valaswig
|
||||
* hg clone http://hg.youterm.com/valaswig
|
||||
* radare2
|
||||
* hg clone http://radare.org/hg/radare2
|
||||
|
||||
Then, you have to compile r2-swig:
|
||||
|
||||
$ cd radare2/swig
|
||||
$ ./configure --prefix=/usr
|
||||
$ make
|
||||
$ sudo make install
|
|
@ -0,0 +1,33 @@
|
|||
r2 Hello World in python
|
||||
========================
|
||||
|
||||
This snippet will open /bin/ls and disassemble 10 instructions at entrypoint:
|
||||
|
||||
$ cat test.py
|
||||
from r2.libr import RCore
|
||||
c=RCore()
|
||||
c.file_open("/bin/ls", False)
|
||||
c.cmd0(".!rabin2 -re /bin/ls")
|
||||
print "Entrypoint: %s"%c.cmd_str("? entry0").split(" ")[1]
|
||||
print c.cmd_str("pd 10 @ entry0")
|
||||
|
||||
|
||||
To run it:
|
||||
|
||||
$ python test.py
|
||||
|
||||
Entrypoint: 0x18a0
|
||||
|
||||
| 0x000018a0 *[ entry0] xor ebp, ebp
|
||||
| 0x000018a2 5e pop esi
|
||||
| 0x000018a3 89e1 mov ecx, esp
|
||||
| 0x000018a5 83e4f0 and esp, 0xf0
|
||||
| 0x000018a8 50 push eax
|
||||
| 0x000018a9 54 push esp
|
||||
| 0x000018aa 52 push edx
|
||||
| 0x000018ab 68a0940508 push dword 0x80594a0
|
||||
| 0x000018b0 68b0940508 push dword 0x80594b0
|
||||
| 0x000018b5 51 push ecx
|
||||
| 0x000018b6 56 push esi
|
||||
| 0x000018b7 6840f80408 push dword 0x804f840
|
||||
`=< 0x000018bc e843fbffff call 0x1404
|
|
@ -0,0 +1,4 @@
|
|||
Python
|
||||
======
|
||||
|
||||
r2-swig provides automatic swig bindings for many scripting languages, one of them is python.
|
|
@ -0,0 +1,26 @@
|
|||
R2w
|
||||
===
|
||||
|
||||
The experimental web interface of r2 is named r2w. Check it out here:
|
||||
|
||||
hg clone http://radare.org/hg/r2w
|
||||
|
||||
The only dependency to run is r2-swig.
|
||||
|
||||
To start the web server type 'make':
|
||||
|
||||
$ make
|
||||
python main.py
|
||||
Process with PID 5756 started...
|
||||
eip = 0x40000810
|
||||
oeax = 0x0000000b
|
||||
eax = 0x00000000
|
||||
ebx = 0x00000000
|
||||
ecx = 0x00000000
|
||||
edx = 0x00000000
|
||||
esp = 0xbfcc6830
|
||||
ebp = 0x00000000
|
||||
esi = 0x00000000
|
||||
edi = 0x00000000
|
||||
eflags = 0x00200212
|
||||
http://127.0.0.1:8080/ : Serving directory 'www'
|
|
@ -0,0 +1,26 @@
|
|||
Using signatures in radare
|
||||
==========================
|
||||
|
||||
All the actions related to signatures in radare2 are collected
|
||||
in the 'z' command.
|
||||
|
||||
Here is the command help:
|
||||
|
||||
[0x000018a0]> z?
|
||||
Usage: z[abcp/*-] [arg]
|
||||
z show status of zignatures
|
||||
z* display all zignatures
|
||||
zp display current prefix
|
||||
zp prefix define prefix for following zignatures
|
||||
zp- unset prefix
|
||||
z-prefix unload zignatures prefixed as
|
||||
z-* unload all zignatures
|
||||
za ... define new zignature for analysis
|
||||
zb name bytes define new zignature for bytes
|
||||
zf name bytes define new function prelude zignature
|
||||
zg pfx [file] generate siganture for current file
|
||||
.zc @ fcn.foo flag signature if matching (.zc@@fcn)
|
||||
z/ [ini] [end] search zignatures between these regions
|
||||
NOTE: bytes can contain '.' (dots) to specify a binary mask
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
Signatures
|
||||
==========
|
||||
Signatures are byte streams used to identify functions, strings
|
||||
or watermarks inside binaries.
|
||||
|
||||
They are mostly helpful when working with static binaries and
|
||||
it is used to identify which functions from which libraries
|
||||
has been compiled into the static bin.
|
||||
|
||||
But there are other reasons to use them, like finding unreachable
|
||||
code, get name of unknown functions, etc..
|
||||
|
||||
Byte-based signatures
|
||||
---------------------
|
||||
|
||||
Those byte streams are used in the most basic signature checking
|
||||
algorithm. They have:
|
||||
|
||||
* byte array
|
||||
* binary mask
|
||||
* size of blob
|
||||
|
||||
The binary mask is required to ignore all those variable bits used
|
||||
to point data by the target code. The code analysis module can do
|
||||
this job for you.
|
||||
|
||||
Example code:
|
||||
|
||||
_foo: ; dummy label
|
||||
mov eax, 33 ; reg, const
|
||||
push ebx ; reg
|
||||
push [0x8049400] ; absolute address (ignored by signature)
|
||||
call 0x80434830 ; absolute address call (ignored by sign)
|
||||
cmp eax, 0 ; reg, const
|
||||
jz _foo ; relative address (used by the signature)
|
||||
|
||||
Other kind of signatures
|
||||
------------------------
|
||||
|
||||
There are other types of ways to identify functions inside a binary,
|
||||
here's a small list of them:
|
||||
|
||||
* function preludes
|
||||
|
||||
By understanding that most of the functions will be
|
||||
prefixed with some standard bytes to construct the
|
||||
stack frame and store return address on stack (depending
|
||||
on compiler and architecture)
|
||||
|
||||
* code analysis
|
||||
|
||||
Code analysis can be used to determine other characteristics of a
|
||||
function like number of basic blocks, code and data references, etc..
|
||||
|
||||
* callgraph
|
||||
|
||||
The name of the function can be determined by identifying
|
||||
the functions called from the target one.
|
||||
|
||||
This metric can be used to generate an automated function
|
||||
name if unknown or use it as a signature to collect this
|
||||
name from the loaded signature database.
|
||||
|
||||
Inline functions
|
||||
----------------
|
||||
|
||||
The compilers usually inline some small functions inside other
|
||||
functions. The size restriction is because the CPU cache that
|
||||
can make the program run slower than using a 'call'.
|
||||
|
||||
As they are small and they can va
|
||||
Those kind of functions are not going to be covered by this
|
||||
method because of the complexity and the small signature they
|
|
@ -0,0 +1,234 @@
|
|||
/* Based on werc stylesheet (werc.cat-v.org) */
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
color: rgb(39,78,144);
|
||||
background-color: rgb(140,170,230);
|
||||
background-color: #ff6d06;
|
||||
border: solid 0 black;
|
||||
border-width: 2px 0;
|
||||
}
|
||||
|
||||
.headerTitle {
|
||||
color: black;
|
||||
font-size: 233%;
|
||||
font-weight: normal;
|
||||
margin: 0 0 0 4mm;
|
||||
padding: 0.25ex 0;
|
||||
}
|
||||
|
||||
.headerSubTitle {
|
||||
font-size: 50%;
|
||||
font-style: italic;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.headerTitle a { color: black; }
|
||||
.headerTitle a:hover { text-decoration: none; }
|
||||
|
||||
/* Side */
|
||||
#side-bar {
|
||||
width: 12em;
|
||||
float: left;
|
||||
clear: left;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#side-bar ul {
|
||||
list-style-type: none;
|
||||
list-style-position: outside;
|
||||
margin: 0;
|
||||
padding: 0 0 0.3em 0;
|
||||
}
|
||||
|
||||
#side-bar li {
|
||||
margin: 0;
|
||||
padding: 0.1ex 0; /* Circumvents a rendering bug (?) in MSIE 6.0 XXX should move to iehacks.css, this causes an ugly gap */
|
||||
}
|
||||
|
||||
#side-bar a {
|
||||
color: rgb(0,102,204);
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
padding: 0.25em 1ex 0.25em 2mm;
|
||||
display: block;
|
||||
text-transform: capitalize;
|
||||
font-weight: bold!important;
|
||||
font-size: 102%;
|
||||
border-left: white solid 0.2em;
|
||||
}
|
||||
|
||||
#side-bar a:hover {
|
||||
color: white;
|
||||
background-color: rgb(100,135,220);
|
||||
border-left: black solid 0.2em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Main Copy */
|
||||
#main {
|
||||
max-width: 50em;
|
||||
color: black;
|
||||
background-color: transparent;
|
||||
text-align: justify;
|
||||
line-height: 1.5em;
|
||||
margin: 0em 0 0 12em;
|
||||
padding: 0.5mm 5mm 5mm 5mm;
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#bodyText {
|
||||
margin: 0 0 0 10.5em;
|
||||
padding: 2mm 5mm 2mm 5mm;
|
||||
}
|
||||
|
||||
#main p {
|
||||
margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#main a {
|
||||
color: rgb(0,102,204);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#main a:hover {
|
||||
color: rgb(100,135,220);
|
||||
}
|
||||
|
||||
#main h1, #main h2 {
|
||||
color: rgb(0,102,204);
|
||||
background-color: transparent;
|
||||
font-size: 145.5%;
|
||||
font-weight: bold;
|
||||
margin: 2em 0 0 0;
|
||||
padding: 0.5ex 0 0.5ex 0.6ex;
|
||||
border-bottom: 2px solid rgb(0,102,204);
|
||||
}
|
||||
|
||||
#main h2 {
|
||||
font-size: 115.5%;
|
||||
border-bottom: 1px solid rgb(0,102,204);
|
||||
}
|
||||
|
||||
#main .topOfPage {
|
||||
color: rgb(0,102,204);
|
||||
background-color: transparent;
|
||||
font-size: 91%;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
margin: 3ex 1ex 0 0;
|
||||
padding: 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 1em 1ex 2em 1ex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
margin: 0 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0 0 2em 2em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
#footer {
|
||||
color: white;
|
||||
background-color: rgb(100,135,220);
|
||||
padding: 0.4em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#footer .right {
|
||||
text-align: right;
|
||||
line-height: 1.45em;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: white;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* General */
|
||||
body {
|
||||
color: black;
|
||||
background-color: white;
|
||||
font-family: Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
|
||||
font-size: 84%; /* Enables font size scaling in MSIE */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
li ul {
|
||||
padding-left: 0.6em !important;
|
||||
}
|
||||
|
||||
table {
|
||||
border: solid 1px black;
|
||||
}
|
||||
th {
|
||||
background-color: #abc;
|
||||
border: solid 1px black;
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
background-color: #def;
|
||||
border: solid 1px black;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-width: 0px 0px 0.1em 0px;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
acronym, .titleTip {
|
||||
border-bottom: 1px solid #ddd;
|
||||
cursor: help;
|
||||
margin: 0;
|
||||
padding: 0 0 0.4px 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-left: 2em;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 1px solid blue;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* pancake css */
|
||||
textarea,body,input,td,tr,p,select,option,font {
|
||||
background-color: black !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
div,span,pre {
|
||||
background-color: black !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4 {
|
||||
background-color: black !important;
|
||||
color: #e02020 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #8080ff !important;
|
||||
/* color: #b0b0b0 !important; */
|
||||
}
|
||||
|
||||
:hover {
|
||||
color: #f0f0f0 !important;
|
||||
}
|
|
@ -874,7 +874,7 @@ static int cmd_help(void *data, const char *input) {
|
|||
" p?[len] ; print current block with format and length\n"
|
||||
" V[vcmds] ; enter visual mode (vcmds=visualvisual keystrokes)\n"
|
||||
" w[mode] [arg] ; multiple write operations\n"
|
||||
" x [len] ; alias for 'px' (print hexadecimal\n"
|
||||
" x [len] ; alias for 'px' (print hexadecimal)\n"
|
||||
" y [len] [off] ; yank/paste bytes from/to memory\n"
|
||||
" ? [expr] ; help or evaluate math expression\n"
|
||||
" /[xmp/] ; search for bytes, regexps, patterns, ..\n"
|
||||
|
|
|
@ -65,6 +65,7 @@ R_API int r_sys_setenv(const char *key, const char *value) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// TODO: strdup?
|
||||
#if __WINDOWS__
|
||||
static char envbuf[1024];
|
||||
R_API const char *r_sys_getenv(const char *key) {
|
||||
|
@ -88,30 +89,44 @@ R_API char *r_sys_getcwd() {
|
|||
}
|
||||
|
||||
#if __UNIX__
|
||||
static void pipeclose(int pipe[2]) {
|
||||
close (pipe[0]);
|
||||
close (pipe[1]);
|
||||
}
|
||||
|
||||
R_API char *r_sys_cmd_str_full(const char *cmd, const char *input, int *len, char **sterr) {
|
||||
char *inputptr = (char *)input;
|
||||
int bytes = 0;
|
||||
int sh_in[2];
|
||||
int sh_out[2];
|
||||
int sh_err[2];
|
||||
int pid, bytes = 0;
|
||||
int sh_in[2], sh_out[2], sh_err[2];
|
||||
|
||||
pipe(sh_in);
|
||||
pipe(sh_out);
|
||||
pipe(sh_err);
|
||||
if (sterr)
|
||||
pipe(sh_err);
|
||||
if (len) *len = 0;
|
||||
|
||||
int pid = fork();
|
||||
if (!pid) {
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
return NULL;
|
||||
case 0:
|
||||
dup2 (sh_in[0], 0); close (sh_in[0]); close (sh_in[1]);
|
||||
dup2 (sh_out[1], 1); close (sh_out[0]); close (sh_out[1]);
|
||||
if (sterr) dup2 (sh_err[1], 2);
|
||||
else close(2);
|
||||
if (sterr) dup2 (sh_err[1], 2); else close (2);
|
||||
close (sh_err[0]); close (sh_err[1]);
|
||||
execl ("/bin/sh", "sh", "-c", cmd, NULL);
|
||||
} else {
|
||||
exit (1);
|
||||
default:
|
||||
char buffer[1024];
|
||||
char *output = calloc (1, 1024);
|
||||
char *output = calloc (1, 1024); // TODO: use malloc
|
||||
if (!output)
|
||||
return NULL;
|
||||
if (sterr)
|
||||
*sterr = calloc (1, 1024);
|
||||
if (!*sterr) {
|
||||
free (output);
|
||||
return NULL;
|
||||
}
|
||||
close (sh_out[1]);
|
||||
close (sh_err[1]);
|
||||
close (sh_in[0]);
|
||||
|
@ -129,8 +144,7 @@ R_API char *r_sys_cmd_str_full(const char *cmd, const char *input, int *len, cha
|
|||
FD_SET (sh_err[0], &rfds);
|
||||
if (inputptr && *inputptr)
|
||||
FD_SET (sh_in[1], &wfds);
|
||||
|
||||
memset (buffer, 0, sizeof(buffer));
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
nfd = select (sh_err[0] + 1, &rfds, &wfds, NULL, NULL);
|
||||
if (nfd < 0)
|
||||
break;
|
||||
|
@ -142,17 +156,18 @@ R_API char *r_sys_cmd_str_full(const char *cmd, const char *input, int *len, cha
|
|||
if (read (sh_err[0], buffer, sizeof (buffer)-1) == 0) break;
|
||||
*sterr = r_str_concat (*sterr, buffer);
|
||||
} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
|
||||
bytes = write (sh_in[1], inputptr, strlen(inputptr));
|
||||
bytes = write (sh_in[1], inputptr, strlen (inputptr));
|
||||
inputptr += bytes;
|
||||
if (!*inputptr) close (sh_in[1]);
|
||||
}
|
||||
}
|
||||
close(sh_out[0]);
|
||||
close(sh_err[0]);
|
||||
close(sh_in[1]);
|
||||
close (sh_out[0]);
|
||||
close (sh_err[0]);
|
||||
close (sh_in[1]);
|
||||
|
||||
if (strlen(output))
|
||||
if (*output)
|
||||
return output;
|
||||
free (output);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue