Implement multidex and proper multibin in apkall:// ##bin

* Add testcase for multidex apk using apkall://
This commit is contained in:
pancake 2021-10-26 22:51:40 +02:00 committed by GitHub
parent 33243ea7f4
commit 05e76eb6bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 102 additions and 46 deletions

View File

@ -429,6 +429,7 @@ static int r_core_file_do_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loada
r_io_use_fd (r->io, fd);
RBinFileOptions opt;
r_bin_file_options_init (&opt, fd, baseaddr, loadaddr, r->bin->rawstr);
// opt.fd = fd;
opt.xtr_idx = xtr_idx;
if (!r_bin_open_io (r->bin, &opt)) {
//eprintf ("Failed to load the bin with an IO Plugin.\n");
@ -619,28 +620,28 @@ static bool linkcb(void *user, void *data, ut32 id) {
}
R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
RIODesc *desc = r->io->desc;
r_return_val_if_fail (r && r->io, false);
ut64 laddr = r_config_get_i (r->config, "bin.laddr");
RBinFile *binfile = NULL;
RBinPlugin *plugin = NULL;
bool is_io_load;
const char *cmd_load;
RIODesc *desc = r->io->desc;
if (!desc && filenameuri) {
desc = r_io_desc_get_byuri (r->io, filenameuri);
}
if (!desc) {
return false;
}
// NULL deref guard
if (desc) {
is_io_load = desc && desc->plugin;
if (!filenameuri || !*filenameuri) {
filenameuri = desc->name;
// hack for openmany handlers
if (*filenameuri == '-') {
// filenameuri = "malloc://512";
return false;
}
} else {
is_io_load = false;
r_core_file_open (r, filenameuri, 0, baddr);
desc = r->io->desc;
}
if (!filenameuri) {
eprintf ("r_core_bin_load: no file specified\n");
return false;
bool is_io_load = false;
if (desc && desc->plugin) {
is_io_load = true;
// r_io_use_fd (r->io, desc->fd);
}
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
@ -831,7 +832,6 @@ beach:
}
R_API RIODesc *r_core_file_open_many(RCore *r, const char *file, int perm, ut64 loadaddr) {
RListIter *fd_iter, *iter2;
RIODesc *fd;
RList *list_fds = r_io_open_many (r->io, file, perm, 0644);
@ -840,11 +840,27 @@ R_API RIODesc *r_core_file_open_many(RCore *r, const char *file, int perm, ut64
r_list_free (list_fds);
return NULL;
}
r_list_foreach_safe (list_fds, fd_iter, iter2, fd) {
r_core_bin_load (r, fd->name, loadaddr);
RListIter *iter;
RIODesc *first = NULL;
bool incloadaddr = loadaddr == 0;
// r_config_set_b (r->config, "io.va", false);
r_list_foreach (list_fds, iter, fd) {
if (fd->uri) {
if (!first) {
first = fd;
}
r_io_use_fd (r->io, fd->fd);
// r_core_file_open (r, fd->uri, perm, loadaddr);
ut64 sz = r_io_fd_size (r->io, fd->fd);
r_core_bin_load (r, fd->uri, loadaddr);
if (incloadaddr && sz != UT64_MAX) {
const int rest = (sz % 4096);
const int pillow = 0x4000;
loadaddr += sz + rest + pillow;
}
}
}
return NULL;
return first;
}
/* loadaddr is r2 -m (mapaddr) */

View File

@ -1552,9 +1552,9 @@ static bool cmd_op(RCore *core, char mode, int fd) {
r_core_block_read (core);
return true;
}
eprintf ("Invalid RBinFile.id number.\n");
// eprintf ("Invalid RBinFile.id number.\n");
}
return false;
return next_fd != -1;
}
static bool cmd_onn(RCore *core, const char* input) {

View File

@ -284,9 +284,7 @@ RIOZipFileObj* r_io_zip_alloc_zipfileobj(const char *archivename, const char *fi
static RList *r_io_zip_open_many(RIO *io, const char *file, int rw, int mode) {
RList *list_fds = NULL;
RListIter *iter;
RList *filenames = NULL;
RIODesc *res = NULL;
RIOZipFileObj *zfo = NULL;
char *filename_in_zipfile, *zip_filename = NULL, *zip_uri;
if (!r_io_zip_plugin_open (io, file, true)) {
@ -310,7 +308,7 @@ static RList *r_io_zip_open_many(RIO *io, const char *file, int rw, int mode) {
return NULL;
}
filenames = r_io_zip_get_files(zip_filename, 0, mode, rw );
RList *filenames = r_io_zip_get_files (zip_filename, 0, mode, rw );
if (!filenames) {
free (zip_uri);
@ -320,27 +318,37 @@ static RList *r_io_zip_open_many(RIO *io, const char *file, int rw, int mode) {
list_fds = r_list_new ();
r_list_foreach (filenames, iter, filename_in_zipfile) {
size_t v = strlen (filename_in_zipfile);
if (filename_in_zipfile[v - 1] == '/') {
if (v < 1 || filename_in_zipfile[v - 1] == '/') {
continue;
}
zfo = r_io_zip_alloc_zipfileobj (zip_filename,
RIOZipFileObj *zfo = r_io_zip_alloc_zipfileobj (zip_filename,
filename_in_zipfile, ZIP_CREATE, mode, rw);
if (zfo && zfo->entry == -1) {
eprintf ("Warning: File did not exist, creating a new one.\n");
}
if (zfo) {
zfo->io_backref = io;
res = r_io_desc_new (io, &r_io_plugin_zip,
zfo->name, rw, mode, zfo);
bool append = false;
if (r_str_startswith (file, "apkall://")) {
if (r_str_endswith (zfo->name, ".dex")) {
append = true;
}
} else {
append = true;
}
if (append) {
char *name = r_str_newf ("zip://%s//%s", zip_filename, zfo->name);
res = r_io_desc_new (io, &r_io_plugin_zip,
name, rw, mode, zfo);
free (name);
r_list_append (list_fds, res);
}
}
r_list_append (list_fds, res);
}
free(zip_uri);
free (zip_uri);
r_list_free (filenames);
return list_fds;
}
@ -391,15 +399,27 @@ static RIODesc *r_io_zip_open(RIO *io, const char *file, int rw, int mode) {
zip_filename = tmp ? strdup (tmp) : NULL;
// 1) Tokenize to the '//' and find the base file directory ('/')
if (!zip_filename) {
if (!strncmp (zip_uri, "apk://", 6)) {
if (r_str_startswith (zip_uri, "apk://")) {
RListIter *iter;
char *name;
RList *files = r_io_zip_get_files (pikaboo + 3, 0, mode, rw );
if (files) {
r_list_foreach (files, iter, name) {
if (r_str_startswith (name, "classes") && r_str_endswith (name, ".dex")) {
if (strcmp (name, "classes.dex")) {
eprintf ("Warning: This is a multidex APK, you may want to use apkall:// instead\n");
break;
}
}
}
}
r_list_free (files);
zip_filename = r_str_newf ("//%s//classes.dex", pikaboo + 3);
} else if (!strncmp (zip_uri, "ipa://", 6)) {
RList *files = NULL;
} else if (r_str_startswith (zip_uri, "ipa://")) {
RListIter *iter;
char *name;
zip_filename = strdup (pikaboo + 3);
files = r_io_zip_get_files (zip_filename, 0, mode, rw );
RList *files = r_io_zip_get_files (zip_filename, 0, mode, rw );
if (files) {
r_list_foreach (files, iter, name) {
/* Find matching file */

View File

@ -114,8 +114,6 @@ RUN
NAME=o -
FILE=malloc://1024
CMDS=<<EOF
e file.nowarn=true
e file.loadmethod=append
o -;o~?
EOF
EXPECT=<<EOF

View File

@ -1,8 +1,6 @@
NAME=dupfd bug
FILE=-
CMDS=<<EOF
e file.nowarn=true
e file.loadmethod=append
e scr.null=true
10o -
e scr.null=false
@ -16,8 +14,6 @@ RUN
NAME=dupfd hard
FILE=-
CMDS=<<EOF
e file.loadmethod=append
e file.nowarn=true
e scr.null=true
1000o -
e scr.null=false

View File

@ -65,8 +65,6 @@ NAME=om 0x100;x@0xff
FILE=-
CMDS=<<EOF
e io.va=false
e file.nowarn=true
e file.loadmethod=append
om `o~[0]` 0x100
w pop @ 1
p8 4 @ 0x100

View File

@ -1,3 +1,31 @@
NAME=apkall://
FILE=apkall://bins/dex/mobipwn-nores.apk
CMDS=<<EOF
o
ob
ic~?
ob *
ob
ic~?
EOF
EXPECT=<<EOF
3 - r-x 0x00045b18 zip://bins/dex/mobipwn-nores.apk//classes.dex
4 - r-x 0x000382b4 zip://bins/dex/mobipwn-nores.apk//classes2.dex
5 - r-x 0x000343a8 zip://bins/dex/mobipwn-nores.apk//classes3.dex
6 * r-x 0x00045d30 zip://bins/dex/mobipwn-nores.apk//classes4.dex
- 0 3 dalvik-32 ba:0x00000000 sz:285464 ?
- 1 4 dalvik-32 ba:0x0004a630 sz:230068 ?
- 2 5 dalvik-32 ba:0x00086b98 sz:213928 ?
* 3 6 dalvik-32 ba:0x000bf2e8 sz:286000 ?
1383
* 0 3 dalvik-32 ba:0x00000000 sz:285464 ?
* 1 4 dalvik-32 ba:0x0004a630 sz:230068 ?
* 2 5 dalvik-32 ba:0x00086b98 sz:213928 ?
* 3 6 dalvik-32 ba:0x000bf2e8 sz:286000 ?
5363
EOF
RUN
NAME=io-zip
FILE=zip://bins/java/example.zip
BROKEN=1