Add webassembly arch (#1359)

* add wasm arch

* fix bug

* delete todo & add wasm into readme
This commit is contained in:
Spike 2019-02-01 23:03:47 +08:00 committed by Nguyen Anh Quynh
parent 098b1402a3
commit 4ae8645b43
44 changed files with 2184 additions and 77 deletions

2
.gitignore vendored
View File

@ -68,6 +68,7 @@ tests/test_m68k
tests/test_tms320c64x
tests/test_m680x
tests/test_evm
tests/test_wasm
tests/test_mos65xx
# regress binaries
@ -98,6 +99,7 @@ build*/
*.backup
*.VC.db
*.VC.opendb
.vscode/
# CMake build directories
build*/

View File

@ -28,8 +28,8 @@ option(CAPSTONE_BUILD_TESTS "Build tests" ON)
option(CAPSTONE_BUILD_CSTOOL "Build cstool" ON)
option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON)
set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX)
set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX)
set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM)
set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM)
list(LENGTH SUPPORTED_ARCHITECTURES count)
math(EXPR count "${count}-1")
@ -49,6 +49,7 @@ foreach(supported_architecture ${SUPPORTED_ARCHITECTURES})
endif()
endforeach(supported_architecture)
option(CAPSTONE_X86_ONLY "Enable just x86, and disable building every other architectures" OFF)
option(CAPSTONE_X86_REDUCE "x86 with reduce instruction sets to minimize library" OFF)
option(CAPSTONE_X86_ATT_DISABLE "Disable x86 AT&T syntax" OFF)
option(CAPSTONE_OSXKERNEL_SUPPORT "Support to embed Capstone into OS X Kernel extensions" OFF)
@ -103,6 +104,7 @@ set(HEADERS_COMMON
include/capstone/arm.h
include/capstone/capstone.h
include/capstone/evm.h
include/capstone/wasm.h
include/capstone/mips.h
include/capstone/ppc.h
include/capstone/x86.h
@ -119,7 +121,7 @@ set(HEADERS_COMMON
set(TEST_SOURCES test_basic.c test_detail.c test_skipdata.c test_iter.c)
## architecture support
if (CAPSTONE_ARM_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_ARM_SUPPORT)
add_definitions(-DCAPSTONE_HAS_ARM)
set(SOURCES_ARM
arch/ARM/ARMDisassembler.c
@ -156,7 +158,7 @@ if (CAPSTONE_ARM_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_arm.c)
endif ()
if (CAPSTONE_ARM64_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_ARM64_SUPPORT)
add_definitions(-DCAPSTONE_HAS_ARM64)
set(SOURCES_ARM64
arch/AArch64/AArch64BaseInfo.c
@ -193,7 +195,7 @@ if (CAPSTONE_ARM64_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_arm64.c)
endif ()
if (CAPSTONE_MIPS_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_MIPS_SUPPORT)
add_definitions(-DCAPSTONE_HAS_MIPS)
set(SOURCES_MIPS
arch/Mips/MipsDisassembler.c
@ -225,7 +227,7 @@ if (CAPSTONE_MIPS_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_mips.c)
endif ()
if (CAPSTONE_PPC_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_PPC_SUPPORT)
add_definitions(-DCAPSTONE_HAS_POWERPC)
set(SOURCES_PPC
arch/PowerPC/PPCDisassembler.c
@ -312,7 +314,7 @@ if (CAPSTONE_X86_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_x86.c test_customized_mnem.c)
endif ()
if (CAPSTONE_SPARC_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_SPARC_SUPPORT)
add_definitions(-DCAPSTONE_HAS_SPARC)
set(SOURCES_SPARC
arch/Sparc/SparcDisassembler.c
@ -335,7 +337,7 @@ if (CAPSTONE_SPARC_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_sparc.c)
endif ()
if (CAPSTONE_SYSZ_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_SYSZ_SUPPORT)
add_definitions(-DCAPSTONE_HAS_SYSZ)
set(SOURCES_SYSZ
arch/SystemZ/SystemZDisassembler.c
@ -360,7 +362,7 @@ if (CAPSTONE_SYSZ_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_systemz.c)
endif ()
if (CAPSTONE_XCORE_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_XCORE_SUPPORT)
add_definitions(-DCAPSTONE_HAS_XCORE)
set(SOURCES_XCORE
arch/XCore/XCoreDisassembler.c
@ -381,7 +383,7 @@ if (CAPSTONE_XCORE_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_xcore.c)
endif ()
if (CAPSTONE_M68K_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_M68K_SUPPORT)
add_definitions(-DCAPSTONE_HAS_M68K)
set(SOURCES_M68K
arch/M68K/M68KDisassembler.c
@ -394,7 +396,7 @@ if (CAPSTONE_M68K_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_m68k.c)
endif ()
if (CAPSTONE_TMS320C64X_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_TMS320C64X_SUPPORT)
add_definitions(-DCAPSTONE_HAS_TMS320C64X)
set(SOURCES_TMS320C64X
arch/TMS320C64x/TMS320C64xDisassembler.c
@ -414,7 +416,7 @@ if (CAPSTONE_TMS320C64X_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_tms320c64x.c)
endif ()
if (CAPSTONE_M680X_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_M680X_SUPPORT)
add_definitions(-DCAPSTONE_HAS_M680X)
set(SOURCES_M680X
arch/M680X/M680XDisassembler.c
@ -429,7 +431,7 @@ if (CAPSTONE_M680X_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_m680x.c)
endif ()
if (CAPSTONE_EVM_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_EVM_SUPPORT)
add_definitions(-DCAPSTONE_HAS_EVM)
set(SOURCES_EVM
arch/EVM/EVMDisassembler.c
@ -446,7 +448,23 @@ if (CAPSTONE_EVM_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_evm.c)
endif ()
if (CAPSTONE_MOS65XX_SUPPORT)
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_WASM_SUPPORT)
add_definitions(-DCAPSTONE_HAS_WASM)
set(SOURCES_WASM
arch/WASM/WASMDisassembler.c
arch/WASM/WASMInstPrinter.c
arch/WASM/WASMMapping.c
arch/WASM/WASMModule.c
)
set(HEADERS_WASM
arch/WASM/WASMDisassembler.h
arch/WASM/WASMInstPrinter.h
arch/WASM/WASMMapping.h
)
set(TEST_SOURCES ${TEST_SOURCES} test_wasm.c)
endif ()
if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_MOS65XX_SUPPORT)
add_definitions(-DCAPSTONE_HAS_MOS65XX)
set(SOURCES_MOS65XX
arch/MOS65XX/MOS65XXModule.c
@ -475,6 +493,7 @@ set(ALL_SOURCES
${SOURCES_TMS320C64X}
${SOURCES_M680X}
${SOURCES_EVM}
${SOURCES_WASM}
${SOURCES_MOS65XX}
)
@ -493,6 +512,7 @@ set(ALL_HEADERS
${HEADERS_TMS320C64X}
${HEADERS_M680X}
${HEADERS_EVM}
${HEADERS_WASM}
${HEADERS_MOS65XX}
)
@ -574,6 +594,7 @@ source_group("Source\\M68K" FILES ${SOURCES_M68K})
source_group("Source\\TMS320C64x" FILES ${SOURCES_TMS320C64X})
source_group("Source\\M680X" FILES ${SOURCES_M680X})
source_group("Source\\EVM" FILES ${SOURCES_EVM})
source_group("Source\\WASM" FILES ${SOURCES_WASM})
source_group("Source\\MOS65XX" FILES ${SOURCES_MOS65XX})
source_group("Include\\Common" FILES ${HEADERS_COMMON})
@ -590,6 +611,7 @@ source_group("Include\\M68K" FILES ${HEADERS_M68K})
source_group("Include\\TMS320C64x" FILES ${HEADERS_TMS320C64X})
source_group("Include\\M680X" FILES ${HEADERS_MC680X})
source_group("Include\\EVM" FILES ${HEADERS_EVM})
source_group("Include\\WASM" FILES ${HEADERS_WASM})
source_group("Include\\MOS65XX" FILES ${HEADERS_MOS65XX})
### test library 64bit routine:

View File

@ -87,6 +87,7 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
/usr/include/capstone/arm.h
/usr/include/capstone/arm64.h
/usr/include/capstone/evm.h
/usr/include/capstone/wasm.h
/usr/include/capstone/m68k.h
/usr/include/capstone/m680x.h
/usr/include/capstone/mips.h

View File

@ -77,5 +77,6 @@ Fotis Loukos: TMS320C64x architecture.
Wolfgang Schwotzer: M680X architecture.
Philippe Antoine: Integration with oss-fuzz and various fixes.
Stephen Eckels (stevemk14ebr): x86 encoding features
Tong Yu(Spike) & Kai Jern, Lau (xwings): WASM architecture.
Sebastian Macke: MOS65XX architecture
Ilya Leoshkevich: SystemZ architecture improvements.

View File

@ -49,3 +49,45 @@ the bindings coming with the core to avoid potential incompatibility issue
with older versions.
See bindings/<language>/README for detail instructions on how to compile &
install the bindings.
Adding an architecture :
Obviously, you first need to write all the logic and put it in a new directory arch/newarch
Then, you have to modify other files.
(You can look for one architecture such as EVM in these files to get what you need to do)
Integrate :
- cs.c
- cstool/cstool.c
- cstool/cstool_newarch.c : print the architecture specific details
- include/capstone/capstone.h
- include/capstone/newarch.h : create this file to export all specifics about the new architecture
Compile :
- CMakeLists.txt
- Makefile
- config.mk
Tests :
- tests/Makefile
- tests/test_basic.c
- tests/test_detail.c
- tests/test_iter.c
- tests/test_newarch.c
- suite/fuzz/fuzz_disasm.c : add the architecture and its modes to the list of fuzzed platforms
Bindings :
- bindings/Makefile
- bindings/const_generator.py : add the header file and the architecture
- bindings/python/Makefile
- bindings/python/capstone/__init__.py
- bindings/python/capstone/newarch.py : define the python structures
- bindings/python/capstone/newarch_const.py : generate this file
- bindings/python/test_newarch.py : create a basic decoding test
- bindings/python/test_all.py
Docs :
- README.md
- HACK.txt
- CREDITS.txt : add your name

View File

@ -32,6 +32,7 @@ void MCInst_Init(MCInst *inst)
inst->ac_idx = 0;
inst->popcode_adjust = 0;
inst->assembly[0] = '\0';
inst->wasm_data.type = WASM_OP_INVALID;
}
void MCInst_clear(MCInst *inst)

View File

@ -108,6 +108,7 @@ struct MCInst {
uint8_t popcode_adjust; // Pseudo X86 instruction adjust
char assembly[8]; // for special instruction, so that we dont need printer
unsigned char evm_data[32]; // for EVM PUSH operand
cs_wasm_op wasm_data; // for WASM operand
};
void MCInst_Init(MCInst *inst);

View File

@ -249,6 +249,16 @@ ifneq (,$(findstring evm,$(CAPSTONE_ARCHS)))
LIBOBJ_EVM += $(LIBSRC_EVM:%.c=$(OBJDIR)/%.o)
endif
DEP_WASM =
DEP_WASM += $(wildcard arch/WASM/WASM*.inc)
LIBOBJ_WASM =
ifneq (,$(findstring wasm,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_WASM
LIBSRC_WASM += $(wildcard arch/WASM/WASM*.c)
LIBOBJ_WASM += $(LIBSRC_WASM:%.c=$(OBJDIR)/%.o)
endif
DEP_MOS65XX =
DEP_MOS65XX += $(wildcard arch/MOS65XX/MOS65XX*.inc)
@ -264,7 +274,7 @@ endif
LIBOBJ =
LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ)
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX)
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM)
LIBOBJ += $(OBJDIR)/MCInst.o
@ -393,6 +403,7 @@ $(LIBOBJ_XCORE): $(DEP_XCORE)
$(LIBOBJ_TMS320C64X): $(DEP_TMS320C64X)
$(LIBOBJ_M680X): $(DEP_M680X)
$(LIBOBJ_EVM): $(DEP_EVM)
$(LIBOBJ_WASM): $(DEP_WASM)
$(LIBOBJ_MOS65XX): $(DEP_MOS65XX)
ifeq ($(CAPSTONE_STATIC),yes)
@ -469,12 +480,12 @@ dist:
TESTS = test_basic test_detail test_arm test_arm64 test_m68k test_mips test_ppc test_sparc
TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_mos65xx
TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_mos65xx test_wasm
TESTS += test_basic.static test_detail.static test_arm.static test_arm64.static
TESTS += test_m68k.static test_mips.static test_ppc.static test_sparc.static
TESTS += test_systemz.static test_x86.static test_xcore.static test_m680x.static
TESTS += test_skipdata test_skipdata.static test_iter.static test_evm.static
TESTS += test_mos65xx.static
TESTS += test_mos65xx.static test_wasm.static
check: $(TESTS) fuzztest fuzzallcorp
test_%:
./tests/$@ > /dev/null && echo OK || echo FAILED

View File

@ -10,7 +10,7 @@ disasm engine for binary analysis and reversing in the security community.
Created by Nguyen Anh Quynh, then developed and maintained by a small community,
Capstone offers some unparalleled features:
- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Ethereum VM, M68K,
- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Ethereum VM, Webassembly, M68K,
Mips, MOS65XX, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore and X86 (including X86_64).
- Having clean/simple/lightweight/intuitive architecture-neutral API.

View File

@ -1,3 +1,12 @@
* Version 4.0.1 - January 10th, 2019
Release 4.0.1 was sponsored by the following companies (in no particular order).
- NowSecure: https://www.nowsecure.com
- Verichains: https://verichains.io
- Vsec: https://vsec.com.vn
-----------------------------------
* Version 4.0 - December 18th, 2018
Capstone 4.0 version marks 5 years of the project!

View File

@ -66,8 +66,7 @@ void printInt64Bang(SStream *O, int64_t val)
SStream_concat(O, "#-0x%"PRIx64, (uint64_t)val);
else
SStream_concat(O, "#-0x%"PRIx64, (uint64_t)-val);
}
else
} else
SStream_concat(O, "#-%"PRIu64, -val);
}
}
@ -94,8 +93,7 @@ void printInt64(SStream *O, int64_t val)
SStream_concat(O, "-0x%"PRIx64, (uint64_t)val);
else
SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val);
}
else
} else
SStream_concat(O, "-%"PRIu64, -val);
}
}
@ -105,11 +103,12 @@ void printInt32BangDec(SStream *O, int32_t val)
{
if (val >= 0)
SStream_concat(O, "#%u", val);
else
else {
if (val == INT_MIN)
SStream_concat(O, "#-%u", val);
else
SStream_concat(O, "#-%u", (uint32_t)-val);
}
}
void printInt32Bang(SStream *O, int32_t val)
@ -125,8 +124,7 @@ void printInt32Bang(SStream *O, int32_t val)
SStream_concat(O, "#-0x%x", (uint32_t)val);
else
SStream_concat(O, "#-0x%x", (uint32_t)-val);
}
else
} else
SStream_concat(O, "#-%u", -val);
}
}
@ -144,8 +142,7 @@ void printInt32(SStream *O, int32_t val)
SStream_concat(O, "-0x%x", (uint32_t)val);
else
SStream_concat(O, "-0x%x", (uint32_t)-val);
}
else
} else
SStream_concat(O, "-%u", -val);
}
}
@ -165,24 +162,3 @@ void printUInt32(SStream *O, uint32_t val)
else
SStream_concat(O, "%u", val);
}
/*
int main()
{
SStream ss;
int64_t i;
SStream_Init(&ss);
SStream_concat(&ss, "hello ");
SStream_concat(&ss, "%d - 0x%x", 200, 16);
i = 123;
SStream_concat(&ss, " + %ld", i);
SStream_concat(&ss, "%s", "haaaaa");
printf("%s\n", ss.buffer);
return 0;
}
*/

