mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-03 02:41:08 +00:00
Better r2 -P and refactor 'r_core_patch' to accept a string instead of file name
This commit is contained in:
parent
6a6af44a4e
commit
cf664a9f22
@ -612,10 +612,18 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
r.num->value = 0;
|
||||
if (patchfile) {
|
||||
r_core_patch (&r, patchfile);
|
||||
} else {
|
||||
char *data = r_file_slurp (patchfile, NULL);
|
||||
if (data) {
|
||||
r_core_patch (&r, data);
|
||||
r_core_seek (&r, 0, 1);
|
||||
free (data);
|
||||
} else eprintf ("Cannot open '%s'\n", patchfile);
|
||||
}
|
||||
if ((patchfile && !quiet) || !patchfile) {
|
||||
if (zerosep)
|
||||
r_cons_zero ();
|
||||
if (seek != UT64_MAX)
|
||||
r_core_seek (&r, seek, 1);
|
||||
for (;;) {
|
||||
r.zerosep = zerosep;
|
||||
#if USE_THREADS
|
||||
|
@ -215,15 +215,16 @@ static int cmd_write(void *data, const char *input) {
|
||||
const char *tmpfile = ".tmp";
|
||||
char *out = r_core_editor (core, NULL);
|
||||
if (out) {
|
||||
// XXX hacky .. patch should support str, not only file
|
||||
r_file_dump (tmpfile, (ut8*)out, strlen (out));
|
||||
r_core_patch (core, tmpfile);
|
||||
r_file_rm (tmpfile);
|
||||
r_core_patch (core, out);
|
||||
free (out);
|
||||
}
|
||||
} else {
|
||||
if (input[1]==' ' && input[2]) {
|
||||
r_core_patch (core, input+2);
|
||||
char *data = r_file_slurp (input+2, NULL);
|
||||
if (data) {
|
||||
r_core_patch (core, data);
|
||||
free (data);
|
||||
}
|
||||
} else {
|
||||
eprintf ("Usage: wp [-|r2patch-file]\n"
|
||||
"TODO: rapatch format documentation here\n");
|
||||
|
@ -2,88 +2,110 @@
|
||||
|
||||
#include <r_core.h>
|
||||
|
||||
R_API int r_core_patch (RCore *core, const char *patch) {
|
||||
char *p, *p2, *q, str[200], tmp[64];
|
||||
ut64 noff = 0LL;
|
||||
FILE *fd = r_sandbox_fopen (patch, "r");
|
||||
if (fd==NULL) {
|
||||
eprintf ("Cannot open patch file\n");
|
||||
return 1;
|
||||
R_API int r_core_patch_line (RCore *core, char *str) {
|
||||
char *p, *q;
|
||||
p = strchr (str+1, ' ');
|
||||
if (!p)
|
||||
return 0;
|
||||
*p = 0;
|
||||
for (++p; *p==' '; p++); // XXX: skipsspaces here
|
||||
|
||||
switch (*p) {
|
||||
case '"':
|
||||
q = strchr (p+1,'"');
|
||||
if (q) *q = 0;
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "\"w %s\"", p+1);
|
||||
break;
|
||||
case ':':
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "wa %s", p);
|
||||
break;
|
||||
default:
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "wx %s", p);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (!feof (fd)) {
|
||||
fgets (str, sizeof (str), fd);
|
||||
if (*str=='#' || *str=='\n' || *str=='\r')
|
||||
continue;
|
||||
if (*str==':') {
|
||||
r_core_cmd0 (core, str+1);
|
||||
continue;
|
||||
}
|
||||
if (*str=='.' || *str=='!') {
|
||||
r_core_cmd0 (core, str);
|
||||
continue;
|
||||
}
|
||||
p = strchr (str+1, ' ');
|
||||
if (!p)
|
||||
continue;
|
||||
*p = 0;
|
||||
for (++p; *p==' '; p++); // XXX: skipsspaces here
|
||||
switch (*p) {
|
||||
case '{': {
|
||||
char *s, *off = strdup (str);
|
||||
RBuffer *b = r_buf_new ();
|
||||
|
||||
while (!feof (fd)) {
|
||||
fgets (str, sizeof (str), fd);
|
||||
if (*str=='}')
|
||||
break;
|
||||
if ((q=strstr (str, "${"))) {
|
||||
char *end = strchr (q+2,'}');
|
||||
if (end) {
|
||||
*q = *end = 0;
|
||||
noff = r_num_math (core->num, q+2);
|
||||
r_buf_append_bytes (b, (const ut8*)str, strlen (str));
|
||||
snprintf (tmp, sizeof (tmp), "0x%08"PFMT64x, noff);
|
||||
r_buf_append_bytes (b, (const ut8*)tmp, strlen (tmp));
|
||||
r_buf_append_bytes (b, (const ut8*)end+1, strlen (end+1));
|
||||
}
|
||||
} else r_buf_append_bytes (b, (const ut8*)str, strlen (str));
|
||||
}
|
||||
R_API int r_core_patch (RCore *core, const char *patch) {
|
||||
char *p, *p0, *str;
|
||||
ut64 noff = 0LL;
|
||||
|
||||
s = r_buf_to_string (b);
|
||||
r_egg_load (core->egg, s, 0);
|
||||
free (s);
|
||||
|
||||
r_egg_compile (core->egg);
|
||||
r_egg_assemble (core->egg);
|
||||
p = p0 = str = strdup (patch);
|
||||
if (!p)
|
||||
return 0;
|
||||
for (; ; p++) {
|
||||
/* read until newline */
|
||||
if (!*p || *p=='\n') *p++ = 0; else continue;
|
||||
|
||||
r_buf_free (b);
|
||||
b = r_egg_get_bin (core->egg);
|
||||
|
||||
if (strcmp (off, "+"))
|
||||
noff = r_num_math (core->num, off);
|
||||
r_core_write_at (core, noff, b->buf, b->length);
|
||||
noff += b->length;
|
||||
r_buf_free (b);
|
||||
free (off);
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
p2 = strchr (p+1,'"');
|
||||
if (p2) *p2=0;
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "\"w %s\"", p+1);
|
||||
switch (*str) {
|
||||
case '#':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\0':
|
||||
break;
|
||||
case ':':
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "wa %s", p);
|
||||
r_core_cmd0 (core, str+1);
|
||||
break;
|
||||
case '.':
|
||||
case '!':
|
||||
r_core_cmd0 (core, str);
|
||||
break;
|
||||
case '{': {
|
||||
char tmp[128];
|
||||
char *s, *q, *off = strdup (str);
|
||||
RBuffer *b = r_buf_new ();
|
||||
|
||||
str = p;
|
||||
for (;;) {
|
||||
if (*p=='\n') {
|
||||
*p++ = 0;
|
||||
} else continue;
|
||||
if (*str=='}')
|
||||
break;
|
||||
if ((q=strstr (str, "${"))) {
|
||||
char *end = strchr (q+2,'}');
|
||||
if (end) {
|
||||
*q = *end = 0;
|
||||
noff = r_num_math (core->num, q+2);
|
||||
r_buf_append_bytes (b, (const ut8*)str, strlen (str));
|
||||
snprintf (tmp, sizeof (tmp), "0x%08"PFMT64x, noff);
|
||||
r_buf_append_bytes (b, (const ut8*)tmp, strlen (tmp));
|
||||
r_buf_append_bytes (b, (const ut8*)end+1, strlen (end+1));
|
||||
}
|
||||
} else r_buf_append_bytes (b, (const ut8*)str, strlen (str));
|
||||
str = p;
|
||||
}
|
||||
|
||||
s = r_buf_to_string (b);
|
||||
r_egg_load (core->egg, s, 0);
|
||||
free (s);
|
||||
|
||||
r_egg_compile (core->egg);
|
||||
r_egg_assemble (core->egg);
|
||||
|
||||
r_buf_free (b);
|
||||
b = r_egg_get_bin (core->egg);
|
||||
|
||||
if (strcmp (off, "+"))
|
||||
noff = r_num_math (core->num, off);
|
||||
r_core_write_at (core, noff, b->buf, b->length);
|
||||
noff += b->length;
|
||||
r_buf_free (b);
|
||||
free (off);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r_core_cmdf (core, "s %s", str);
|
||||
r_core_cmdf (core, "wx %s", p);
|
||||
r_core_patch_line (core, str);
|
||||
break;
|
||||
}
|
||||
if (!*p) break;
|
||||
str = p;
|
||||
}
|
||||
fclose (fd);
|
||||
// eprintf ("%d\n", *p);
|
||||
// eprintf ("Missing newline\n");
|
||||
free (p0);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user