Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,6 @@ capstone_get_setup
*.s

cstool/cstool

# android
android-ndk-*
16 changes: 13 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ before_script:
# TODO remove built in cmocka compile and use system cmocka (including brewfile) once xenial is default
- git clone https://git.cryptomilk.org/projects/cmocka.git suite/cstest/cmocka
- chmod +x suite/cstest/build_cstest.sh
- if [[ ${TRAVIS_OS_NAME} = linux ]]; then export PATH="/usr/lib/llvm-9/bin:${PATH}"; fi
script:
- ./make.sh
- make check
Expand All @@ -18,6 +19,7 @@ script:
- if [[ "$NOPYTEST" != "true" ]]; then cd suite/cstest && ./build_cstest.sh; fi
- if [[ "$NOPYTEST" != "true" ]]; then python cstest_report.py -D -t build/cstest -d ../MC; fi
- if [[ "$NOPYTEST" != "true" ]]; then python cstest_report.py -D -t build/cstest -f issues.cs; fi
- if [ -n "$QA_FUZZIT" ]; then suite/fuzz/fuzzit.sh; fi
compiler:
- clang
- gcc
Expand All @@ -43,14 +45,22 @@ matrix:
packages:
- libcmocka-dev
- name: fuzza
env: ASAN_OPTIONS=detect_leaks=0 CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address" LDFLAGS="-fsanitize=address" NOPYTEST=true
env: ASAN_OPTIONS=detect_leaks=0 CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" LDFLAGS="-fsanitize=address" NOPYTEST=true QA_FUZZIT=asan
compiler: clang
os: linux
- name: fuzzm
env: CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory" LDFLAGS="-fsanitize=memory" NOPYTEST=true
env: CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" LDFLAGS="-fsanitize=memory" NOPYTEST=true QA_FUZZIT=msan
compiler: clang
os: linux
- name: fuzzu
env: CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fno-sanitize-recover=undefined,integer" LDFLAGS="-fsanitize=undefined" NOPYTEST=true
env: CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link" CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fno-sanitize-recover=undefined,integer -fsanitize=fuzzer-no-link" LDFLAGS="-fsanitize=undefined" NOPYTEST=true QA_FUZZIT=ubsan
compiler: clang
os: linux

addons:
apt:
sources:
- llvm-toolchain-trusty
- ubuntu-toolchain-r-test
packages:
- clang-9
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ endif

ifeq ($(CROSS),)
RANLIB ?= ranlib
else ifeq ($(ANDROID), 1)
CC = $(CROSS)/../../bin/clang
AR = $(CROSS)/ar
RANLIB = $(CROSS)/ranlib
STRIP = $(CROSS)/strip
else
CC = $(CROSS)gcc
AR = $(CROSS)ar
Expand Down Expand Up @@ -406,7 +411,7 @@ else
endif
endif