1041
arch/WASM/WASMDisassembler.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#ifndef CS_WASMDISASSEMBLER_H
#define CS_WASMDISASSEMBLER_H
#include "../../MCInst.h"
bool WASM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address, void *info);
#endif

View File

@ -0,0 +1,57 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#include "WASMInstPrinter.h"
#include "WASMMapping.h"
void WASM_printInst(MCInst *MI, struct SStream *O, void *PrinterInfo)
{
int i;
SStream_concat(O, WASM_insn_name((csh)MI->csh, MI->Opcode));
switch (MI->wasm_data.type) {
default:
break;
case WASM_OP_VARUINT32:
SStream_concat(O, "\t0x%x", MI->wasm_data.varuint32);
break;
case WASM_OP_VARUINT64:
SStream_concat(O, "\t0x%lx", MI->wasm_data.varuint64);
break;
case WASM_OP_UINT32:
SStream_concat(O, "\t0x%2" PRIx32, MI->wasm_data.uint32);
break;
case WASM_OP_UINT64:
SStream_concat(O, "\t0x%2" PRIx64, MI->wasm_data.uint64);
break;
case WASM_OP_IMM:
SStream_concat(O, "\t0x%x, 0x%x", MI->wasm_data.immediate[0], MI->wasm_data.immediate[1]);
break;
case WASM_OP_INT7:
SStream_concat(O, "\t%d", MI->wasm_data.int7);
break;
case WASM_OP_BRTABLE:
SStream_concat(O, "\t0x%x, [", MI->wasm_data.brtable.length);
for (i = 0; i < MI->wasm_data.brtable.length; i++) {
if (i == 0) {
SStream_concat(O, "0x%x", MI->wasm_data.brtable.target[i]);
} else {
SStream_concat(O, ",0x%x", MI->wasm_data.brtable.target[i]);
}
}
SStream_concat(O, "], 0x%x", MI->wasm_data.brtable.default_target);
cs_mem_free(MI->wasm_data.brtable.target);
break;
}
}

