test2
Nguyen Anh Quynh 8 years ago
commit d14504d5fa
  1. 2
      .gitignore
  2. 7
      CMakeLists.txt
  3. 5
      HACK.TXT
  4. 25
      Makefile
  5. 35
      arch/X86/X86Mapping.c
  6. 6
      bindings/python/capstone/__init__.py
  7. 29
      cstool/Makefile
  8. 26
      cstool/README
  9. 280
      cstool/cstool.c

2
.gitignore vendored

@ -101,3 +101,5 @@ test_iter_benchmark
*.s
cstool/cstool

@ -449,3 +449,10 @@ if (CAPSTONE_BUILD_SHARED)
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
endif ()
if (CAPSTONE_BUILD_SHARED)
add_executable(cstool "cstool/cstool.c")
target_link_libraries(cstool ${default-target})
install(TARGETS cstool DESTINATION bin)
endif ()

@ -17,6 +17,7 @@ Capstone source is organized as followings.
   ├── ocaml <- Ocaml bindings + test code
   └── python <- Python bindings + test code
├── contrib <- Code contributed by community to help Capstone integration
├── cstool <- Cstool
├── docs <- Documentation
├── include <- API headers in C language (*.h)
├── msvc <- Microsoft Visual Studio support (for Windows compile)
@ -35,6 +36,10 @@ the code and try to recompile/reinstall again. This can be done with:
$ ./make.sh
$ sudo ./make.sh install
Then test Capstone with cstool, for example:
$ cstool x32 "90 91"
At the same time, for Java/Ocaml/Python bindings, be sure to always use
the bindings coming with the core to avoid potential incompatibility issue
with older versions.

