1 /* radare2 - LGPL - Copyright 2017-2018 - cgvwzq */ 2 3 #include <r_types.h> 4 #include <r_util.h> 5 #include <r_lib.h> 6 #include <r_bin.h> 7 8 #ifndef _INCLUDE_WASM_H_ 9 #define _INCLUDE_WASM_H_ 10 11 // version 0x1 (WIP) 12 // https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md 13 14 #define R_BIN_WASM_MAGIC_BYTES "\x00" \ 15 "asm" 16 #define R_BIN_WASM_VERSION 0x1 17 #define R_BIN_WASM_STRING_LENGTH 256 18 #define R_BIN_WASM_END_OF_CODE 0xb 19 20 #define R_BIN_WASM_SECTION_CUSTOM 0x0 21 #define R_BIN_WASM_SECTION_TYPE 0x1 22 #define R_BIN_WASM_SECTION_IMPORT 0x2 23 #define R_BIN_WASM_SECTION_FUNCTION 0x3 24 #define R_BIN_WASM_SECTION_TABLE 0x4 25 #define R_BIN_WASM_SECTION_MEMORY 0x5 26 #define R_BIN_WASM_SECTION_GLOBAL 0x6 27 #define R_BIN_WASM_SECTION_EXPORT 0x7 28 #define R_BIN_WASM_SECTION_START 0x8 29 #define R_BIN_WASM_SECTION_ELEMENT 0x9 30 #define R_BIN_WASM_SECTION_CODE 0xa 31 #define R_BIN_WASM_SECTION_DATA 0xb 32 33 typedef enum { 34 R_BIN_WASM_VALUETYPE_i32 = 0x1, 35 R_BIN_WASM_VALUETYPE_i64 = 0x2, 36 R_BIN_WASM_VALUETYPE_f32 = 0x3, 37 R_BIN_WASM_VALUETYPE_f64 = 0x4, 38 R_BIN_WASM_VALUETYPE_v128 = 0x5, 39 R_BIN_WASM_VALUETYPE_ANYFUNC = 0x10, 40 R_BIN_WASM_VALUETYPE_FUNC = 0x20, 41 R_BIN_WASM_VALUETYPE_EMPTY = 0x40, 42 } r_bin_wasm_value_type_t; 43 44 typedef enum { 45 R_BIN_WASM_EXTERNALKIND_Function = 0x0, 46 R_BIN_WASM_EXTERNALKIND_Table = 0x1, 47 R_BIN_WASM_EXTERNALKIND_Memory = 0x2, 48 R_BIN_WASM_EXTERNALKIND_Global = 0x3, 49 } r_bin_wasm_external_kind_t; 50 51 typedef enum { 52 R_BIN_WASM_NAMETYPE_Module = 0x0, 53 R_BIN_WASM_NAMETYPE_Function = 0x1, 54 R_BIN_WASM_NAMETYPE_Local = 0x2, 55 } r_bin_wasm_custom_name_type_t; 56 57 struct r_bin_wasm_init_expr_t { 58 // bytecode terminated in 0xb 59 size_t len; 60 }; 61 62 struct r_bin_wasm_resizable_limits_t { 63 ut8 flags; // 1 if max field is present, 0 otherwise 64 ut32 initial; 65 ut32 maximum; 66 }; 67 68 typedef struct r_bin_wasm_name_t { 69 ut32 len; 70 ut8 *name; 71 } RBinWasmName; 72 73 typedef struct r_bin_wasm_section_t { 74 ut8 id; 75 ut32 size; 76 ut32 name_len; 77 char *name; 78 ut32 offset; 79 ut32 payload_data; 80 ut32 payload_len; 81 ut32 count; 82 } RBinWasmSection; 83 84 typedef struct r_bin_wasm_type_t { 85 ut8 form; 86 ut32 param_count; 87 r_bin_wasm_value_type_t *param_types; 88 st8 return_count; // MVP = 1 89 r_bin_wasm_value_type_t return_type; 90 char to_str[R_BIN_WASM_STRING_LENGTH]; 91 } RBinWasmTypeEntry; 92 93 // Other Types 94 struct r_bin_wasm_global_type_t { 95 r_bin_wasm_value_type_t content_type; 96 ut8 mutability; 97 }; 98 99 struct r_bin_wasm_table_type_t { 100 r_bin_wasm_value_type_t elem_type; 101 struct r_bin_wasm_resizable_limits_t limits; 102 }; 103 104 struct r_bin_wasm_memory_type_t { 105 struct r_bin_wasm_resizable_limits_t limits; 106 }; 107 108 typedef struct r_bin_wasm_import_t { 109 ut32 module_len; 110 char module_str[R_BIN_WASM_STRING_LENGTH]; 111 ut32 field_len; 112 char field_str[R_BIN_WASM_STRING_LENGTH]; 113 ut8 kind; 114 union { 115 ut32 type_f; 116 struct r_bin_wasm_global_type_t type_g; 117 struct r_bin_wasm_table_type_t type_t; 118 struct r_bin_wasm_memory_type_t type_m; 119 }; 120 121 } RBinWasmImportEntry; 122 123 typedef struct r_bin_wasm_function_t { 124 ut32 type_index; // index to Type entries 125 } RBinWasmFunctionEntry; 126 127 typedef struct r_bin_wasm_table_t { 128 ut8 element_type; // only anyfunc 129 struct r_bin_wasm_resizable_limits_t limits; 130 } RBinWasmTableEntry; 131 132 typedef struct r_bin_wasm_memory_t { 133 struct r_bin_wasm_resizable_limits_t limits; 134 } RBinWasmMemoryEntry; 135 136 typedef struct r_bin_wasm_global_t { 137 r_bin_wasm_value_type_t content_type; 138 ut8 mutability; // 0 if immutable, 1 if mutable 139 struct r_bin_wasm_init_expr_t init; 140 } RBinWasmGlobalEntry; 141 142 typedef struct r_bin_wasm_export_t { 143 ut32 field_len; 144 char field_str[R_BIN_WASM_STRING_LENGTH]; 145 ut8 kind; 146 ut32 index; 147 } RBinWasmExportEntry; 148 149 typedef struct r_bin_wasm_start_t { 150 ut32 index; 151 } RBinWasmStartEntry; 152 153 struct r_bin_wasm_local_entry_t { 154 ut32 count; 155 r_bin_wasm_value_type_t type; 156 }; 157 158 typedef struct r_bin_wasm_element_t { 159 ut32 index; 160 struct r_bin_wasm_init_expr_t init; 161 ut32 num_elem; 162 ut32 elems[]; 163 } RBinWasmElementEntry; 164 165 typedef struct r_bin_wasm_code_t { 166 ut32 body_size; 167 ut32 local_count; // numer of local entries 168 struct r_bin_wasm_local_entry_t *locals; 169 ut32 code; // offset 170 ut32 len; // real bytecode length 171 ut8 byte; // 0xb, indicating end of the body 172 char *name; 173 char *signature; 174 } RBinWasmCodeEntry; 175 176 typedef struct r_bin_wasm_data_t { 177 ut32 index; // linear memory index (0 in MVP) 178 struct r_bin_wasm_init_expr_t offset; // bytecode evaluated at runtime 179 ut32 size; 180 ut32 data; // offset 181 } RBinWasmDataEntry; 182 183 // TODO: custom sections 184 185 186 typedef struct r_bin_wasm_custom_name_function_names_t { 187 ut32 count; 188 RIDStorage *names; 189 } RBinWasmCustomNameFunctionNames; 190 191 typedef struct r_bin_wasm_custom_name_local_name_t { 192 ut32 index; // function index 193 194 ut32 names_count; 195 RIDStorage *names; // local names 196 } RBinWasmCustomNameLocalName; 197 198 typedef struct r_bin_wasm_custom_name_local_names_t { 199 ut32 count; 200 RList *locals; // RBinWasmCustomNameLocalName 201 } RBinWasmCustomNameLocalNames; 202 203 // "name" section entry 204 typedef struct r_bin_wasm_custom_name_entry_t { 205 ut8 type; 206 ut32 size; 207 208 ut8 payload_data; 209 union { 210 struct r_bin_wasm_name_t* mod_name; 211 RBinWasmCustomNameFunctionNames *func; 212 RBinWasmCustomNameLocalNames *local; 213 }; 214 } RBinWasmCustomNameEntry; 215 216 typedef struct r_bin_wasm_obj_t { 217 218 RBuffer *buf; 219 size_t size; 220 221 ut32 entrypoint; 222 223 // cache purposes 224 RList *g_sections; 225 RList *g_types; 226 RList *g_imports; 227 RList *g_exports; 228 RList *g_tables; 229 RList *g_memories; 230 RList *g_globals; 231 RList *g_elements; 232 RList *g_codes; 233 RList *g_datas; 234 RBinWasmStartEntry *g_start; 235 236 RList *g_names; 237 // etc... 238 239 } RBinWasmObj; 240 241 RBinWasmObj *r_bin_wasm_init(RBinFile *bf, RBuffer *buf); 242 void r_bin_wasm_destroy(RBinFile *bf); 243 RList *r_bin_wasm_get_sections(RBinWasmObj *bin); 244 RList *r_bin_wasm_get_types(RBinWasmObj *bin); 245 RList *r_bin_wasm_get_imports(RBinWasmObj *bin); 246 RList *r_bin_wasm_get_exports(RBinWasmObj *bin); 247 RList *r_bin_wasm_get_tables(RBinWasmObj *bin); 248 RList *r_bin_wasm_get_memories(RBinWasmObj *bin); 249 RList *r_bin_wasm_get_globals(RBinWasmObj *bin); 250 RList *r_bin_wasm_get_elements(RBinWasmObj *bin); 251 RList *r_bin_wasm_get_codes(RBinWasmObj *bin); 252 RList *r_bin_wasm_get_datas(RBinWasmObj *bin); 253 RList *r_bin_wasm_get_custom_names(RBinWasmObj *bin); 254 ut32 r_bin_wasm_get_entrypoint(RBinWasmObj *bin); 255 const char *r_bin_wasm_get_function_name(RBinWasmObj *bin, ut32 idx); 256 const char *r_bin_wasm_valuetype_to_string(r_bin_wasm_value_type_t type); 257 258 #endif 259