View File

@ -0,0 +1,18 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#ifndef CS_WASMINSTPRINTER_H
#define CS_WASMINSTPRINTER_H
#include "capstone/capstone.h"
#include "../../MCInst.h"
#include "../../SStream.h"
#include "../../cs_priv.h"
struct SStream;
void WASM_printInst(MCInst *MI, struct SStream *O, void *Info);
void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
#endif

333
arch/WASM/WASMMapping.c Normal file
View File

@ -0,0 +1,333 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#ifdef CAPSTONE_HAS_WASM
#include <string.h>
#include "../../cs_priv.h"
#include "../../utils.h"
#include "WASMMapping.h"
// fill in details
void WASM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{
insn->id = id;
}
#ifndef CAPSTONE_DIET
static name_map insn_name_maps[256] = {
{ WASM_INS_UNREACHABLE, "unreachable" },
{ WASM_INS_NOP, "nop" },
{ WASM_INS_BLOCK, "block" },
{ WASM_INS_LOOP, "loop" },
{ WASM_INS_IF, "if" },
{ WASM_INS_ELSE, "else" },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_END, "end" },
{ WASM_INS_BR, "br" },
{ WASM_INS_BR_IF, "br_if" },
{ WASM_INS_BR_TABLE, "br_table" },
{ WASM_INS_RETURN, "return" },
{ WASM_INS_CALL, "call" },
{ WASM_INS_CALL_INDIRECT, "call_indirect" },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_DROP, "drop" },
{ WASM_INS_SELECT, "select" },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_GET_LOCAL, "get_local" },
{ WASM_INS_SET_LOCAL, "set_local" },
{ WASM_INS_TEE_LOCAL, "tee_local" },
{ WASM_INS_GET_GLOBAL, "get_global" },
{ WASM_INS_SET_GLOBAL, "set_global" },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_I32_LOAD, "i32.load" },
{ WASM_INS_I64_LOAD, "i64.load" },
{ WASM_INS_F32_LOAD, "f32.load" },
{ WASM_INS_F64_LOAD, "f64.load" },
{ WASM_INS_I32_LOAD8_S, "i32.load8_s" },
{ WASM_INS_I32_LOAD8_U, "i32.load8_u" },
{ WASM_INS_I32_LOAD16_S, "i32.load16_s" },
{ WASM_INS_I32_LOAD16_U, "i32.load16_u" },
{ WASM_INS_I64_LOAD8_S, "i64.load8_s" },
{ WASM_INS_I64_LOAD8_U, "i64.load8_u" },
{ WASM_INS_I64_LOAD16_S, "i64.load16_s" },
{ WASM_INS_I64_LOAD16_U, "i64.load16_u"},
{ WASM_INS_I64_LOAD32_S, "i64.load32_s"},
{ WASM_INS_I64_LOAD32_U, "i64.load32_u" },
{ WASM_INS_I32_STORE, "i32.store" },
{ WASM_INS_I64_STORE, "i64.store" },
{ WASM_INS_F32_STORE, "f32.store" },
{ WASM_INS_F64_STORE, "f64.store" },
{ WASM_INS_I32_STORE8, "i32.store8" },
{ WASM_INS_I32_STORE16, "i32.store16" },
{ WASM_INS_I64_STORE8, "i64.store8" },
{ WASM_INS_I64_STORE16, "i64.store16" },
{ WASM_INS_I64_STORE32, "i64.store32" },
{ WASM_INS_CURRENT_MEMORY, "current_memory" },
{ WASM_INS_GROW_MEMORY, "grow_memory" },
{ WASM_INS_I32_CONST, "i32.const" },
{ WASM_INS_I64_CONST, "i64.const" },
{ WASM_INS_F32_CONST, "f32.const" },
{ WASM_INS_F64_CONST, "f64.const" },
{ WASM_INS_I32_EQZ, "i32.eqz" },
{ WASM_INS_I32_EQ, "i32.eq" },
{ WASM_INS_I32_NE, "i32.ne" },
{ WASM_INS_I32_LT_S, "i32.lt_s" },
{ WASM_INS_I32_LT_U, "i32.lt_u" },
{ WASM_INS_I32_GT_S, "i32.gt_s" },
{ WASM_INS_I32_GT_U, "i32.gt_u" },
{ WASM_INS_I32_LE_S, "i32.le_s" },
{ WASM_INS_I32_LE_U, "i32.le_u" },
{ WASM_INS_I32_GE_S, "i32.ge_s" },
{ WASM_INS_I32_GE_U, "i32.ge_u" },
{ WASM_INS_I64_EQZ, "i64.eqz" },
{ WASM_INS_I64_EQ, "i64.eq" },
{ WASM_INS_I64_NE, "i64.ne" },
{ WASM_INS_I64_LT_S, "i64.lt_s" },
{ WASM_INS_I64_LT_U, "i64.lt_u" },
{ WASN_INS_I64_GT_S, "i64.gt_s" },
{ WASM_INS_I64_GT_U, "i64.gt_u" },
{ WASM_INS_I64_LE_S, "i64.le_s" },
{ WASM_INS_I64_LE_U, "i64.le_u" },
{ WASM_INS_I64_GE_S, "i64.ge_s" },
{ WASM_INS_I64_GE_U, "i64.ge_u" },
{ WASM_INS_F32_EQ, "f32.eq" },
{ WASM_INS_F32_NE, "f32.ne" },
{ WASM_INS_F32_LT, "f32.lt" },
{ WASM_INS_F32_GT, "f32.gt" },
{ WASM_INS_F32_LE, "f32.le" },
{ WASM_INS_F32_GE, "f32.ge" },
{ WASM_INS_F64_EQ, "f64.eq" },
{ WASM_INS_F64_NE, "f64.ne" },
{ WASM_INS_F64_LT, "f64.lt" },
{ WASM_INS_F64_GT, "f64.gt" },
{ WASM_INS_F64_LE, "f64.le" },
{ WASM_INS_F64_GE, "f64.ge" },
{ WASM_INS_I32_CLZ, "i32.clz" },
{ WASM_INS_I32_CTZ, "i32.ctz" },
{ WASM_INS_I32_POPCNT, "i32.popcnt" },
{ WASM_INS_I32_ADD, "i32.add" },
{ WASM_INS_I32_SUB, "i32.sub" },
{ WASM_INS_I32_MUL, "i32.mul" },
{ WASM_INS_I32_DIV_S, "i32.div_s" },
{ WASM_INS_I32_DIV_U, "i32.div_u" },
{ WASM_INS_I32_REM_S, "i32.rem_s" },
{ WASM_INS_I32_REM_U, "i32.rem_u" },
{ WASM_INS_I32_AND, "i32.and" },
{ WASM_INS_I32_OR, "i32.or" },
{ WASM_INS_I32_XOR, "i32.xor" },
{ WASM_INS_I32_SHL, "i32.shl" },
{ WASM_INS_I32_SHR_S, "i32.shr_s" },
{ WASM_INS_I32_SHR_U, "i32.shr_u" },
{ WASM_INS_I32_ROTL, "i32.rotl" },
{ WASM_INS_I32_ROTR, "i32.rotr" },
{ WASM_INS_I64_CLZ, "i64.clz" },
{ WASM_INS_I64_CTZ, "i64.ctz" },
{ WASM_INS_I64_POPCNT, "i64.popcnt" },
{ WASM_INS_I64_ADD, "i64.add" },
{ WASM_INS_I64_SUB, "i64.sub" },
{ WASM_INS_I64_MUL, "i64.mul" },
{ WASM_INS_I64_DIV_S, "i64.div_s" },
{ WASM_INS_I64_DIV_U, "i64.div_u" },
{ WASM_INS_I64_REM_S, "i64.rem_s" },
{ WASM_INS_I64_REM_U, "i64.rem_u" },
{ WASM_INS_I64_AND, "i64.and" },
{ WASM_INS_I64_OR, "i64.or" },
{ WASM_INS_I64_XOR, "i64.xor" },
{ WASM_INS_I64_SHL, "i64.shl" },
{ WASM_INS_I64_SHR_S, "i64.shr_s" },
{ WASM_INS_I64_SHR_U, "i64.shr_u" },
{ WASM_INS_I64_ROTL, "i64.rotl" },
{ WASM_INS_I64_ROTR, "i64.rotr" },
{ WASM_INS_F32_ABS, "f32.abs" },
{ WASM_INS_F32_NEG, "f32.neg" },
{ WASM_INS_F32_CEIL, "f32.ceil" },
{ WASM_INS_F32_FLOOR, "f32.floor" },
{ WASM_INS_F32_TRUNC, "f32.trunc" },
{ WASM_INS_F32_NEAREST, "f32.nearest" },
{ WASM_INS_F32_SQRT, "f32.sqrt" },
{ WASM_INS_F32_ADD, "f32.add" },
{ WASM_INS_F32_SUB, "f32.sub" },
{ WASM_INS_F32_MUL, "f32.mul" },
{ WASM_INS_F32_DIV, "f32.div" },
{ WASM_INS_F32_MIN, "f32.min" },
{ WASM_INS_F32_MAX, "f32.max" },
{ WASM_INS_F32_COPYSIGN, "f32.copysign" },
{ WASM_INS_F64_ABS, "f64.abs" },
{ WASM_INS_F64_NEG, "f64.neg" },
{ WASM_INS_F64_CEIL, "f64.ceil" },
{ WASM_INS_F64_FLOOR, "f64.floor" },
{ WASM_INS_F64_TRUNC, "f64.trunc" },
{ WASM_INS_F64_NEAREST, "f64.nearest" },
{ WASM_INS_F64_SQRT, "f64.sqrt" },
{ WASM_INS_F64_ADD, "f64.add" },
{ WASM_INS_F64_SUB, "f64.sub" },
{ WASM_INS_F64_MUL, "f64.mul" },
{ WASM_INS_F64_DIV, "f64.div" },
{ WASM_INS_F64_MIN, "f64.min" },
{ WASM_INS_F64_MAX, "f64.max" },
{ WASM_INS_F64_COPYSIGN, "f64.copysign" },
{ WASM_INS_I32_WARP_I64, "i32.warp/i64" },
{ WASP_INS_I32_TRUNC_S_F32, "i32.trunc_s/f32" },
{ WASM_INS_I32_TRUNC_U_F32, "i32.trunc_u/f32" },
{ WASM_INS_I32_TRUNC_S_F64, "i32/trunc_s/f64" },
{ WASM_INS_I32_TRUNC_U_F64, "i32/trunc_u/f64" },
{ WASM_INS_I64_EXTEND_S_I32, "i64/extend_s/i32" },
{ WASM_INS_I64_EXTEND_U_I32, "i64/extend_u/i32" },
{ WASM_INS_I64_TRUNC_S_F32, "i64.trunc_s/f32" },
{ WASM_INS_I64_TRUNC_U_F32, "i64.trunc_u/f32" },
{ WASM_INS_I64_TRUNC_S_F64, "f64.trunc_s/f64" },
{ WASM_INS_I64_TRUNC_U_F64, "f64.trunc_u/f64" },
{ WASM_INS_F32_CONVERT_S_I32, "f32.convert_s/i32" },
{ WASM_INS_F32_CONVERT_U_I32, "f32.convert_u/i32" },
{ WASM_INS_F32_CONVERT_S_I64, "f32.convert_s/i64" },
{ WASM_INS_F32_CONVERT_U_I64, "f32.convert_u/i64" },
{ WASM_INS_F32_DEMOTE_F64, "f32.demote/f64" },
{ WASM_INS_F64_CONVERT_S_I32, "f64.convert_s/i32" },
{ WASM_INS_F64_CONVERT_U_I32, "f64.convert_u/i32" },
{ WASM_INS_F64_CONVERT_S_I64, "f64.convert_s/i64" },
{ WASM_INS_F64_CONVERT_U_I64, "f64.convert_u/i64" },
{ WASM_INS_F64_PROMOTE_F32, "f64.promote/f32" },
{ WASM_INS_I32_REINTERPRET_F32, "i32.reinterpret/f32" },
{ WASM_INS_I64_REINTERPRET_F64, "i64.reinterpret/f64" },
{ WASM_INS_F32_REINTERPRET_I32, "f32.reinterpret/i32" },
{ WASM_INS_F64_REINTERPRET_I64, "f64.reinterpret/i64" },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
{ WASM_INS_INVALID, NULL },
};
#endif
const char *WASM_insn_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
if (id >= ARR_SIZE(insn_name_maps))
return NULL;
else
return insn_name_maps[id].name;
#else
return NULL;
#endif
}
#ifndef CAPSTONE_DIET
static name_map group_name_maps[] = {
// generic groups
{ WASM_GRP_INVALID, NULL },
// special groups
{ WASM_GRP_NUMBERIC, "numberic"},
{ WASM_GRP_PARAMETRIC, "parametric"},
{ WASM_GRP_VARIABLE, "variable"},
{ WASM_GRP_MEMORY, "memory"},
{ WASM_GRP_CONTROL, "control"},
};
#endif
#ifndef CAPSTONE_DIET
static name_map kind_name_maps[] = {
{ WASM_OP_INVALID, "Invalid" },
{ WASM_OP_NONE, "None" },
{ WASM_OP_INT7, "uint7" },
{ WASM_OP_VARUINT32, "varuint32" },
{ WASM_OP_VARUINT64, "varuint64" },
{ WASM_OP_UINT32, "uint32" },
{ WASM_OP_UINT64, "uint64" },
};
#endif
const char *WASM_kind_name(unsigned int id){
#ifndef CAPSTONE_DIET
return id2name(kind_name_maps, ARR_SIZE(kind_name_maps), id);
#else
return NULL;
#endif
}
const char *WASM_group_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
#else
return NULL;
#endif
}
#endif

