mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
rz-ar: add archive extraction utility (#6036)
This commit is contained in:
parent
6e016eee9c
commit
470b1b1eb7
13 changed files with 445 additions and 2 deletions
|
|
@ -93,6 +93,7 @@ Apart from the main tool `rizin`, there are also other tools tailored for specif
|
||||||
useful for shell scripting or as separate standalone tools:
|
useful for shell scripting or as separate standalone tools:
|
||||||
|
|
||||||
- `rz-bin` - provides all kind of information about binary formats
|
- `rz-bin` - provides all kind of information about binary formats
|
||||||
|
- `rz-ar` - list and extract members from static archives (.a and .lib)
|
||||||
- `rz-asm` - a command-line assembler and disassemblers
|
- `rz-asm` - a command-line assembler and disassemblers
|
||||||
- `rz-diff` - a tool to compare two binaries as raw data or analyzed executables
|
- `rz-diff` - a tool to compare two binaries as raw data or analyzed executables
|
||||||
- `rz-hash` - allows to calculate different hashes or even encrypt data
|
- `rz-hash` - allows to calculate different hashes or even encrypt data
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ set -e
|
||||||
mkdir -p "${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
|
mkdir -p "${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
|
||||||
cd "${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
|
cd "${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
|
||||||
|
|
||||||
TOOLS="rz-hash rz-run rz-asm rz-bin rz-gg rz-diff rz-find rz-sign rz-ax"
|
TOOLS="rz-ar rz-hash rz-run rz-asm rz-bin rz-gg rz-diff rz-find rz-sign rz-ax"
|
||||||
|
|
||||||
for TOOL in $TOOLS ; do
|
for TOOL in $TOOLS ; do
|
||||||
ln -sf rizin "$TOOL" ;
|
ln -sf rizin "$TOOL" ;
|
||||||
|
|
|
||||||
67
binrz/man/rz-ar.1
Normal file
67
binrz/man/rz-ar.1
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
.Dd March 14, 2026
|
||||||
|
.Dt RZ_AR 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rz-ar
|
||||||
|
.Nd List and extract members from .a and .lib archives
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm rz-ar
|
||||||
|
.Op Fl hlqv
|
||||||
|
.Op Fl o Ar outdir
|
||||||
|
.Ar archive
|
||||||
|
.Op Ar member ...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This command is part of the Rizin project.
|
||||||
|
.Pp
|
||||||
|
.Nm rz-ar
|
||||||
|
lists or extracts archive members from
|
||||||
|
.Pa .a
|
||||||
|
and
|
||||||
|
.Pa .lib
|
||||||
|
files.
|
||||||
|
It creates missing directories in the output path automatically.
|
||||||
|
.Pp
|
||||||
|
When no member filters are provided, all members are processed.
|
||||||
|
When one or more
|
||||||
|
.Ar member
|
||||||
|
arguments are provided, only matching members are processed.
|
||||||
|
.Pp
|
||||||
|
The options are:
|
||||||
|
.Bl -tag -width Fl
|
||||||
|
.It Fl h
|
||||||
|
Show usage help message.
|
||||||
|
.It Fl l
|
||||||
|
List matching members only.
|
||||||
|
.It Fl o Ar outdir
|
||||||
|
Set extraction output directory (default: current directory).
|
||||||
|
.It Fl q
|
||||||
|
Quiet mode.
|
||||||
|
.It Fl v
|
||||||
|
Show version information.
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It 0
|
||||||
|
Operation completed successfully.
|
||||||
|
.It 1
|
||||||
|
Invalid arguments, open failure, no matches, or extraction failures.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
List all members:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
rz-ar -l libfoo.a
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Extract all members into current directory:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
rz-ar libfoo.a
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Extract selected members into output directory:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
rz-ar -o out libfoo.a foo.o bar.o
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rizin 1 ,
|
||||||
|
.Xr rz-bin 1 ,
|
||||||
|
.Xr rz-hash 1
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
if get_option('blob')
|
if get_option('blob')
|
||||||
subdir('blob')
|
subdir('blob')
|
||||||
else
|
else
|
||||||
|
subdir('rz-ar')
|
||||||
subdir('rz-hash')
|
subdir('rz-hash')
|
||||||
subdir('rz-run')
|
subdir('rz-run')
|
||||||
subdir('rz-asm')
|
subdir('rz-asm')
|
||||||
|
|
@ -17,6 +18,7 @@ if get_option('enable_rz_test')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install_man(
|
install_man(
|
||||||
|
'man/rz-ar.1',
|
||||||
'man/rz-bin.1',
|
'man/rz-bin.1',
|
||||||
'man/rizin.1',
|
'man/rizin.1',
|
||||||
'man/rz-diff.1',
|
'man/rz-diff.1',
|
||||||
|
|
|
||||||
10
binrz/rz-ar/meson.build
Normal file
10
binrz/rz-ar/meson.build
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
executable('rz-ar', 'rz-ar.c',
|
||||||
|
include_directories: [platform_inc],
|
||||||
|
dependencies: [
|
||||||
|
rz_main_dep,
|
||||||
|
rz_util_dep,
|
||||||
|
],
|
||||||
|
install: true,
|
||||||
|
install_rpath: rpath_exe,
|
||||||
|
implicit_include_directories: false,
|
||||||
|
)
|
||||||
11
binrz/rz-ar/rz-ar.c
Normal file
11
binrz/rz-ar/rz-ar.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 RizinOrg <info@rizin.re>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#include <rz_main.h>
|
||||||
|
|
||||||
|
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||||
|
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||||
|
int ret = rz_main_rz_ar(argc, (const char **)utf8_argv);
|
||||||
|
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,7 @@ static char *read_string_val(char **nextline, const char *val, ut64 *linenum) {
|
||||||
|
|
||||||
static const char *rz_test_tools[] = {
|
static const char *rz_test_tools[] = {
|
||||||
"rizin",
|
"rizin",
|
||||||
|
"rz-ar",
|
||||||
"rz-asm",
|
"rz-asm",
|
||||||
"rz-ax",
|
"rz-ax",
|
||||||
"rz-bin",
|
"rz-bin",
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ RZ_API int rz_main_rz_find(int argc, const char **argv);
|
||||||
RZ_API int rz_main_rz_diff(int argc, const char **argv);
|
RZ_API int rz_main_rz_diff(int argc, const char **argv);
|
||||||
RZ_API int rz_main_rz_gg(int argc, const char **argv);
|
RZ_API int rz_main_rz_gg(int argc, const char **argv);
|
||||||
RZ_API int rz_main_rz_sign(int argc, const char **argv);
|
RZ_API int rz_main_rz_sign(int argc, const char **argv);
|
||||||
|
RZ_API int rz_main_rz_ar(int argc, const char **argv);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ typedef struct main_entry_t {
|
||||||
|
|
||||||
static MainEntry main_prog[] = {
|
static MainEntry main_prog[] = {
|
||||||
{ "rizin", rz_main_rizin },
|
{ "rizin", rz_main_rizin },
|
||||||
|
{ "rz-ar", rz_main_rz_ar },
|
||||||
{ "rz-asm", rz_main_rz_asm },
|
{ "rz-asm", rz_main_rz_asm },
|
||||||
{ "rz-ax", rz_main_rz_ax },
|
{ "rz-ax", rz_main_rz_ax },
|
||||||
{ "rz-bin", rz_main_rz_bin },
|
{ "rz-bin", rz_main_rz_bin },
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
rz_main_sources = [
|
rz_main_sources = [
|
||||||
'main.c',
|
'main.c',
|
||||||
|
'rz-ar.c',
|
||||||
'rz-bin.c',
|
'rz-bin.c',
|
||||||
'rizin.c',
|
'rizin.c',
|
||||||
'rz-diff.c',
|
'rz-diff.c',
|
||||||
|
|
@ -34,6 +35,7 @@ rz_main_deps = [
|
||||||
rz_sign_dep,
|
rz_sign_dep,
|
||||||
rz_core_dep,
|
rz_core_dep,
|
||||||
rz_diff_dep,
|
rz_diff_dep,
|
||||||
|
dependency('rzar'),
|
||||||
]
|
]
|
||||||
|
|
||||||
rz_main = library('rz_main', rz_main_sources,
|
rz_main = library('rz_main', rz_main_sources,
|
||||||
|
|
|
||||||
284
librz/main/rz-ar.c
Normal file
284
librz/main/rz-ar.c
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 RizinOrg <info@rizin.re>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#include <rz_main.h>
|
||||||
|
#include <rz_cons.h>
|
||||||
|
#include <rz_util.h>
|
||||||
|
#include <rz_util/rz_print.h>
|
||||||
|
#include "ar.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *outdir;
|
||||||
|
bool list_only;
|
||||||
|
bool quiet;
|
||||||
|
} RzArOptions;
|
||||||
|
|
||||||
|
#define RZ_AR_EXTRACT_CHUNK_SIZE 0x10000
|
||||||
|
|
||||||
|
static void rz_ar_show_help(void) {
|
||||||
|
printf("%s%s%s", Color_CYAN, "Usage: ", Color_RESET);
|
||||||
|
printf("rz-ar [-hlqv] [-o outdir] archive [member ...]\n");
|
||||||
|
// clang-format off
|
||||||
|
const char *options[] = {
|
||||||
|
"-h", "", "Show this help",
|
||||||
|
"-l", "", "List matching members",
|
||||||
|
"-o", "dir", "Set output directory (default .)",
|
||||||
|
"-q", "", "Quiet mode",
|
||||||
|
"-v", "", "Show version information",
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
rz_print_colored_help(options, RZ_ARRAY_SIZE(options), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *rz_ar_normalize_member_path(const char *name) {
|
||||||
|
rz_return_val_if_fail(name, NULL);
|
||||||
|
char *tmp = rz_file_path_local_to_unix(name);
|
||||||
|
if (!tmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rz_str_replace_char(tmp, '\\', '/');
|
||||||
|
RzList *parts = rz_str_split_duplist(tmp, "/", false);
|
||||||
|
if (!parts) {
|
||||||
|
free(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
RzList *stack = rz_list_newf(free);
|
||||||
|
if (!stack) {
|
||||||
|
rz_list_free(parts);
|
||||||
|
free(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
RzListIter *it;
|
||||||
|
char *part;
|
||||||
|
rz_list_foreach (parts, it, part) {
|
||||||
|
if (RZ_STR_ISEMPTY(part) || RZ_STR_EQ(part, ".")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (RZ_STR_EQ(part, "..")) {
|
||||||
|
char *prev = rz_list_pop(stack);
|
||||||
|
free(prev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *tok = rz_str_dup(part);
|
||||||
|
if (!tok) {
|
||||||
|
rz_list_free(stack);
|
||||||
|
rz_list_free(parts);
|
||||||
|
free(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (char *p = tok; *p; p++) {
|
||||||
|
if (*p == ':' || !IS_PRINTABLE(*p)) {
|
||||||
|
*p = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rz_list_append(stack, tok)) {
|
||||||
|
free(tok);
|
||||||
|
rz_list_free(stack);
|
||||||
|
rz_list_free(parts);
|
||||||
|
free(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RzStrBuf sb;
|
||||||
|
rz_strbuf_init(&sb);
|
||||||
|
bool first = true;
|
||||||
|
rz_list_foreach (stack, it, part) {
|
||||||
|
if (!first) {
|
||||||
|
rz_strbuf_append(&sb, "/");
|
||||||
|
}
|
||||||
|
rz_strbuf_append(&sb, part);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
char *out = NULL;
|
||||||
|
if (!rz_strbuf_is_empty(&sb)) {
|
||||||
|
out = rz_strbuf_drain_nofree(&sb);
|
||||||
|
}
|
||||||
|
rz_strbuf_fini(&sb);
|
||||||
|
rz_list_free(stack);
|
||||||
|
rz_list_free(parts);
|
||||||
|
free(tmp);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rz_ar_member_matches(const char *member_name, const char *normalized_name, const char **filters, int nfilters) {
|
||||||
|
rz_return_val_if_fail(member_name && normalized_name, false);
|
||||||
|
if (!nfilters || !filters) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char *member_base = rz_file_basename(member_name);
|
||||||
|
const char *normalized_base = rz_file_basename(normalized_name);
|
||||||
|
for (int i = 0; i < nfilters; i++) {
|
||||||
|
const char *f = filters[i];
|
||||||
|
if (RZ_STR_EQ(f, member_name) || RZ_STR_EQ(f, normalized_name) || RZ_STR_EQ(f, member_base) || RZ_STR_EQ(f, normalized_base)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *rz_ar_unique_output_path(const char *path) {
|
||||||
|
rz_return_val_if_fail(path, NULL);
|
||||||
|
if (!rz_file_exists(path) && !rz_file_is_directory(path)) {
|
||||||
|
return rz_str_dup(path);
|
||||||
|
}
|
||||||
|
for (int i = 1;; i++) {
|
||||||
|
char *candidate = rz_str_newf("%s.%d", path, i);
|
||||||
|
if (!candidate) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!rz_file_exists(candidate) && !rz_file_is_directory(candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
free(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rz_ar_extract_member(RzArFp *member, const char *dst_path) {
|
||||||
|
rz_return_val_if_fail(member && dst_path, false);
|
||||||
|
const ut64 size = member->end - member->start;
|
||||||
|
if (size == 0) {
|
||||||
|
return rz_file_dump(dst_path, NULL, 0, false);
|
||||||
|
}
|
||||||
|
ut8 *buf = malloc(RZ_AR_EXTRACT_CHUNK_SIZE);
|
||||||
|
if (!buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ut64 off = 0;
|
||||||
|
bool append = false;
|
||||||
|
while (off < size) {
|
||||||
|
const ut64 left = size - off;
|
||||||
|
const int want = (int)RZ_MIN(left, (ut64)RZ_AR_EXTRACT_CHUNK_SIZE);
|
||||||
|
const int got = ar_read_at(member, off, buf, want);
|
||||||
|
if (got <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!rz_file_dump(dst_path, buf, got, append)) {
|
||||||
|
off = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
append = true;
|
||||||
|
off += got;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return off == size;
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API int rz_main_rz_ar(int argc, const char **argv) {
|
||||||
|
RzGetopt opt;
|
||||||
|
RzArOptions options = {
|
||||||
|
.outdir = ".",
|
||||||
|
.list_only = false,
|
||||||
|
.quiet = false,
|
||||||
|
};
|
||||||
|
int c;
|
||||||
|
rz_getopt_init(&opt, argc, argv, "hlo:qv");
|
||||||
|
while ((c = rz_getopt_next(&opt)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
rz_ar_show_help();
|
||||||
|
return 0;
|
||||||
|
case 'l':
|
||||||
|
options.list_only = true;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
options.outdir = opt.arg;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
options.quiet = true;
|
||||||
|
break;
|
||||||
|
case 'v': {
|
||||||
|
RzPath *sys_path = rz_path_new();
|
||||||
|
if (!sys_path) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int ret = rz_main_version_print(sys_path, "rz-ar");
|
||||||
|
rz_path_free(sys_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
RZ_LOG_ERROR("rz-ar: invalid option -%c\n", c);
|
||||||
|
rz_ar_show_help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opt.ind >= argc) {
|
||||||
|
RZ_LOG_ERROR("rz-ar: missing archive path\n");
|
||||||
|
rz_ar_show_help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char *archive_path = argv[opt.ind++];
|
||||||
|
const char **filters = argc > opt.ind ? &argv[opt.ind] : NULL;
|
||||||
|
const int nfilters = argc - opt.ind;
|
||||||
|
RzList *members = ar_open_all(archive_path, O_RDONLY | O_BINARY);
|
||||||
|
if (!members) {
|
||||||
|
RZ_LOG_ERROR("rz-ar: cannot open archive '%s'\n", archive_path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!options.list_only && !rz_sys_mkdirp(options.outdir)) {
|
||||||
|
RZ_LOG_ERROR("rz-ar: cannot create output directory '%s'\n", options.outdir);
|
||||||
|
rz_list_free(members);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int matched = 0;
|
||||||
|
int extracted = 0;
|
||||||
|
int failed = 0;
|
||||||
|
RzListIter *it;
|
||||||
|
RzArFp *member;
|
||||||
|
rz_list_foreach (members, it, member) {
|
||||||
|
char *normalized_name = rz_ar_normalize_member_path(member->name);
|
||||||
|
if (!normalized_name) {
|
||||||
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!rz_ar_member_matches(member->name, normalized_name, filters, nfilters)) {
|
||||||
|
free(normalized_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
matched++;
|
||||||
|
if (options.list_only) {
|
||||||
|
printf("%s\n", normalized_name);
|
||||||
|
free(normalized_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *dst = rz_file_path_join(options.outdir, normalized_name);
|
||||||
|
free(normalized_name);
|
||||||
|
if (!dst) {
|
||||||
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *unique_dst = rz_ar_unique_output_path(dst);
|
||||||
|
free(dst);
|
||||||
|
if (!unique_dst) {
|
||||||
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *dir = rz_file_dirname(unique_dst);
|
||||||
|
if (!dir || !rz_sys_mkdirp(dir)) {
|
||||||
|
free(dir);
|
||||||
|
free(unique_dst);
|
||||||
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
free(dir);
|
||||||
|
if (!rz_ar_extract_member(member, unique_dst)) {
|
||||||
|
RZ_LOG_ERROR("rz-ar: failed to extract '%s'\n", unique_dst);
|
||||||
|
free(unique_dst);
|
||||||
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
extracted++;
|
||||||
|
if (!options.quiet) {
|
||||||
|
printf("%s\n", unique_dst);
|
||||||
|
}
|
||||||
|
free(unique_dst);
|
||||||
|
}
|
||||||
|
rz_list_free(members);
|
||||||
|
if (matched == 0) {
|
||||||
|
RZ_LOG_ERROR("rz-ar: no matching members\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!options.list_only && !options.quiet) {
|
||||||
|
printf("extracted %d file(s)%s\n", extracted, failed ? " with failures" : "");
|
||||||
|
}
|
||||||
|
return failed ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
@ -190,7 +190,7 @@ Without the regex that filtered out the non-deterministic file path and addresse
|
||||||
|
|
||||||
* **NAME** is the name of the test, it must be unique
|
* **NAME** is the name of the test, it must be unique
|
||||||
* **FILE** (optional when `TOOL` is set) is the file or input used for the test
|
* **FILE** (optional when `TOOL` is set) is the file or input used for the test
|
||||||
* **TOOL** (optional) allows you to override the tool to test (supports only `rizin`, `rz-asm`, `rz-ax`, `rz-bin`, `rz-diff`, `rz-find`, `rz-gg`, `rz-hash`, `rz-run`, `rz-sign`, `rz-test`)
|
* **TOOL** (optional) allows you to override the tool to test (supports only `rizin`, `rz-ar`, `rz-asm`, `rz-ax`, `rz-bin`, `rz-diff`, `rz-find`, `rz-gg`, `rz-hash`, `rz-run`, `rz-sign`, `rz-test`)
|
||||||
* **ARGS** (optional, unless `TOOL` is set) are the command line argument passed to rizin (e.g -b 16)
|
* **ARGS** (optional, unless `TOOL` is set) are the command line argument passed to rizin (e.g -b 16)
|
||||||
* **CMDS** are the commands to be executed by the test
|
* **CMDS** are the commands to be executed by the test
|
||||||
* **ENVS** (optional) allows to set a custom environment variable (example `FOO=bar`)
|
* **ENVS** (optional) allows to set a custom environment variable (example `FOO=bar`)
|
||||||
|
|
|
||||||
63
test/db/tools/rz_ar
Normal file
63
test/db/tools/rz_ar
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
NAME=rz-ar -h
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=-h
|
||||||
|
REGEXP_FILTER_OUT=(Usage:|Show this help|List matching members|Set output directory \(default \.\)|Quiet mode|Show version information)
|
||||||
|
EXPECT=<<EOF
|
||||||
|
Usage:
|
||||||
|
Show this help
|
||||||
|
List matching members
|
||||||
|
Set output directory (default .)
|
||||||
|
Quiet mode
|
||||||
|
Show version information
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar list fpu.lib
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=-l bins/ar/fpu.lib
|
||||||
|
REGEXP_FILTER_OUT=(FpuXexpY\.obj|FpuTrunc\.obj)
|
||||||
|
EXPECT=<<EOF
|
||||||
|
FpuXexpY.obj
|
||||||
|
FpuTrunc.obj
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar list ucrtd.osmode.lib
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=-l bins/ar/ucrtd.osmode.lib __setusermatherr_stub.obj
|
||||||
|
REGEXP_FILTER_OUT=(__setusermatherr_stub\.obj)
|
||||||
|
EXPECT=<<EOF
|
||||||
|
__setusermatherr_stub.obj
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar list normalized parent path
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=-l bins/ar/ucrtd.osmode.lib __setusermatherr.obj
|
||||||
|
EXPECT=<<EOF
|
||||||
|
d_/os/obj/x86fre/minkernel/crts/ucrt/src/appcrt/dll/not_callable_by_os/objfre/i386/__setusermatherr.obj
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar extract one member
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=-o .tmp/rz-ar bins/ar/fpu.lib FpuXexpY.obj
|
||||||
|
REGEXP_FILTER_OUT=(FpuXexpY\.obj)
|
||||||
|
EXPECT=<<EOF
|
||||||
|
FpuXexpY.obj
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar no matching members
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=bins/ar/fpu.lib not_existing_member.obj
|
||||||
|
EXIT_STATUS=1
|
||||||
|
EXPECT=
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=rz-ar invalid archive
|
||||||
|
TOOL=rz-ar
|
||||||
|
ARGS=bins/elf/analysis/hello-linux-x86_64
|
||||||
|
EXIT_STATUS=1
|
||||||
|
EXPECT=
|
||||||
|
RUN
|
||||||
Loading…
Add table
Add a link
Reference in a new issue