243 lines
7.4 KiB
C
243 lines
7.4 KiB
C
#ifndef RZ_EGG_H
|
|
#define RZ_EGG_H
|
|
|
|
#include <rz_asm.h>
|
|
#include <rz_lib.h>
|
|
#include <rz_util.h>
|
|
#include <rz_syscall.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
RZ_LIB_VERSION_HEADER(rz_egg);
|
|
|
|
#define RZ_EGG_INCDIR_ENV "EGG_INCDIR"
|
|
#define RZ_EGG_INCDIR_PATH "/lib/rizin/" RZ_VERSION "/egg"
|
|
|
|
// rename to RzEggShellcode
|
|
#define RZ_EGG_PLUGIN_SHELLCODE 0
|
|
#define RZ_EGG_PLUGIN_ENCODER 1
|
|
|
|
typedef struct rz_egg_plugin_t {
|
|
const char *name;
|
|
const char *desc;
|
|
int type;
|
|
RzBuffer *(*build)(void *egg);
|
|
} RzEggPlugin;
|
|
|
|
typedef struct rz_egg_lang_t {
|
|
int pushargs;
|
|
int nalias;
|
|
int nsyscalls;
|
|
char *conditionstr;
|
|
char *syscallbody;
|
|
char *includefile;
|
|
char *setenviron;
|
|
char *mathline;
|
|
// used for confusing mathop
|
|
int commentmode;
|
|
int varsize;
|
|
int varxs;
|
|
int lastctxdelta;
|
|
int nargs;
|
|
int docall;
|
|
int nfunctions;
|
|
int nbrackets;
|
|
int slurpin;
|
|
int slurp;
|
|
int line;
|
|
char elem[1024];
|
|
int attsyntax;
|
|
int elem_n;
|
|
char *callname;
|
|
char *endframe;
|
|
char *ctxpush[32];
|
|
char *file;
|
|
char *dstvar;
|
|
char *dstval;
|
|
char *includedir;
|
|
char *ifelse_table[32][32];
|
|
// used to solve if-else problem in a not so ugly way
|
|
int ndstval;
|
|
int skipline; // BOOL
|
|
int quoteline;
|
|
int quotelinevar;
|
|
int stackframe;
|
|
int stackfixed;
|
|
int oc;
|
|
int mode;
|
|
int inlinectr;
|
|
struct {
|
|
char *name;
|
|
char *body;
|
|
// int fastcall; /* TODO: NOT YET USED */
|
|
} inlines[256];
|
|
int ninlines;
|
|
struct {
|
|
char *name;
|
|
char *arg;
|
|
} syscalls[256];
|
|
struct {
|
|
char *name;
|
|
char *content;
|
|
} aliases[256];
|
|
char *nested[32];
|
|
char *nested_callname[32];
|
|
// char *nestede[32] = {0};
|
|
// seems nestede are not used any more
|
|
// (only one place that gives nestede[] value, where could be replaced)
|
|
int nestedi[32];
|
|
} RzEggLang;
|
|
|
|
typedef struct rz_egg_t {
|
|
RzBuffer *src;
|
|
RzBuffer *buf;
|
|
RzBuffer *bin;
|
|
// RzList *shellcodes; // XXX is plugins nao?
|
|
RzAsm *rasm;
|
|
RzSyscall *syscall;
|
|
RzEggLang lang;
|
|
Sdb *db;
|
|
HtSP /*<RzEggPlugin *>*/ *plugins;
|
|
RzList /*<struct egg_patch_t *>*/ *patches; // <RzBuffer>
|
|
RzPath *sys_path; ///< pointer to RzPath, contains path prefix of the system
|
|
struct rz_egg_emit_t *remit;
|
|
int arch;
|
|
int endian;
|
|
int bits;
|
|
ut32 os;
|
|
int context;
|
|
} RzEgg;
|
|
|
|
#define RZ_EGG_OS_LINUX 0x5ca62a43
|
|
#define RZ_EGG_OS_OSX 0x0ad593a1
|
|
#define RZ_EGG_OS_DARWIN 0xd86d1ae2
|
|
#define RZ_EGG_OS_WATCHOS 0x14945c70
|
|
#define RZ_EGG_OS_IOS 0x0ad58830
|
|
#define RZ_EGG_OS_MACOS 0x5cb23c16
|
|
#define RZ_EGG_OS_W32 0x0ad5fbb3
|
|
#define RZ_EGG_OS_WINDOWS 0x05b7de9a
|
|
#define RZ_EGG_OS_BEOS 0x506108be
|
|
#define RZ_EGG_OS_FREEBSD 0x73a72944
|
|
|
|
#if __APPLE__
|
|
#define RZ_EGG_OS_DEFAULT RZ_EGG_OS_OSX
|
|
#define RZ_EGG_OS_NAME "darwin"
|
|
#define RZ_EGG_FORMAT_DEFAULT "mach0"
|
|
#elif __WINDOWS__
|
|
#define RZ_EGG_OS_DEFAULT RZ_EGG_OS_W32
|
|
#define RZ_EGG_OS_NAME "windows"
|
|
#define RZ_EGG_FORMAT_DEFAULT "pe"
|
|
#else
|
|
#define RZ_EGG_OS_DEFAULT RZ_EGG_OS_LINUX
|
|
#define RZ_EGG_OS_NAME "linux"
|
|
#define RZ_EGG_FORMAT_DEFAULT "elf"
|
|
#endif
|
|
|
|
typedef struct rz_egg_emit_t RzEggEmit;
|
|
struct rz_egg_emit_t {
|
|
const char *arch;
|
|
int size; /* in bytes.. 32bit arch is 4, 64bit is 8 .. */
|
|
const char *retvar;
|
|
// const char *syscall_body;
|
|
const char *(*regs)(RzEgg *egg, int idx);
|
|
void (*init)(RzEgg *egg);
|
|
void (*begin)(RzEgg *egg);
|
|
void (*fini)(RzEggEmit *egg_emit);
|
|
void (*call)(RzEgg *egg, const char *addr, int ptr);
|
|
void (*jmp)(RzEgg *egg, const char *addr, int ptr);
|
|
// void (*sc)(int num);
|
|
void (*frame)(RzEgg *egg, int sz);
|
|
char *(*syscall)(RzEgg *egg, int num);
|
|
void (*trap)(RzEgg *egg);
|
|
void (*frame_end)(RzEgg *egg, int sz, int ctx);
|
|
void (*comment)(RzEgg *egg, const char *fmt, ...);
|
|
void (*push_arg)(RzEgg *egg, int xs, int num, const char *str);
|
|
void (*set_string)(RzEgg *egg, const char *dstvar, const char *str, int j);
|
|
void (*equ)(RzEgg *egg, const char *key, const char *value);
|
|
void (*get_result)(RzEgg *egg, const char *ocn);
|
|
void (*restore_stack)(RzEgg *egg, int size);
|
|
void (*syscall_args)(RzEgg *egg, int nargs);
|
|
void (*get_var)(RzEgg *egg, int type, char *out, int idx);
|
|
void (*get_ar)(RzEgg *egg, char *out, int idx);
|
|
void (*while_end)(RzEgg *egg, const char *label);
|
|
void (*load)(RzEgg *egg, const char *str, int sz);
|
|
void (*load_ptr)(RzEgg *egg, const char *str);
|
|
void (*branch)(RzEgg *egg, char *b, char *g, char *e, char *n, int sz, const char *dst);
|
|
void (*mathop)(RzEgg *egg, int ch, int sz, int type, const char *eq, const char *p);
|
|
void (*get_while_end)(RzEgg *egg, char *out, const char *ctxpush, const char *label);
|
|
void *emit_context; ///< May holds the context data of each emit type
|
|
};
|
|
|
|
/**
|
|
* \brief Compare plugins by name (via strcmp).
|
|
*/
|
|
static inline int rz_egg_plugin_cmp(RZ_NULLABLE const RzEggPlugin *a, RZ_NULLABLE const RzEggPlugin *b) {
|
|
if (!a && !b) {
|
|
return 0;
|
|
} else if (!a) {
|
|
return -1;
|
|
} else if (!b) {
|
|
return 1;
|
|
}
|
|
return rz_str_cmp(a->name, b->name, -1);
|
|
}
|
|
|
|
#ifdef RZ_API
|
|
RZ_API RzEgg *rz_egg_new(void);
|
|
RZ_API void rz_egg_lang_init(RzEgg *egg);
|
|
RZ_API void rz_egg_lang_free(RzEgg *egg);
|
|
RZ_API const char *rz_egg_os_as_string(int os);
|
|
RZ_API char *rz_egg_to_string(RzEgg *egg);
|
|
RZ_API void rz_egg_free(RzEgg *egg);
|
|
RZ_API bool rz_egg_plugin_add(RzEgg *a, RZ_NONNULL RzEggPlugin *plugin);
|
|
RZ_API bool rz_egg_plugin_del(RzEgg *a, RZ_NONNULL RzEggPlugin *plugin);
|
|
RZ_API void rz_egg_reset(RzEgg *egg);
|
|
RZ_API bool rz_egg_setup(RzEgg *egg, const char *arch, int bits, int endian, const char *os);
|
|
RZ_API int rz_egg_include(RzEgg *egg, const char *file, int format);
|
|
RZ_API void rz_egg_load(RzEgg *egg, const char *code, int format);
|
|
RZ_API bool rz_egg_load_file(RzEgg *egg, const char *file);
|
|
RZ_API void rz_egg_syscall(RzEgg *egg, const char *arg, ...) RZ_PRINTF_CHECK(2, 3);
|
|
RZ_API void rz_egg_alloc(RzEgg *egg, int n);
|
|
RZ_API void rz_egg_label(RzEgg *egg, const char *name);
|
|
RZ_API int rz_egg_raw(RzEgg *egg, const ut8 *b, int len);
|
|
RZ_API int rz_egg_encode(RZ_NONNULL RZ_BORROW RzEgg *egg, const char *name);
|
|
RZ_API int rz_egg_shellcode(RZ_NONNULL RZ_BORROW RzEgg *egg, const char *name);
|
|
#define rz_egg_get_shellcodes(x) x->plugins
|
|
RZ_API void rz_egg_option_set(RzEgg *egg, const char *k, const char *v);
|
|
RZ_API char *rz_egg_option_get(RzEgg *egg, const char *k);
|
|
RZ_API void rz_egg_if(RzEgg *egg, const char *reg, char cmp, int v);
|
|
RZ_API void rz_egg_printf(RzEgg *egg, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3);
|
|
RZ_API int rz_egg_compile(RzEgg *egg);
|
|
RZ_API int rz_egg_padding(RzEgg *egg, const char *pad);
|
|
RZ_API bool rz_egg_assemble(RzEgg *egg);
|
|
RZ_API bool rz_egg_assemble_asm(RzEgg *egg, char **asm_list);
|
|
RZ_API bool rz_egg_pattern(RzEgg *egg, int size);
|
|
// RZ_API int rz_egg_dump (RzEgg *egg, const char *file) { }
|
|
RZ_API char *rz_egg_get_source(RzEgg *egg);
|
|
RZ_API RzBuffer *rz_egg_get_bin(RzEgg *egg);
|
|
RZ_API char *rz_egg_get_assembly(RzEgg *egg);
|
|
RZ_API void rz_egg_append(RzEgg *egg, const char *src);
|
|
RZ_API int rz_egg_run(RzEgg *egg);
|
|
RZ_API int rz_egg_run_rop(RzEgg *egg);
|
|
RZ_API int rz_egg_patch(RzEgg *egg, int off, const ut8 *b, int l);
|
|
RZ_API bool rz_egg_patch_num(RzEgg *egg, int off, ut64 val, ut32 bits);
|
|
RZ_API void rz_egg_finalize(RzEgg *egg);
|
|
|
|
/* rz_egg_Cfile.c */
|
|
RZ_API RZ_OWN char *rz_egg_compile_c_source(RZ_NONNULL const char *source_file, RZ_NONNULL const char *arch, RZ_NONNULL const char *os, int bits, RZ_BORROW RZ_NONNULL RzPath *sys_path);
|
|
|
|
/* lang.c */
|
|
RZ_API char *rz_egg_mkvar(RzEgg *egg, char *out, const char *_str, int delta);
|
|
RZ_API int rz_egg_lang_parsechar(RzEgg *egg, char c);
|
|
RZ_API void rz_egg_lang_include_path(RzEgg *egg, const char *path);
|
|
RZ_API void rz_egg_lang_include_init(RzEgg *egg);
|
|
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|