9
arch/WASM/WASMMapping.h Normal file
View File

@ -0,0 +1,9 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#include <capstone/capstone.h>
void WASM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *WASM_insn_name(csh handle, unsigned int id);
const char *WASM_group_name(csh handle, unsigned int id);
const char *WASM_kind_name(unsigned int id);

33
arch/WASM/WASMModule.c Normal file
View File

@ -0,0 +1,33 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#ifdef CAPSTONE_HAS_WASM
#include "../../cs_priv.h"
#include "WASMDisassembler.h"
#include "WASMInstPrinter.h"
#include "WASMMapping.h"
#include "WASMModule.h"
cs_err WASM_global_init(cs_struct *ud)
{
// verify if requested mode is valid
if (ud->mode)
return CS_ERR_MODE;
ud->printer = WASM_printInst;
ud->printer_info = NULL;
ud->insn_id = WASM_get_insn_id;
ud->insn_name = WASM_insn_name;
ud->group_name = WASM_group_name;
ud->disasm = WASM_getInstruction;
return CS_ERR_OK;
}
cs_err WASM_option(cs_struct *handle, cs_opt_type type, size_t value)
{
return CS_ERR_OK;
}
#endif

12
arch/WASM/WASMModule.h Normal file
View File

@ -0,0 +1,12 @@
/* Capstone Disassembly Engine */
/* By Spike, xwings 2019 */
#ifndef CS_WASM_MODULE_H
#define CS_WASM_MODULE_H
#include "../../utils.h"
cs_err WASM_global_init(cs_struct *ud);
cs_err WASM_option(cs_struct *handle, cs_opt_type type, size_t value);
#endif