$(LIBOBJ): config.mk *.h include/capstone/*.h
$(LIBOBJ): config.mk

$(LIBOBJ_ARM): $(DEP_ARM)
$(LIBOBJ_ARM64): $(DEP_ARM64)
Expand Down Expand Up @@ -444,6 +449,12 @@ else
$(generate-pkgcfg)
endif

# create a list of auto dependencies
AUTODEPS:= $(patsubst %.o,%.d, $(LIBOBJ))

# include by auto dependencies
-include $(AUTODEPS)

install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
mkdir -p $(LIBDIR)
$(call install-library,$(LIBDIR))
Expand All @@ -467,6 +478,8 @@ clean:
rm -f $(LIBOBJ)
rm -f $(BLDIR)/lib$(LIBNAME).* $(BLDIR)/$(LIBNAME).pc
rm -f $(PKGCFGF)
rm -f $(AUTODEPS)
[ "${ANDROID}" = "1" ] && rm -rf android-ndk-* || true
$(MAKE) -C cstool clean

ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Capstone Engine
[![Build status](https://ci.appveyor.com/api/projects/status/a4wvbn89wu3pinas/branch/next?svg=true)](https://ci.appveyor.com/project/aquynh/capstone/branch/next)
[![pypi package](https://badge.fury.io/py/capstone.svg)](https://pypi.python.org/pypi/capstone)
[![pypi downloads](https://pepy.tech/badge/capstone)](https://pepy.tech/project/capstone)
[![Fuzzit Status](https://app.fuzzit.dev/badge?org_id=ANOh0D48gSLBxNZcDQMI&branch=master)](https://app.fuzzit.dev/admin/ANOh0D48gSLBxNZcDQMI/dashboard)<br/>

Capstone is a disassembly framework with the target of becoming the ultimate
disasm engine for binary analysis and reversing in the security community.
Expand Down Expand Up @@ -61,6 +62,12 @@ Hack
See HACK.TXT file for the structure of the source code.


Fuzz
----

See suite/fuzz/README.md for more information.


License
-------

Expand Down
10 changes: 10 additions & 0 deletions arch/SystemZ/SystemZGenAsmWriter.inc
Original file line number Diff line number Diff line change
Expand Up @@ -10645,6 +10645,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 0 encoded into 5 bits for 18 unique commands.
// printf("Fragment 0 = %" PRIu64 "\n", (Bits >> 14) & 31);
switch ((Bits >> 14) & 31) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -10752,6 +10753,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 1 encoded into 5 bits for 17 unique commands.
// printf("Fragment 1 = %" PRIu64 "\n", (Bits >> 19) & 31);
switch ((Bits >> 19) & 31) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -10845,6 +10847,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 2 encoded into 6 bits for 34 unique commands.
// printf("Fragment 2 = %" PRIu64 "\n", (Bits >> 24) & 63);
switch ((Bits >> 24) & 63) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -11011,6 +11014,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 3 encoded into 5 bits for 20 unique commands.
// printf("Fragment 3 = %" PRIu64 "\n", (Bits >> 30) & 31);
switch ((Bits >> 30) & 31) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -11116,6 +11120,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 4 encoded into 6 bits for 33 unique commands.
// printf("Fragment 4 = %" PRIu64 "\n", (Bits >> 35) & 63);
switch ((Bits >> 35) & 63) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -11277,6 +11282,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 5 encoded into 4 bits for 9 unique commands.
// printf("Fragment 5 = %" PRIu64 "\n", (Bits >> 41) & 15);
switch ((Bits >> 41) & 15) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -11329,6 +11335,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 6 encoded into 4 bits for 11 unique commands.
// printf("Fragment 6 = %" PRIu64 "\n", (Bits >> 45) & 15);
switch ((Bits >> 45) & 15) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand Down Expand Up @@ -11386,6 +11393,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 7 encoded into 1 bits for 2 unique commands.
// printf("Fragment 7 = %" PRIu64 "\n", (Bits >> 49) & 1);
if ((Bits >> 49) & 1) {
// RISBG, RISBG32, RISBGN, RISBHG, RISBLG, RNSBG, ROSBG, RXSBG, VAC, VACC...
SStream_concat0(O, ", ");
Expand All @@ -11396,6 +11404,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 8 encoded into 2 bits for 3 unique commands.
// printf("Fragment 8 = %" PRIu64 "\n", (Bits >> 50) & 3);
switch ((Bits >> 50) & 3) {
default: // llvm_unreachable("Invalid command number.");
case 0:
Expand All @@ -11416,6 +11425,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)


// Fragment 9 encoded into 1 bits for 2 unique commands.
// printf("Fragment 9 = %" PRIu64 "\n", (Bits >> 52) & 1);
if ((Bits >> 52) & 1) {
// VFCE, VFCH, VFCHE, VFMA, VFMAX, VFMIN, VFMS, VFNMA, VFNMS, VMSL, VSTRC
SStream_concat0(O, ", ");
Expand Down
7 changes: 3 additions & 4 deletions arch/SystemZ/SystemZInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,15 @@ static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O)
static void printPCRelOperand(MCInst *MI, int OpNum, SStream *O)
{
MCOperand *MO = MCInst_getOperand(MI, OpNum);
int32_t imm;

if (MCOperand_isImm(MO)) {
imm = (int32_t)MCOperand_getImm(MO);
int64_t imm = (int64_t)MCOperand_getImm(MO);

printInt32(O, imm);
printInt64(O, imm);

if (MI->csh->detail) {
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)imm;
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = imm;
MI->flat_insn->detail->sysz.op_count++;
}
}
Expand Down
6 changes: 3 additions & 3 deletions arch/X86/X86MappingInsnOp.inc
Original file line number Diff line number Diff line change
Expand Up @@ -7415,7 +7415,7 @@

{ /* X86_MOVBE16mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE16rm, X86_INS_MOVBE: movbe */
Expand All @@ -7425,7 +7425,7 @@