@ -74,6 +74,7 @@ LIBDIRARCH ?= lib
# Or better, pass 'LIBDIRARCH=lib64' to 'make install/uninstall' via 'make.sh'.
#LIBDIRARCH ?= lib64
LIBDIR ?= $(PREFIX)/$(LIBDIRARCH)
BINDIR = $(PREFIX)/bin
LIBDATADIR ?= $(LIBDIR)
@ -355,6 +356,7 @@ PKGCFGF = $(BLDIR)/$(LIBNAME).pc
all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
@V=$(V) $(MAKE) -C cstool
ifndef BUILDDIR
cd tests && $(MAKE)
else
@ -405,25 +407,28 @@ else
endif
install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
mkdir -p $(DESTDIR)/$(LIBDIR)
$(call install-library,$(DESTDIR)/$(LIBDIR))
mkdir -p $(DESTDIR)$(LIBDIR)
$(call install-library,$(DESTDIR)$(LIBDIR))
ifeq ($(CAPSTONE_STATIC),yes)
$(INSTALL_DATA) $(ARCHIVE) $(DESTDIR)/$(LIBDIR)
$(INSTALL_DATA) $(ARCHIVE) $(DESTDIR)$(LIBDIR)
endif
mkdir -p $(DESTDIR)/$(INCDIR)/$(LIBNAME)
$(INSTALL_DATA) include/capstone/*.h $(DESTDIR)/$(INCDIR)/$(LIBNAME)
mkdir -p $(DESTDIR)/$(PKGCFGDIR)
$(INSTALL_DATA) $(PKGCFGF) $(DESTDIR)/$(PKGCFGDIR)
mkdir -p $(DESTDIR)$(INCDIR)/$(LIBNAME)
$(INSTALL_DATA) include/capstone/*.h $(DESTDIR)$(INCDIR)/$(LIBNAME)
mkdir -p $(DESTDIR)$(PKGCFGDIR)
$(INSTALL_DATA) $(PKGCFGF) $(DESTDIR)$(PKGCFGDIR)
$(INSTALL_LIB) cstool/cstool $(DESTDIR)$(BINDIR)
uninstall:
rm -rf $(DESTDIR)/$(INCDIR)/$(LIBNAME)
rm -f $(DESTDIR)/$(LIBDIR)/lib$(LIBNAME).*
rm -f $(DESTDIR)/$(PKGCFGDIR)/$(LIBNAME).pc
rm -rf $(DESTDIR)$(INCDIR)/$(LIBNAME)
rm -f $(DESTDIR)$(LIBDIR)/lib$(LIBNAME).*
rm -f $(DESTDIR)$(PKGCFGDIR)/$(LIBNAME).pc
rm -f $(DESTDIR)$(BINDIR)/cstool
clean:
rm -f $(LIBOBJ)
rm -f $(BLDIR)/lib$(LIBNAME).* $(BLDIR)/$(LIBNAME).*
rm -f $(PKGCFGF)
$(MAKE) -C cstool clean
ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
cd tests && $(MAKE) clean

@ -2616,6 +2616,25 @@ void X86_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
break;
}
break;
case X86_INS_RET:
switch(h->mode) {
case CS_MODE_16:
insn->detail->regs_write[0] = X86_REG_SP;
insn->detail->regs_read[0] = X86_REG_SP;
break;
case CS_MODE_32:
insn->detail->regs_write[0] = X86_REG_ESP;
insn->detail->regs_read[0] = X86_REG_ESP;
break;
default: // 64-bit
insn->detail->regs_write[0] = X86_REG_RSP;
insn->detail->regs_read[0] = X86_REG_RSP;
break;
}
insn->detail->regs_write_count = 1;
insn->detail->regs_read_count = 1;
break;
}
memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
@ -2667,10 +2686,20 @@ static struct insn_reg insn_regs_att[] = {
{ X86_INSW, X86_REG_DX },
{ X86_INSL, X86_REG_DX },
{ X86_MOV64o64a, X86_REG_RAX },
{ X86_MOV32o32a, X86_REG_EAX },
{ X86_MOV64o32a, X86_REG_EAX },
{ X86_MOV8o16a, X86_REG_AL },
{ X86_MOV8o32a, X86_REG_AL },
{ X86_MOV8o64a, X86_REG_AL },
{ X86_MOV16o16a, X86_REG_AX },
{ X86_MOV16o32a, X86_REG_AX },
{ X86_MOV16o64a, X86_REG_AX },
{ X86_MOV32o16a, X86_REG_EAX },
{ X86_MOV32o32a, X86_REG_EAX },
{ X86_MOV32o64a, X86_REG_EAX },
{ X86_MOV64o32a, X86_REG_RAX },
{ X86_MOV64o64a, X86_REG_RAX },
{ X86_PUSHCS32, X86_REG_CS },
{ X86_PUSHDS32, X86_REG_DS },

@ -503,7 +503,7 @@ class CsInsn(object):
if self._cs._detail and self._raw.id != 0:
# save detail
self._raw.detail = ctypes.pointer(all_info.detail._type_())
ctypes.pointer(self._raw.detail[0])[0] = all_info.detail[0]
ctypes.memmove(ctypes.byref(self._raw.detail[0]), ctypes.byref(all_info.detail[0]), ctypes.sizeof(type(all_info.detail[0])))
# return instruction's ID.
@property
@ -976,6 +976,10 @@ class Cs(object):
print(code)
code = code.encode()
print(code)'''
# Hack, unicorn's memory accessors give you back bytearrays, but they
# cause TypeErrors when you hand them into Capstone.
if isinstance(code, bytearray):
code = bytes(code)
res = _cs.cs_disasm(self.csh, code, len(code), offset, count, ctypes.byref(all_insn))
if res > 0:
try:

@ -0,0 +1,29 @@
# Makefile for Cstool of Capstone Disassembly Engine
include ../functions.mk
.PHONY: clean
LIBNAME = capstone
CFLAGS = -I../include
LDFLAGS = -O3 -Wall -L.. -l$(LIBNAME)
cstool: cstool.o
ifeq ($(V),0)
$(call log,LINK,$@)
@${CC} $< $(LDFLAGS) -o $@
else
${CC} $< $(LDFLAGS) -o $@
endif
clean:
${RM} -rf *.o cstool
%.o: %.c
ifeq ($(V),0)
$(call log,CC,$@)
@${CC} $(CFLAGS) -c $< -o $@
else
${CC} $(CFLAGS) -c $< -o $@
endif

@ -0,0 +1,26 @@
This directory contains cstool of Capstone Engine.
Cstool is a command-line tool to disassemble assembly hex-string.
For example, to decode a hexcode string for Intel 32bit, run:
$ cstool x32 "90 91"
0 90 nop
1 91 xchg eax, ecx
Cstool disassembles the input and prints out the assembly instructions.
On each line, the first column is the instruction offset, the second
column is opcodes, and the rest is the instruction itself.
Cstool is flexible enough to accept all kind of hexcode format. The following
inputs have the same output with the example above.
$ cstool x32 "0x90 0x91"
$ cstool x32 "\x90\x91"
$ cstool x32 "90,91"
$ cstool x32 "90;91"
$ cstool x32 "90+91"
$ cstool x32 "90:91"
To see all the supported options, run ./cstool

@ -0,0 +1,280 @@
/* Tang Yuhang <1648200150@qq.com> 2016 */
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <capstone/capstone.h>
#define VERSION "1.0"
// convert hexchar to hexnum
static uint8_t char_to_hexnum(char c)
{
if (c >= '0' && c <= '9') {
return (uint8_t)(c - '0');
}
if (c >= 'a' && c <= 'f') {
return (uint8_t)(10 + c - 'a');
}
// c >= 'A' && c <= 'F'
return (uint8_t)(10 + c - 'A');
}
// convert user input (char[]) to uint8_t[], each element of which is
// valid hexadecimal, and return actual length of uint8_t[] in @size.
static uint8_t *preprocess(char *code, size_t *size)
{
size_t i = 0, j = 0;
uint8_t high, low;
uint8_t *result;
result = (uint8_t *)malloc(strlen(code));
if (result != NULL) {
while (code[i] != '\0') {
if (isxdigit(code[i]) && isxdigit(code[i+1])) {
high = 16 * char_to_hexnum(code[i]);
low = char_to_hexnum(code[i+1]);
result[j] = high + low;
i++;
j++;
}
i++;
}
*size = j;
}
return result;
}
static void usage(char *prog)
{
printf("Cstool v%s for Capstone Disassembler Engine (www.capstone-engine.org)\n\n", VERSION);
printf("Syntax: %s <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)) {
printf(" x16: 16-bit mode (X86)\n");
printf(" x32: 32-bit mode (X86)\n");
printf(" x64: 64-bit mode (X86)\n");
printf(" x16att: 16-bit mode (X86) syntax-att\n");
printf(" x32att: 32-bit mode (X86) syntax-att\n");
printf(" x64att: 64-bit mode (X86) syntax-att\n");
}
if (cs_support(CS_ARCH_ARM)) {
printf(" arm: arm\n");
printf(" armb: arm + big endian\n");
printf(" arml: arm + little endian\n");
printf(" thumb: thumb mode\n");
printf(" thumbbe: thumb + big endian\n");
printf(" thumble: thumb + billtle endian\n");
}
if (cs_support(CS_ARCH_ARM64)) {
printf(" arm64: aarch64 mode\n");
}
if (cs_support(CS_ARCH_MIPS)) {
printf(" mips: mips32 + little endian\n");
printf(" mipsbe: mips32 + big endian\n");
printf(" mips64: mips64 + little endian\n");
printf(" mips64be: mips64 + big endian\n");
}
if (cs_support(CS_ARCH_PPC)) {
printf(" ppc64: ppc64 + little endian\n");
printf(" ppc64be: ppc64 + big endian\n");
}
if (cs_support(CS_ARCH_SPARC)) {
printf(" sparc: sparc\n");
}
if (cs_support(CS_ARCH_SYSZ)) {
printf(" systemz: systemz (s390x)\n");
}
if (cs_support(CS_ARCH_XCORE)) {
printf(" xcore: xcore\n");
}
printf("\n");
}
int main(int argc, char **argv)
{
csh handle;
char *mode;
uint8_t *assembly;
size_t count, size;
uint64_t address = 0;
cs_insn *insn;
cs_err err;
bool x86_arch = false;
if (argc != 3 && argc != 4) {
usage(argv[0]);
return -1;
}
mode = argv[1];
assembly = preprocess(argv[2], &size);
if (assembly == NULL) {
printf("ERROR: invalid assembler-string argument, quit!\n");
return -3;
}
if (argc == 4) {
// cstool <arch> <assembly> <address>
char *temp;
address = strtoull(argv[3], &temp, 16);
if (temp == argv[3] || *temp != '\0' || errno == ERANGE) {
printf("ERROR: invalid address argument, quit!\n");
return -2;
}
}
if (!strcmp(mode, "arm")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle);
}
if (!strcmp(mode, "armb")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "arml")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode, "thumb")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode, "thumbbe")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "thumble")) {
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode, "arm64")) {
err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode, "mips")) {
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode, "mipsbe")) {
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "mips64")) {
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "mips64be")) {
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "x16")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
}
if (!strcmp(mode, "x32")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
}
if (!strcmp(mode, "x64")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
}
if (!strcmp(mode, "x16att")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
if (!err) {
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
}
}
if (!strcmp(mode,"x32att")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
if (!err) {
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
}
}
if (!strcmp(mode,"x64att")) {
x86_arch = true;
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
if (!err) {
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
}
}
if (!strcmp(mode,"ppc64")) {
err = cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_LITTLE_ENDIAN, &handle);
}
if (!strcmp(mode,"ppc64be")) {
err = cs_open(CS_ARCH_PPC,CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode,"sparc")) {
err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle);
}
if (!strcmp(mode,"xcore")) {
err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle);
}
if (err) {
printf("ERROR: Failed on cs_open(), quit!\n");
usage(argv[0]);
return -1;
}
count = cs_disasm(handle, assembly, size, address, 0, &insn);
if (count > 0) {
size_t i;
for (i = 0; i < count; i++) {
int j;
printf("%"PRIx64" ", insn[i].address);
for (j = 0; j < insn[i].size; j++) {
printf("%02x", insn[i].bytes[j]);
}
// X86 instruction size is variable.
// align assembly instruction after the opcode
if (x86_arch) {
for (; j < 16; j++) {
printf(" ");
}
}
printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
}
cs_free(insn, count);
} else {
printf("ERROR: invalid assembly code\n");
return(-4);
}
cs_close(&handle);
return 0;
}
Loading…
Cancel
Save