View File

@ -129,8 +129,8 @@ __all__ = [
# Capstone C interface
# API version
CS_API_MAJOR = 4
CS_API_MINOR = 1
CS_API_MAJOR = 5
CS_API_MINOR = 0
# Package version
CS_VERSION_MAJOR = CS_API_MAJOR

10
cmake-x86.sh Executable file
View File

@ -0,0 +1,10 @@
# Capstone disassembler engine (www.capstone-engine.org)
# Build Capstone libs for X86 only (libcapstone.so & libcapstone.a) on *nix with CMake & make
# By Nguyen Anh Quynh, 2019
# Uncomment below line to compile in Diet mode
# cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_DIET=ON -DCAPSTONE_X86_ONLY=1 ..
cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_X86_ONLY=1 ..
make -j8

View File

@ -4,7 +4,7 @@
################################################################################
# Specify which archs you want to compile in. By default, we build all archs.
CAPSTONE_ARCHS ?= arm aarch64 m68k mips powerpc sparc systemz x86 xcore tms320c64x m680x evm mos65xx
CAPSTONE_ARCHS ?= arm aarch64 m68k mips powerpc sparc systemz x86 xcore tms320c64x m680x evm mos65xx wasm
################################################################################

40
cs.c
View File

@ -55,6 +55,7 @@
#include "arch/AArch64/AArch64Module.h"
#include "arch/ARM/ARMModule.h"
#include "arch/EVM/EVMModule.h"
#include "arch/WASM/WASMModule.h"
#include "arch/M680X/M680XModule.h"
#include "arch/M68K/M68KModule.h"
#include "arch/Mips/MipsModule.h"
@ -128,6 +129,11 @@ static cs_err (*cs_arch_init[MAX_ARCH])(cs_struct *) = {
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_WASM
WASM_global_init,
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_MOS65XX
MOS65XX_global_init,
#else
@ -197,6 +203,11 @@ static cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t valu
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_WASM
WASM_option,
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_MOS65XX
MOS65XX_option,
#else
@ -275,6 +286,11 @@ static cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH] = {
#else
0,
#endif
#ifdef CAPSTONE_HAS_WASM
0,
#else
0,
#endif
#ifdef CAPSTONE_HAS_MOS65XX
~(CS_MODE_BIG_ENDIAN),
#else
@ -320,6 +336,9 @@ static uint32_t all_arch = 0
#ifdef CAPSTONE_HAS_EVM
| (1 << CS_ARCH_EVM)
#endif
#ifdef CAPSTONE_HAS_WASM
| (1 << CS_ARCH_WASM)
#endif
#ifdef CAPSTONE_HAS_MOS65XX
| (1 << CS_ARCH_MOS65XX)
#endif
@ -394,7 +413,7 @@ bool CAPSTONE_API cs_support(int query)
(1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_MOS65XX));
(1 << CS_ARCH_MOS65XX) | (1 << CS_ARCH_WASM));
if ((unsigned int)query < CS_ARCH_MAX)
return all_arch & (1 << query);
@ -660,6 +679,9 @@ static uint8_t skipdata_size(cs_struct *handle)
case CS_ARCH_EVM:
// EVM alignment is 1.
return 1;
case CS_ARCH_WASM:
//WASM alignment is 1
return 1;
case CS_ARCH_MOS65XX:
// MOS65XX alignment is 1.
return 1;
@ -1381,11 +1403,18 @@ int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
if (insn->detail->evm.operands[i].type == (evm_op_type)op_type)
count++;
#endif
break;
case CS_ARCH_MOS65XX:
for (i = 0; i < insn->detail->m680x.op_count; i++)
if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type)
count++;
break;
case CS_ARCH_WASM:
#if 0
for (i = 0; i < insn->detail->evm.op_count; i++)
if (insn->detail->evm.operands[i].type == (evm_op_type)op_type)
count++;
#endif
break;
}
@ -1530,6 +1559,15 @@ int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
return i;
}
break;
case CS_ARCH_WASM:
for (i = 0; i < insn->detail->wasm.op_count; i++) {
if (insn->detail->wasm.operands[i].type == (wasm_op_type)op_type)
count++;
if (count == post)
return i;
}
break;
}
return -1;

View File