{ /* X86_MOVBE32mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE32rm, X86_INS_MOVBE: movbe */
Expand All @@ -7435,7 +7435,7 @@

{ /* X86_MOVBE64mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE64rm, X86_INS_MOVBE: movbe */
Expand Down
6 changes: 3 additions & 3 deletions arch/X86/X86MappingInsnOp_reduce.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3720,7 +3720,7 @@

{ /* X86_MOVBE16mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE16rm, X86_INS_MOVBE: movbe */
Expand All @@ -3730,7 +3730,7 @@

{ /* X86_MOVBE32mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE32rm, X86_INS_MOVBE: movbe */
Expand All @@ -3740,7 +3740,7 @@

{ /* X86_MOVBE64mr, X86_INS_MOVBE: movbe */
0,
{ CS_AC_READ, CS_AC_READ, 0 }
{ CS_AC_WRITE, CS_AC_READ, 0 }
},

{ /* X86_MOVBE64rm, X86_INS_MOVBE: movbe */
Expand Down
4 changes: 2 additions & 2 deletions bindings/README
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ See <language>/README for how to compile & install each binding.

More bindings created & maintained by the community are available as followings.

- Gapstone: Go binding (by Ben Nagy).
- Gapstone: Go binding (by Scott Knight).

https://github.com/bnagy/gapstone
https://github.com/knightsc/gapstone

- Crabstone: Ruby binding (by Ben Nagy).

Expand Down
52 changes: 27 additions & 25 deletions bindings/java/capstone/Capstone.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public List getFieldOrder() {
}

public static class CsInsn {
private NativeLong csh;
private Pointer csh;
private CS cs;
private _cs_insn raw;
private int arch;
Expand All @@ -121,7 +121,7 @@ public static class CsInsn {
public byte[] groups;
public OpInfo operands;

public CsInsn (_cs_insn insn, int _arch, NativeLong _csh, CS _cs, boolean diet) {
public CsInsn (_cs_insn insn, int _arch, Pointer _csh, CS _cs, boolean diet) {
id = insn.id;
address = insn.address;
size = insn.size;
Expand Down Expand Up @@ -294,31 +294,31 @@ private CsInsn[] fromArrayRaw(_cs_insn[] arr_raw) {
}

private interface CS extends Library {
public int cs_open(int arch, int mode, NativeLongByReference handle);
public NativeLong cs_disasm(NativeLong handle, byte[] code, NativeLong code_len,
public int cs_open(int arch, int mode, PointerByReference handle);
public NativeLong cs_disasm(Pointer handle, byte[] code, NativeLong code_len,
long addr, NativeLong count, PointerByReference insn);
public void cs_free(Pointer p, NativeLong count);
public int cs_close(NativeLongByReference handle);
public int cs_option(NativeLong handle, int option, NativeLong optionValue);

public String cs_reg_name(NativeLong csh, int id);
public int cs_op_count(NativeLong csh, Pointer insn, int type);
public int cs_op_index(NativeLong csh, Pointer insn, int type, int index);

public String cs_insn_name(NativeLong csh, int id);
public String cs_group_name(NativeLong csh, int id);
public byte cs_insn_group(NativeLong csh, Pointer insn, int id);
public byte cs_reg_read(NativeLong csh, Pointer insn, int id);
public byte cs_reg_write(NativeLong csh, Pointer insn, int id);
public int cs_errno(NativeLong csh);
public int cs_close(PointerByReference handle);
public int cs_option(Pointer handle, int option, NativeLong optionValue);

public String cs_reg_name(Pointer csh, int id);
public int cs_op_count(Pointer csh, Pointer insn, int type);
public int cs_op_index(Pointer csh, Pointer insn, int type, int index);

public String cs_insn_name(Pointer csh, int id);
public String cs_group_name(Pointer csh, int id);
public byte cs_insn_group(Pointer csh, Pointer insn, int id);
public byte cs_reg_read(Pointer csh, Pointer insn, int id);
public byte cs_reg_write(Pointer csh, Pointer insn, int id);
public int cs_errno(Pointer csh);
public int cs_version(IntByReference major, IntByReference minor);
public boolean cs_support(int query);
public String cs_strerror(int code);
public int cs_regs_access(NativeLong handle, Pointer insn, Pointer regs_read, ByteByReference regs_read_count, Pointer regs_write, ByteByReference regs_write_count);
public int cs_regs_access(Pointer handle, Pointer insn, Pointer regs_read, ByteByReference regs_read_count, Pointer regs_write, ByteByReference regs_write_count);
}

// Capstone API version
public static final int CS_API_MAJOR = 4;
public static final int CS_API_MAJOR = 5;
public static final int CS_API_MINOR = 0;

// architectures
Expand Down Expand Up @@ -420,8 +420,8 @@ public NativeLong cs_disasm(NativeLong handle, byte[] code, NativeLong code_len,
public static final int CS_SUPPORT_X86_REDUCE = CS_ARCH_ALL+2; // X86 reduce mode

protected class NativeStruct {
private NativeLong csh;
private NativeLongByReference handleRef;
private Pointer csh;
private PointerByReference handleRef;
}

private static final CsInsn[] EMPTY_INSN = new CsInsn[0];
Expand All @@ -436,15 +436,17 @@ protected class NativeStruct {

public Capstone(int arch, int mode) {
cs = (CS)Native.loadLibrary("capstone", CS.class);
int version = cs.cs_version(null, null);
if (version != (CS_API_MAJOR << 8) + CS_API_MINOR) {
throw new RuntimeException("Different API version between core & binding (CS_ERR_VERSION)");
int coreVersion = cs.cs_version(null, null);
int bindingVersion = (CS_API_MAJOR << 8) + CS_API_MINOR;
if (coreVersion != bindingVersion) {
throw new RuntimeException("Different API version between core " + coreVersion +
" & binding " + bindingVersion + " (CS_ERR_VERSION)");
}

this.arch = arch;
this.mode = mode;
ns = new NativeStruct();
ns.handleRef = new NativeLongByReference();
ns.handleRef = new PointerByReference();
if (cs.cs_open(arch, mode, ns.handleRef) != CS_ERR_OK) {
throw new RuntimeException("ERROR: Wrong arch or mode");
}
Expand Down
Loading