@ -56,7 +56,8 @@ static struct {
{ "hd6309", CS_ARCH_M680X, CS_MODE_M680X_6309 },
{ "hcs08", CS_ARCH_M680X, CS_MODE_M680X_HCS08 },
{ "evm", CS_ARCH_EVM, 0 },
{ "mos65xx", CS_ARCH_MOS65XX, 0 },
{ "wasm", CS_ARCH_WASM, 0 },
{ "mos65xx", CS_ARCH_MOS65XX, 0 },
{ NULL }
};
@ -72,6 +73,7 @@ void print_insn_detail_m68k(csh handle, cs_insn *ins);
void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);
void print_insn_detail_m680x(csh handle, cs_insn *ins);
void print_insn_detail_evm(csh handle, cs_insn *ins);
void print_insn_detail_wasm(csh handle, cs_insn *ins);
void print_insn_detail_mos65xx(csh handle, cs_insn *ins);
static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins);
@ -134,8 +136,8 @@ static uint8_t *preprocess(char *code, size_t *size)
static void usage(char *prog)
{
printf("cstool for Capstone Disassembler, v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
printf("Syntax: %s [-d|-u|-s|-v] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
printf("Cstool for Capstone Disassembler Engine v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
printf("Syntax: %s [-u|-d|-s|-v] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
printf("\nThe following <arch+mode> options are supported:\n");
if (cs_support(CS_ARCH_X86)) {
@ -214,6 +216,10 @@ static void usage(char *prog)
printf(" mox65xx MOS65XX family\n");
}
if (cs_support(CS_ARCH_WASM)) {
printf(" wasm: Web Assembly\n");
}
printf("\nExtra options:\n");
printf(" -d show detailed information of the instructions\n");
printf(" -u show immediates as unsigned\n");
@ -260,6 +266,9 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
case CS_ARCH_EVM:
print_insn_detail_evm(handle, ins);
break;
case CS_ARCH_WASM:
print_insn_detail_wasm(handle, ins);
break;
case CS_ARCH_MOS65XX:
print_insn_detail_mos65xx(handle, ins);
break;
@ -359,6 +368,10 @@ int main(int argc, char **argv)
printf("evm=1 ");
}
if (cs_support(CS_ARCH_WASM)) {
printf("wasm=1 ");
}
if (cs_support(CS_ARCH_MOS65XX)) {
printf("mox65xx=1 ");
}

View File

@ -3,7 +3,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_arm(csh handle, cs_insn *ins)
{

View File

@ -6,7 +6,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_arm64(csh handle, cs_insn *ins)
{

View File

@ -3,7 +3,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_evm(csh handle, cs_insn *ins)
{

View File

@ -4,12 +4,11 @@
#include <stdio.h>
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
static const char *s_access[] = {
"UNCHANGED", "READ", "WRITE", "READ | WRITE",
};
void print_read_write_regs(csh handle, cs_detail *detail)
{
int i;

View File

@ -9,7 +9,6 @@
#include <stdio.h>
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
static const char* s_addressing_modes[] = {
"<invalid mode>",

View File

@ -6,7 +6,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_mips(csh handle, cs_insn *ins)
{

View File

@ -5,7 +5,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
static const char* get_bc_name(int bc)
{

View File

@ -5,7 +5,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_sparc(csh handle, cs_insn *ins)
{

View File

@ -5,7 +5,6 @@
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_sysz(csh handle, cs_insn *ins)
{

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <capstone/capstone.h>
void print_string_hex(const char *comment, unsigned char *str, size_t len);
void print_insn_detail_tms320c64x(csh handle, cs_insn *ins)
{

50
cstool/cstool_wasm.c Normal file
View File

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
void print_insn_detail_wasm(csh handle, cs_insn *ins)
{
cs_wasm *wasm;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
wasm = &(ins->detail->wasm);
if (wasm->op_count > 0) {
unsigned int i;
printf("\tOperand count: %d\n", wasm->op_count);
for (i = 0; i < wasm->op_count; i++) {
switch (wasm->operands[i].type) {
default:
break;
case WASM_OP_INT7:
printf("\t\tOperand[%d] type: int7\n", i);
printf("\t\tOperand[%d] value: %d\n", i, wasm->operands[i].int7);
break;
case WASM_OP_UINT32:
printf("\t\tOperand[%d] type: uint32\n", i);
printf("\t\tOperand[%d] value: 0x%x\n", i, wasm->operands[i].uint32);
break;
case WASM_OP_UINT64:
printf("\t\tOperand[%d] type: uint64\n", i);
printf("\t\tOperand[%d] value: 0x%lx\n", i, wasm->operands[i].uint64);
break;
case WASM_OP_VARUINT32:
printf("\t\tOperand[%d] type: varuint32\n", i);
printf("\t\tOperand[%d] value: 0x%x\n", i, wasm->operands[i].varuint32);
break;
case WASM_OP_VARUINT64:
printf("\t\tOperand[%d] type: varuint64\n", i);
printf("\t\tOperand[%d] value: 0x%lx\n", i, wasm->operands[i].varuint64);
break;
}
printf("\t\tOperand[%d] size: %d\n", i, wasm->operands[i].size);
}
}
}

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <capstone/capstone.h>
void print_string_hex(char *comment, unsigned char *str, size_t len);
void print_insn_detail_xcore(csh handle, cs_insn *ins)
{

View File

@ -84,6 +84,7 @@ typedef enum cs_arch {
CS_ARCH_TMS320C64X, ///< TMS320C64x architecture
CS_ARCH_M680X, ///< 680X architecture
CS_ARCH_EVM, ///< Ethereum architecture
CS_ARCH_WASM, ///< WebAssembly architecture
CS_ARCH_MOS65XX, ///< MOS65XX architecture (including MOS6502)
CS_ARCH_MAX,
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
@ -258,6 +259,7 @@ typedef struct cs_opt_skipdata {
/// X86: 1 bytes.
/// XCore: 2 bytes.
/// EVM: 1 bytes.
/// WASM: 1 bytes.
/// MOS65XX: 1 bytes.
cs_skipdata_cb_t callback; // default value is NULL
@ -278,6 +280,7 @@ typedef struct cs_opt_skipdata {
#include "tms320c64x.h"
#include "m680x.h"
#include "evm.h"
#include "wasm.h"
#include "mos65xx.h"
/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
@ -309,7 +312,8 @@ typedef struct cs_detail {
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
cs_m680x m680x; ///< M680X architecture
cs_evm evm; ///< Ethereum architecture
cs_mos65xx mos65xx; ///< Ethereum architecture
cs_wasm wasm; ///< Web Assembly architecture
cs_mos65xx mos65xx; ///< MOS65XX architecture (including MOS6502)
};
} cs_detail;

250
include/capstone/wasm.h Normal file
View File

@ -0,0 +1,250 @@
/* Capstone Disassembly Engine */
/* By Spike <spikeinhouse@gmail.com>, xwings 2019 */
#ifndef CAPSTONE_WASM_H
#define CAPSTONE_WASM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "platform.h"
#ifdef _MSC_VER
#pragma warning(disable:4201)
#endif
typedef enum wasm_op_type {
WASM_OP_INVALID = 0,
WASM_OP_NONE,
WASM_OP_INT7,
WASM_OP_VARUINT32,
WASM_OP_VARUINT64,
WASM_OP_UINT32,
WASM_OP_UINT64,
WASM_OP_IMM,
WASM_OP_BRTABLE,
} wasm_op_type;
typedef struct cs_wasm_brtable {
uint32_t length;
uint32_t *target;
uint32_t default_target;
} cs_wasm_brtable;
typedef struct cs_wasm_op {
wasm_op_type type;
uint8_t size;
union {
int8_t int7;
uint32_t varuint32;
uint64_t varuint64;
uint32_t uint32;
uint64_t uint64;
uint32_t immediate[2];
cs_wasm_brtable brtable;
};
} cs_wasm_op;
/// Instruction structure
typedef struct cs_wasm {
uint8_t op_count;
cs_wasm_op *operands;
} cs_wasm;
/// WASM instruction
typedef enum wasm_insn {
WASM_INS_UNREACHABLE = 0x0,
WASM_INS_NOP = 0x1,
WASM_INS_BLOCK = 0x2,
WASM_INS_LOOP = 0x3,
WASM_INS_IF = 0x4,
WASM_INS_ELSE = 0x5,
WASM_INS_END = 0xb,
WASM_INS_BR = 0xc,
WASM_INS_BR_IF = 0xd,
WASM_INS_BR_TABLE = 0xe,
WASM_INS_RETURN = 0xf,
WASM_INS_CALL = 0x10,
WASM_INS_CALL_INDIRECT = 0x11,
WASM_INS_DROP = 0x1a,
WASM_INS_SELECT = 0x1b,
WASM_INS_GET_LOCAL = 0x20,
WASM_INS_SET_LOCAL = 0x21,
WASM_INS_TEE_LOCAL = 0x22,
WASM_INS_GET_GLOBAL = 0x23,
WASM_INS_SET_GLOBAL = 0x24,
WASM_INS_I32_LOAD = 0x28,
WASM_INS_I64_LOAD = 0x29,
WASM_INS_F32_LOAD = 0x2a,
WASM_INS_F64_LOAD = 0x2b,
WASM_INS_I32_LOAD8_S = 0x2c,
WASM_INS_I32_LOAD8_U = 0x2d,
WASM_INS_I32_LOAD16_S = 0x2e,
WASM_INS_I32_LOAD16_U = 0x2f,
WASM_INS_I64_LOAD8_S = 0x30,
WASM_INS_I64_LOAD8_U = 0x31,
WASM_INS_I64_LOAD16_S = 0x32,
WASM_INS_I64_LOAD16_U = 0x33,
WASM_INS_I64_LOAD32_S = 0x34,
WASM_INS_I64_LOAD32_U = 0x35,
WASM_INS_I32_STORE = 0x36,
WASM_INS_I64_STORE = 0x37,
WASM_INS_F32_STORE = 0x38,
WASM_INS_F64_STORE = 0x39,
WASM_INS_I32_STORE8 = 0x3a,
WASM_INS_I32_STORE16 = 0x3b,
WASM_INS_I64_STORE8 = 0x3c,
WASM_INS_I64_STORE16 = 0x3d,
WASM_INS_I64_STORE32 = 0x3e,
WASM_INS_CURRENT_MEMORY = 0x3f,
WASM_INS_GROW_MEMORY = 0x40,
WASM_INS_I32_CONST = 0x41,
WASM_INS_I64_CONST = 0x42,
WASM_INS_F32_CONST = 0x43,
WASM_INS_F64_CONST = 0x44,
WASM_INS_I32_EQZ = 0x45,
WASM_INS_I32_EQ = 0x46,
WASM_INS_I32_NE = 0x47,
WASM_INS_I32_LT_S = 0x48,
WASM_INS_I32_LT_U = 0x49,
WASM_INS_I32_GT_S = 0x4a,
WASM_INS_I32_GT_U = 0x4b,
WASM_INS_I32_LE_S = 0x4c,
WASM_INS_I32_LE_U = 0x4d,
WASM_INS_I32_GE_S = 0x4e,
WASM_INS_I32_GE_U = 0x4f,
WASM_INS_I64_EQZ = 0x50,
WASM_INS_I64_EQ = 0x51,
WASM_INS_I64_NE = 0x52,
WASM_INS_I64_LT_S = 0x53,
WASM_INS_I64_LT_U = 0x54,
WASN_INS_I64_GT_S = 0x55,
WASM_INS_I64_GT_U = 0x56,
WASM_INS_I64_LE_S = 0x57,
WASM_INS_I64_LE_U = 0x58,
WASM_INS_I64_GE_S = 0x59,
WASM_INS_I64_GE_U = 0x5a,
WASM_INS_F32_EQ = 0x5b,
WASM_INS_F32_NE = 0x5c,
WASM_INS_F32_LT = 0x5d,
WASM_INS_F32_GT = 0x5e,
WASM_INS_F32_LE = 0x5f,
WASM_INS_F32_GE = 0x60,
WASM_INS_F64_EQ = 0x61,
WASM_INS_F64_NE = 0x62,
WASM_INS_F64_LT = 0x63,
WASM_INS_F64_GT = 0x64,
WASM_INS_F64_LE = 0x65,
WASM_INS_F64_GE = 0x66,
WASM_INS_I32_CLZ = 0x67,
WASM_INS_I32_CTZ = 0x68,
WASM_INS_I32_POPCNT = 0x69,
WASM_INS_I32_ADD = 0x6a,
WASM_INS_I32_SUB = 0x6b,
WASM_INS_I32_MUL = 0x6c,
WASM_INS_I32_DIV_S = 0x6d,
WASM_INS_I32_DIV_U = 0x6e,
WASM_INS_I32_REM_S = 0x6f,
WASM_INS_I32_REM_U = 0x70,
WASM_INS_I32_AND = 0x71,
WASM_INS_I32_OR = 0x72,
WASM_INS_I32_XOR = 0x73,
WASM_INS_I32_SHL = 0x74,
WASM_INS_I32_SHR_S = 0x75,
WASM_INS_I32_SHR_U = 0x76,
WASM_INS_I32_ROTL = 0x77,
WASM_INS_I32_ROTR = 0x78,
WASM_INS_I64_CLZ = 0x79,
WASM_INS_I64_CTZ = 0x7a,
WASM_INS_I64_POPCNT = 0x7b,
WASM_INS_I64_ADD = 0x7c,
WASM_INS_I64_SUB = 0x7d,
WASM_INS_I64_MUL = 0x7e,
WASM_INS_I64_DIV_S = 0x7f,
WASM_INS_I64_DIV_U = 0x80,
WASM_INS_I64_REM_S = 0x81,
WASM_INS_I64_REM_U = 0x82,
WASM_INS_I64_AND = 0x83,
WASM_INS_I64_OR = 0x84,
WASM_INS_I64_XOR = 0x85,
WASM_INS_I64_SHL = 0x86,
WASM_INS_I64_SHR_S = 0x87,
WASM_INS_I64_SHR_U = 0x88,
WASM_INS_I64_ROTL = 0x89,
WASM_INS_I64_ROTR = 0x8a,
WASM_INS_F32_ABS = 0x8b,
WASM_INS_F32_NEG = 0x8c,
WASM_INS_F32_CEIL = 0x8d,
WASM_INS_F32_FLOOR = 0x8e,
WASM_INS_F32_TRUNC = 0x8f,
WASM_INS_F32_NEAREST = 0x90,
WASM_INS_F32_SQRT = 0x91,
WASM_INS_F32_ADD = 0x92,
WASM_INS_F32_SUB = 0x93,
WASM_INS_F32_MUL = 0x94,
WASM_INS_F32_DIV = 0x95,
WASM_INS_F32_MIN = 0x96,
WASM_INS_F32_MAX = 0x97,
WASM_INS_F32_COPYSIGN = 0x98,
WASM_INS_F64_ABS = 0x99,
WASM_INS_F64_NEG = 0x9a,
WASM_INS_F64_CEIL = 0x9b,
WASM_INS_F64_FLOOR = 0x9c,
WASM_INS_F64_TRUNC = 0x9d,
WASM_INS_F64_NEAREST = 0x9e,
WASM_INS_F64_SQRT = 0x9f,
WASM_INS_F64_ADD = 0xa0,
WASM_INS_F64_SUB = 0xa1,
WASM_INS_F64_MUL = 0xa2,
WASM_INS_F64_DIV = 0xa3,
WASM_INS_F64_MIN = 0xa4,
WASM_INS_F64_MAX = 0xa5,
WASM_INS_F64_COPYSIGN = 0xa6,
WASM_INS_I32_WARP_I64 = 0xa7,
WASP_INS_I32_TRUNC_S_F32 = 0xa8,
WASM_INS_I32_TRUNC_U_F32 = 0xa9,
WASM_INS_I32_TRUNC_S_F64 = 0xaa,
WASM_INS_I32_TRUNC_U_F64 = 0xab,
WASM_INS_I64_EXTEND_S_I32 = 0xac,
WASM_INS_I64_EXTEND_U_I32 = 0xad,
WASM_INS_I64_TRUNC_S_F32 = 0xae,
WASM_INS_I64_TRUNC_U_F32 = 0xaf,
WASM_INS_I64_TRUNC_S_F64 = 0xb0,
WASM_INS_I64_TRUNC_U_F64 = 0xb1,
WASM_INS_F32_CONVERT_S_I32 = 0xb2,
WASM_INS_F32_CONVERT_U_I32 = 0xb3,
WASM_INS_F32_CONVERT_S_I64 = 0xb4,
WASM_INS_F32_CONVERT_U_I64 = 0xb5,
WASM_INS_F32_DEMOTE_F64 = 0xb6,
WASM_INS_F64_CONVERT_S_I32 = 0xb7,
WASM_INS_F64_CONVERT_U_I32 = 0xb8,
WASM_INS_F64_CONVERT_S_I64 = 0xb9,
WASM_INS_F64_CONVERT_U_I64 = 0xba,
WASM_INS_F64_PROMOTE_F32 = 0xbb,
WASM_INS_I32_REINTERPRET_F32 = 0xbc,
WASM_INS_I64_REINTERPRET_F64 = 0xbd,
WASM_INS_F32_REINTERPRET_I32 = 0xbe,
WASM_INS_F64_REINTERPRET_I64 = 0xbf,
WASM_INS_INVALID = 512,
WASM_INS_ENDING,
} wasm_insn;
/// Group of WASM instructions
typedef enum wasm_insn_group {
WASM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
WASM_GRP_NUMBERIC = 8,
WASM_GRP_PARAMETRIC,
WASM_GRP_VARIABLE,
WASM_GRP_MEMORY,
WASM_GRP_CONTROL,
WASM_GRP_ENDING, ///< <-- mark the end of the list of groups
} wasm_insn_group;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -3,8 +3,8 @@
:: By Nguyen Anh Quynh, 2017
:: Uncomment below line to compile in Diet mode
:: cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_DIET=ON -DCAPSTONE_ARM_SUPPORT=0 -DCAPSTONE_ARM64_SUPPORT=0 -DCAPSTONE_M68K_SUPPORT=0 -DCAPSTONE_MIPS_SUPPORT=0 -DCAPSTONE_PPC_SUPPORT=0 -DCAPSTONE_SPARC_SUPPORT=0 -DCAPSTONE_SYSZ_SUPPORT=0 -DCAPSTONE_XCORE_SUPPORT=0 -DCAPSTONE_TMS320C64X_SUPPORT=0 -DCAPSTONE_EVM_SUPPORT=0 -DCAPSTONE_MOS65XX_SUPPORT=0 -DCAPSTONE_M680X_SUPPORT=0 -DCAPSTONE_BUILD_STATIC_RUNTIME=OFF -G "NMake Makefiles" ..
:: cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_DIET=ON -DCAPSTONE_X86_ONLY=1 -DCAPSTONE_BUILD_STATIC_RUNTIME=ON -G "NMake Makefiles" ..
cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_ARM_SUPPORT=0 -DCAPSTONE_ARM64_SUPPORT=0 -DCAPSTONE_M68K_SUPPORT=0 -DCAPSTONE_MIPS_SUPPORT=0 -DCAPSTONE_PPC_SUPPORT=0 -DCAPSTONE_SPARC_SUPPORT=0 -DCAPSTONE_SYSZ_SUPPORT=0 -DCAPSTONE_XCORE_SUPPORT=0 -DCAPSTONE_TMS320C64X_SUPPORT=0 -DCAPSTONE_EVM_SUPPORT=0 -DCAPSTONE_MOS65XX_SUPPORT=0 -DCAPSTONE_M680X_SUPPORT=0 -DCAPSTONE_BUILD_STATIC_RUNTIME=OFF -G "NMake Makefiles" ..
cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_X86_ONLY=1 -DCAPSTONE_BUILD_STATIC_RUNTIME=ON -G "NMake Makefiles" ..
nmake

View File

@ -2,6 +2,6 @@
:: Build Capstone libs (capstone.dll & capstone.lib) on Windows with CMake & Nmake
:: By Nguyen Anh Quynh, 2017
cmake -DCMAKE_BUILD_TYPE=Release -G "NMake Makefiles" ..
cmake -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_STATIC_RUNTIME=ON -G "NMake Makefiles" ..
nmake

View File

@ -8,7 +8,7 @@
On default Capstone build, this code prints out the below output:
$ capstone_get_setup
x86=1 arm=1 arm64=1 mips=1 ppc=1 sparc=1 sysz=1 xcore=1 m68k=1 tms320c64x=1 m680x=1 evm=1
x86=1 arm=1 arm64=1 mips=1 ppc=1 sparc=1 sysz=1 xcore=1 m68k=1 tms320c64x=1 m680x=1 evm=1 wasm=1
*/
#include <stdio.h>
@ -64,6 +64,10 @@ int main()
printf("evm=1 ");
}
if (cs_support(CS_ARCH_WASM)) {
printf("wasm=1 ");
}
if (cs_support(CS_ARCH_MOS65XX)) {
printf("mox65xx=1 ");
}

View File

@ -113,6 +113,10 @@ ifneq (,$(findstring evm,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_EVM
SOURCES += test_evm.c
endif
ifneq (,$(findstring wasm,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_WASM
SOURCES += test_wasm.c
endif
ifneq (,$(findstring evm,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_MOS65XX
SOURCES += test_mos65xx.c

View File

@ -33,7 +33,7 @@ static void test()
#ifdef CAPSTONE_HAS_X86
#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
#define X86_CODE32 "\xba\xcd\xab\x00\x00\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
//#define X86_CODE32 "\x0f\xa7\xc0" // xstorerng
//#define X86_CODE32 "\x0f\xa7\xc0" // xstorerng
#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00"
#endif
#ifdef CAPSTONE_HAS_ARM
@ -52,10 +52,10 @@ static void test()
#define MIPS_32R6 "\xec\x80\x00\x19\x7c\x43\x22\xa0"
#endif
#ifdef CAPSTONE_HAS_ARM64
//#define ARM64_CODE "\x00\x40\x21\x4b" // sub w0, w0, w1, uxtw
//#define ARM64_CODE "\x21\x7c\x02\x9b" // mul x1, x1, x2
//#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0
//#define ARM64_CODE "\xe1\x0b\x40\xb9" // ldr w1, [sp, #0x8]
//#define ARM64_CODE "\x00\x40\x21\x4b" // sub w0, w0, w1, uxtw
//#define ARM64_CODE "\x21\x7c\x02\x9b" // mul x1, x1, x2
//#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0
//#define ARM64_CODE "\xe1\x0b\x40\xb9" // ldr w1, [sp, #0x8]
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9"
#endif
#ifdef CAPSTONE_HAS_PPC
@ -84,6 +84,9 @@ static void test()
#ifdef CAPSTONE_HAS_EVM
#define EVM_CODE "\x60\x61"
#endif
#ifdef CAPSTONE_HAS_WASM
#define WASM_CODE "\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b"
#endif
#ifdef CAPSTONE_HAS_MOS65XX
#define MOS65XX_CODE "\x0d\x34\x12\x00\x81\x65\x87\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42"
@ -319,6 +322,15 @@ static void test()
"EVM",
},
#endif
#ifdef CAPSTONE_HAS_WASM
{
CS_ARCH_WASM,
0,
(unsigned char*)WASM_CODE,
sizeof(WASM_CODE) - 1,
"WASM",
},
#endif
#ifdef CAPSTONE_HAS_MOS65XX
{
CS_ARCH_MOS65XX,

152
tests/test_wasm.c Normal file
View File

@ -0,0 +1,152 @@
/* Capstone Disassembler Engine */
/* By Spike <spikeinhouse@gmail.com>, 2018 */
#include <stdio.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include <capstone/capstone.h>
static csh handle;
struct platform {
cs_arch arch;
cs_mode mode;
unsigned char *code;
size_t size;
const char *comment;
};
static void print_string_hex(const char *comment, unsigned char *str, size_t len)
{
unsigned char *c;
printf("%s", comment);
for (c = str; c < str + len; c++) {
printf("0x%02x ", *c & 0xff);
}
printf("\n");
}
static void print_insn_detail(csh cs_handle, cs_insn *ins)
{
cs_wasm *wasm;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
if (ins->detail->groups_count) {
int j;
printf("\tGroups: ");
for(j = 0; j < ins->detail->groups_count; j++) {
printf("%s ", cs_group_name(handle, ins->detail->groups[j]));
}
printf("\n");
}
wasm = &(ins->detail->wasm);
if (wasm->op_count > 0) {
int i;
printf("\tOperand count: %u\n", wasm->op_count);
for (i = 0; i < wasm->op_count; i++) {
switch (wasm->operands[i].type) {
default:
break;
case WASM_OP_INT7:
printf("\t\tOperand[%d] type: int7\n", i);
printf("\t\tOperand[%d] value: %d\n", i, wasm->operands[i].int7);
break;
case WASM_OP_UINT32:
printf("\t\tOperand[%d] type: uint32\n", i);
printf("\t\tOperand[%d] value: 0x%x\n", i, wasm->operands[i].uint32);
break;
case WASM_OP_UINT64:
printf("\t\tOperand[%d] type: uint64\n", i);
printf("\t\tOperand[%d] value: 0x%lx\n", i, wasm->operands[i].uint64);
break;
case WASM_OP_VARUINT32:
printf("\t\tOperand[%d] type: varuint32\n", i);
printf("\t\tOperand[%d] value: 0x%x\n", i, wasm->operands[i].varuint32);
break;
case WASM_OP_VARUINT64:
printf("\t\tOperand[%d] type: varuint64\n", i);
printf("\t\tOperand[%d] value: 0x%lx\n", i, wasm->operands[i].varuint64);
break;
}
printf("\t\tOperand[%d] size: %u\n", i, wasm->operands[i].size);
}
}
}
static void test()
{
// #define WASM_CODE "\x00\x0e\x01\x04\x20\x00\x00\x00\x00"
// #define WASM_CODE "\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b"
// #define WASM_CODE "\x43\x01\x01\x01\x01"
#define WASM_CODE "\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b"
struct platform platforms[] = {
{
CS_ARCH_WASM,
0,
(unsigned char *)WASM_CODE,
sizeof(WASM_CODE) - 1,
"WASM"
},
};
uint64_t address = 0xffff;
cs_insn *insn;
size_t count;
int i;
for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
if (err) {
printf("Failed on cs_open() with error returned: %u\n", err);
abort();
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
if (count) {
size_t j;
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
printf("Disasm:\n");
for (j = 0; j < count; j++) {
printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
print_insn_detail(handle, &insn[j]);
}
printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);
// free memory allocated by cs_disasm()
cs_free(insn, count);
} else {
printf("****************\n");
printf("Platform: %s\n", platforms[i].comment);
print_string_hex("Code:", platforms[i].code, platforms[i].size);
printf("ERROR: Failed to disasm given code!\n");
abort();
}
printf("\n");
cs_close(&handle);
}
}
int main()
{
test();
return 0;
}