diff --git a/.gitignore b/.gitignore index 835ee69..6703d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ link/ tmp/ build/ +build-riscv/ +fyne_metadata_init.go asm2hex ASM to HEX Converter.app diff --git a/FyneApp.toml b/FyneApp.toml index 7a27997..4c5a356 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -5,4 +5,4 @@ Website = "https://github.com/suifei/asm2hex" Name = "ASM to HEX Converter" ID = "suifei.asm2hex.app" Version = "1.2.0" - Build = 58 + Build = 59 diff --git a/Makefile b/Makefile index de4c5b4..b1e2b97 100644 --- a/Makefile +++ b/Makefile @@ -40,10 +40,12 @@ endif help: @echo "Available targets:" - @echo " help - Show this help message" - @echo " clean - Clean up temporary files" - @echo " lib - Build and install Capstone and Keystone libraries" - @echo " build - Build the project" + @echo " help - Show this help message" + @echo " clean - Clean up temporary files" + @echo " lib - Build and install Capstone and Keystone libraries" + @echo " build - Build the project" + @echo " lib_riscv - Build and install Capstone and Keystone libraries for RISC-V" + @echo " build_riscv - Build the project for RISC-V" clean: @rm -rf tmp build && \ @@ -88,6 +90,52 @@ lib: echo "Libraries installed successfully for $(PLATFORM)"; \ fi + +lib_riscv: + @if [ -d "$(INSTALL_PREFIX)/lib" ] && \ + [ -f "$(INSTALL_PREFIX)/lib/libcapstone.a" ] && \ + [ -f "$(INSTALL_PREFIX)/lib/libkeystone.a" ]; then \ + echo "Capstone and Keystone libraries are already installed"; \ + else \ + mkdir -p ./tmp && \ + cd ./tmp && \ + if [ ! -d "capstone" ]; then \ + git clone https://github.com/capstone-engine/capstone.git && \ + cd capstone && \ + git checkout $(CAPSTONE_VERSION) && \ + mkdir build && \ + cd build && \ + cmake $(CMAKE_FLAGS) .. && \ + $(SUDO) cmake --build . --config Release --target install; \ + else \ + echo "Capstone library is already built, skipping build"; \ + fi && \ + cd ../.. && \ + if [ ! -d "keystone" ]; then \ + git clone https://github.com/null-cell/keystone.git keystone-riscv && \ + cd keystone-riscv && \ + git checkout 0.9.3.dev2 && \ + mkdir build && \ + cd build && \ + $(KEYSTONE_BUILD_CMD); \ + else \ + echo "Keystone library is already built, skipping build"; \ + fi && \ + cd ../.. && \ + echo "Libraries installed successfully for $(PLATFORM)"; \ + fi + +build_riscv: + @mkdir -p ./build-riscv && \ + CGO_ENABLED=1 \ + CGO_CFLAGS="$(CGO_CFLAGS)" \ + CGO_LDFLAGS="$(CGO_LDFLAGS)" \ + fyne package --release --target $(TARGET) --icon ./theme/icons/asm2hex.png -tags build_riscv && \ + rm -rf ./build-riscv/$(if $(filter $(PLATFORM),Windows),*.exe,*.app) && \ + mv -fv $(if $(filter $(PLATFORM),Windows),*.exe,*.app) ./build-riscv && \ + echo "Build completed for $(PLATFORM)" + + build: @mkdir -p ./build && \ CGO_ENABLED=1 \ diff --git a/archs/arch.go b/archs/arch.go index 96012af..086329c 100644 --- a/archs/arch.go +++ b/archs/arch.go @@ -1,3 +1,5 @@ +//go:build !build_riscv + package archs import ( @@ -8,6 +10,114 @@ import ( "github.com/suifei/asm2hex/bindings/keystone" ) + +var WithRiscv = false +type Option struct { + Const uint64 + Name string +} + +type OptionSlice []Option + +var KeystoneArchOptions = OptionSlice{ + {uint64(keystone.ARCH_ARM), "ARM"}, + {uint64(keystone.ARCH_ARM64), "ARM64"}, + {uint64(keystone.ARCH_MIPS), "MIPS"}, + {uint64(keystone.ARCH_X86), "X86"}, + {uint64(keystone.ARCH_PPC), "PPC"}, + {uint64(keystone.ARCH_SPARC), "SPARC"}, + {uint64(keystone.ARCH_SYSTEMZ), "SYSTEMZ"}, + {uint64(keystone.ARCH_HEXAGON), "HEXAGON"}, +} + +var KeystoneModeList = OptionSlice{} +var KeystoneModeOptions = map[uint64]OptionSlice{ + uint64(keystone.ARCH_ARM): {{uint64(keystone.MODE_ARM), "ARM"}, {uint64(keystone.MODE_THUMB), "THUMB"}, {uint64(keystone.MODE_V8), "V8"}}, + uint64(keystone.ARCH_ARM64): {{uint64(keystone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(keystone.ARCH_MIPS): {{uint64(keystone.MODE_MICRO), "MICRO"}, {uint64(keystone.MODE_MIPS3), "MIPS3"}, {uint64(keystone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(keystone.MODE_MIPS32), "MIPS32"}, {uint64(keystone.MODE_MIPS64), "MIPS64"}}, + uint64(keystone.ARCH_X86): {{uint64(keystone.MODE_16), "16"}, {uint64(keystone.MODE_32), "32"}, {uint64(keystone.MODE_64), "64"}}, + uint64(keystone.ARCH_PPC): {{uint64(keystone.MODE_PPC32), "PPC32"}, {uint64(keystone.MODE_PPC64), "PPC64"}, {uint64(keystone.MODE_QPX), "QPX"}}, + uint64(keystone.ARCH_SPARC): {{uint64(keystone.MODE_SPARC32), "SPARC32"}, {uint64(keystone.MODE_SPARC64), "SPARC64"}, {uint64(keystone.MODE_V9), "V9"}}, + uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, +} + +// var KeystoneSyntaxList = OptionSlice{} +// var KeystoneSyntaxOptions = map[uint64]OptionSlice{ +// uint64(keystone.ARCH_ARM): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_ARM64): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_MIPS): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_X86): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}, {uint64(keystone.OPT_SYNTAX_NASM), "NASM"}, {uint64(keystone.OPT_SYNTAX_MASM), "MASM"}, {uint64(keystone.OPT_SYNTAX_GAS), "GAS"}, {uint64(keystone.OPT_SYNTAX_RADIX16), "Radix16"}}, +// uint64(keystone.ARCH_PPC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_SPARC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}}, +// } + +var CapstoneArchOptions = OptionSlice{ + {uint64(capstone.ARCH_ARM), "ARM"}, + {uint64(capstone.ARCH_ARM64), "ARM64"}, + {uint64(capstone.ARCH_MIPS), "MIPS"}, + {uint64(capstone.ARCH_X86), "X86"}, + {uint64(capstone.ARCH_PPC), "PPC"}, + {uint64(capstone.ARCH_SPARC), "SPARC"}, + {uint64(capstone.ARCH_SYSZ), "SYSZ"}, + {uint64(capstone.ARCH_XCORE), "XCORE"}, + {uint64(capstone.ARCH_M68K), "M68K"}, + {uint64(capstone.ARCH_TMS320C64X), "TMS320C64X"}, + {uint64(capstone.ARCH_M680X), "M680X"}, + {uint64(capstone.ARCH_EVM), "EVM"}, + {uint64(capstone.ARCH_MOS65XX), "MOS65XX"}, + {uint64(capstone.ARCH_WASM), "WASM"}, + {uint64(capstone.ARCH_BPF), "BPF"}, + {uint64(capstone.ARCH_RISCV), "RISCV"}, + {uint64(capstone.ARCH_SH), "SH"}, + {uint64(capstone.ARCH_TRICORE), "TRICORE"}, +} + +var CapstoneModeList = OptionSlice{} +var CapstoneModeOptions = map[uint64]OptionSlice{ + uint64(capstone.ARCH_ARM): {{uint64(capstone.MODE_ARM), "ARM"}, {uint64(capstone.MODE_THUMB), "THUMB"}, {uint64(capstone.MODE_MCLASS), "MCLASS"}, {uint64(capstone.MODE_V8), "V8"}}, + uint64(capstone.ARCH_ARM64): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_MIPS): {{uint64(capstone.MODE_MIPS32), "MIPS32"}, {uint64(capstone.MODE_MIPS64), "MIPS64"}, {uint64(capstone.MODE_MICRO), "MICRO"}, {uint64(capstone.MODE_MIPS3), "MIPS3"}, {uint64(capstone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(capstone.MODE_MIPS2), "MIPS2"}}, + uint64(capstone.ARCH_X86): {{uint64(capstone.MODE_16), "16"}, {uint64(capstone.MODE_32), "32"}, {uint64(capstone.MODE_64), "64"}}, + uint64(capstone.ARCH_PPC): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}, {uint64(capstone.MODE_QPX), "QPX"}, {uint64(capstone.MODE_SPE), "SPE"}, {uint64(capstone.MODE_BOOKE), "BOOKE"}}, + uint64(capstone.ARCH_SPARC): {{uint64(capstone.MODE_V9), "V9"}}, + uint64(capstone.ARCH_SYSZ): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(capstone.ARCH_XCORE): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_M68K): {{uint64(capstone.MODE_M68K_000), "M68K_000"}, {uint64(capstone.MODE_M68K_010), "M68K_010"}, {uint64(capstone.MODE_M68K_020), "M68K_020"}, {uint64(capstone.MODE_M68K_030), "M68K_030"}, {uint64(capstone.MODE_M68K_040), "M68K_040"}, {uint64(capstone.MODE_M68K_060), "M68K_060"}}, + uint64(capstone.ARCH_M680X): {{uint64(capstone.MODE_M680X_6301), "M680X_6301"}, {uint64(capstone.MODE_M680X_6309), "M680X_6309"}, {uint64(capstone.MODE_M680X_6800), "M680X_6800"}, {uint64(capstone.MODE_M680X_6801), "M680X_6801"}, {uint64(capstone.MODE_M680X_6805), "M680X_6805"}, {uint64(capstone.MODE_M680X_6808), "M680X_6808"}, {uint64(capstone.MODE_M680X_6809), "M680X_6809"}, {uint64(capstone.MODE_M680X_6811), "M680X_6811"}, {uint64(capstone.MODE_M680X_CPU12), "M680X_CPU12"}, {uint64(capstone.MODE_M680X_HCS08), "M680X_HCS08"}}, + uint64(capstone.ARCH_EVM): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.MODE_MOS65XX_6502), "MOS65XX_6502"}, {uint64(capstone.MODE_MOS65XX_65C02), "MOS65XX_65C02"}, {uint64(capstone.MODE_MOS65XX_W65C02), "MOS65XX_W65C02"}, {uint64(capstone.MODE_MOS65XX_65816), "MOS65XX_65816"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_M), "MOS65XX_65816_LONG_M"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_X), "MOS65XX_65816_LONG_X"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_MX), "MOS65XX_65816_LONG_MX"}}, + uint64(capstone.ARCH_WASM): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_BPF): {{uint64(capstone.MODE_BPF_CLASSIC), "BPF_CLASSIC"}, {uint64(capstone.MODE_BPF_EXTENDED), "BPF_EXTENDED"}}, + uint64(capstone.ARCH_RISCV): {{uint64(capstone.MODE_RISCV32), "RISCV32"}, {uint64(capstone.MODE_RISCV64), "RISCV64"}, {uint64(capstone.MODE_RISCVC), "RISCVC"}}, + uint64(capstone.ARCH_SH): {{uint64(capstone.MODE_SH2), "SH2"}, {uint64(capstone.MODE_SH2A), "SH2A"}, {uint64(capstone.MODE_SH3), "SH3"}, {uint64(capstone.MODE_SH4), "SH4"}, {uint64(capstone.MODE_SH4A), "SH4A"}, {uint64(capstone.MODE_SHFPU), "SHFPU"}, {uint64(capstone.MODE_SHDSP), "SHDSP"}}, + uint64(capstone.ARCH_TRICORE): {{uint64(capstone.MODE_TRICORE_110), "TRICORE_110"}, {uint64(capstone.MODE_TRICORE_120), "TRICORE_120"}, {uint64(capstone.MODE_TRICORE_130), "TRICORE_130"}, {uint64(capstone.MODE_TRICORE_131), "TRICORE_131"}, {uint64(capstone.MODE_TRICORE_160), "TRICORE_160"}, {uint64(capstone.MODE_TRICORE_161), "TRICORE_161"}, {uint64(capstone.MODE_TRICORE_162), "TRICORE_162"}}, +} + +// var CapstoneSyntaxList = OptionSlice{} +// var CapstoneSyntaxOptions = map[uint64]OptionSlice{ +// uint64(capstone.ARCH_ARM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_ARM64): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_MIPS): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_X86): {{uint64(capstone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(capstone.OPT_SYNTAX_ATT), "ATT"}, {uint64(capstone.OPT_SYNTAX_MASM), "MASM"}}, +// uint64(capstone.ARCH_PPC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_SPARC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_SYSZ): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_XCORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_M68K): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_TMS320C64X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_M680X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_EVM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_WASM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_BPF): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_RISCV): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_SH): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_TRICORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// } + func Disassemble(arch capstone.Architecture, mode capstone.Mode, code []byte, offset uint64, bigEndian bool /*syntaxValue capstone.OptionValue, */, addAddress bool) (string, uint64, bool, error) { defer func() { if r := recover(); r != nil { diff --git a/archs/arch_riscv.go b/archs/arch_riscv.go new file mode 100644 index 0000000..518e6f4 --- /dev/null +++ b/archs/arch_riscv.go @@ -0,0 +1,204 @@ +//go:build build_riscv + +package archs + +import ( + "fmt" + "strings" + + "github.com/suifei/asm2hex/bindings/capstone" + "github.com/suifei/asm2hex/bindings/keystone" +) + +var WithRiscv = true + +type Option struct { + Const uint64 + Name string +} + +type OptionSlice []Option + +var KeystoneArchOptions = OptionSlice{ + {uint64(keystone.ARCH_ARM), "ARM"}, + {uint64(keystone.ARCH_ARM64), "ARM64"}, + {uint64(keystone.ARCH_MIPS), "MIPS"}, + {uint64(keystone.ARCH_X86), "X86"}, + {uint64(keystone.ARCH_PPC), "PPC"}, + {uint64(keystone.ARCH_RISCV), "RISCV"}, + {uint64(keystone.ARCH_SPARC), "SPARC"}, + {uint64(keystone.ARCH_SYSTEMZ), "SYSTEMZ"}, + {uint64(keystone.ARCH_HEXAGON), "HEXAGON"}, +} + +var KeystoneModeList = OptionSlice{} +var KeystoneModeOptions = map[uint64]OptionSlice{ + uint64(keystone.ARCH_ARM): {{uint64(keystone.MODE_ARM), "ARM"}, {uint64(keystone.MODE_THUMB), "THUMB"}, {uint64(keystone.MODE_V8), "V8"}}, + uint64(keystone.ARCH_ARM64): {{uint64(keystone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(keystone.ARCH_MIPS): {{uint64(keystone.MODE_MICRO), "MICRO"}, {uint64(keystone.MODE_MIPS3), "MIPS3"}, {uint64(keystone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(keystone.MODE_MIPS32), "MIPS32"}, {uint64(keystone.MODE_MIPS64), "MIPS64"}}, + uint64(keystone.ARCH_X86): {{uint64(keystone.MODE_16), "16"}, {uint64(keystone.MODE_32), "32"}, {uint64(keystone.MODE_64), "64"}}, + uint64(keystone.ARCH_RISCV): {{uint64(keystone.MODE_RISCV32), "RISCV32"}, {uint64(keystone.MODE_RISCV64), "RISCV64"}}, + uint64(keystone.ARCH_PPC): {{uint64(keystone.MODE_PPC32), "PPC32"}, {uint64(keystone.MODE_PPC64), "PPC64"}, {uint64(keystone.MODE_QPX), "QPX"}}, + uint64(keystone.ARCH_SPARC): {{uint64(keystone.MODE_SPARC32), "SPARC32"}, {uint64(keystone.MODE_SPARC64), "SPARC64"}, {uint64(keystone.MODE_V9), "V9"}}, + uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, +} + +// var KeystoneSyntaxList = OptionSlice{} +// var KeystoneSyntaxOptions = map[uint64]OptionSlice{ +// uint64(keystone.ARCH_ARM): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_ARM64): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_MIPS): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_X86): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}, {uint64(keystone.OPT_SYNTAX_NASM), "NASM"}, {uint64(keystone.OPT_SYNTAX_MASM), "MASM"}, {uint64(keystone.OPT_SYNTAX_GAS), "GAS"}, {uint64(keystone.OPT_SYNTAX_RADIX16), "Radix16"}}, +// uint64(keystone.ARCH_PPC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_SPARC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, +// uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}}, +// } + +var CapstoneArchOptions = OptionSlice{ + {uint64(capstone.ARCH_ARM), "ARM"}, + {uint64(capstone.ARCH_ARM64), "ARM64"}, + {uint64(capstone.ARCH_MIPS), "MIPS"}, + {uint64(capstone.ARCH_X86), "X86"}, + {uint64(capstone.ARCH_PPC), "PPC"}, + {uint64(capstone.ARCH_SPARC), "SPARC"}, + {uint64(capstone.ARCH_SYSZ), "SYSZ"}, + {uint64(capstone.ARCH_XCORE), "XCORE"}, + {uint64(capstone.ARCH_M68K), "M68K"}, + {uint64(capstone.ARCH_TMS320C64X), "TMS320C64X"}, + {uint64(capstone.ARCH_M680X), "M680X"}, + {uint64(capstone.ARCH_EVM), "EVM"}, + {uint64(capstone.ARCH_MOS65XX), "MOS65XX"}, + {uint64(capstone.ARCH_WASM), "WASM"}, + {uint64(capstone.ARCH_BPF), "BPF"}, + {uint64(capstone.ARCH_RISCV), "RISCV"}, + {uint64(capstone.ARCH_SH), "SH"}, + {uint64(capstone.ARCH_TRICORE), "TRICORE"}, +} + +var CapstoneModeList = OptionSlice{} +var CapstoneModeOptions = map[uint64]OptionSlice{ + uint64(capstone.ARCH_ARM): {{uint64(capstone.MODE_ARM), "ARM"}, {uint64(capstone.MODE_THUMB), "THUMB"}, {uint64(capstone.MODE_MCLASS), "MCLASS"}, {uint64(capstone.MODE_V8), "V8"}}, + uint64(capstone.ARCH_ARM64): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_MIPS): {{uint64(capstone.MODE_MIPS32), "MIPS32"}, {uint64(capstone.MODE_MIPS64), "MIPS64"}, {uint64(capstone.MODE_MICRO), "MICRO"}, {uint64(capstone.MODE_MIPS3), "MIPS3"}, {uint64(capstone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(capstone.MODE_MIPS2), "MIPS2"}}, + uint64(capstone.ARCH_X86): {{uint64(capstone.MODE_16), "16"}, {uint64(capstone.MODE_32), "32"}, {uint64(capstone.MODE_64), "64"}}, + uint64(capstone.ARCH_PPC): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}, {uint64(capstone.MODE_QPX), "QPX"}, {uint64(capstone.MODE_SPE), "SPE"}, {uint64(capstone.MODE_BOOKE), "BOOKE"}}, + uint64(capstone.ARCH_SPARC): {{uint64(capstone.MODE_V9), "V9"}}, + uint64(capstone.ARCH_SYSZ): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(capstone.ARCH_XCORE): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_M68K): {{uint64(capstone.MODE_M68K_000), "M68K_000"}, {uint64(capstone.MODE_M68K_010), "M68K_010"}, {uint64(capstone.MODE_M68K_020), "M68K_020"}, {uint64(capstone.MODE_M68K_030), "M68K_030"}, {uint64(capstone.MODE_M68K_040), "M68K_040"}, {uint64(capstone.MODE_M68K_060), "M68K_060"}}, + uint64(capstone.ARCH_M680X): {{uint64(capstone.MODE_M680X_6301), "M680X_6301"}, {uint64(capstone.MODE_M680X_6309), "M680X_6309"}, {uint64(capstone.MODE_M680X_6800), "M680X_6800"}, {uint64(capstone.MODE_M680X_6801), "M680X_6801"}, {uint64(capstone.MODE_M680X_6805), "M680X_6805"}, {uint64(capstone.MODE_M680X_6808), "M680X_6808"}, {uint64(capstone.MODE_M680X_6809), "M680X_6809"}, {uint64(capstone.MODE_M680X_6811), "M680X_6811"}, {uint64(capstone.MODE_M680X_CPU12), "M680X_CPU12"}, {uint64(capstone.MODE_M680X_HCS08), "M680X_HCS08"}}, + uint64(capstone.ARCH_EVM): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, + uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.MODE_MOS65XX_6502), "MOS65XX_6502"}, {uint64(capstone.MODE_MOS65XX_65C02), "MOS65XX_65C02"}, {uint64(capstone.MODE_MOS65XX_W65C02), "MOS65XX_W65C02"}, {uint64(capstone.MODE_MOS65XX_65816), "MOS65XX_65816"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_M), "MOS65XX_65816_LONG_M"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_X), "MOS65XX_65816_LONG_X"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_MX), "MOS65XX_65816_LONG_MX"}}, + uint64(capstone.ARCH_WASM): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, + uint64(capstone.ARCH_BPF): {{uint64(capstone.MODE_BPF_CLASSIC), "BPF_CLASSIC"}, {uint64(capstone.MODE_BPF_EXTENDED), "BPF_EXTENDED"}}, + uint64(capstone.ARCH_RISCV): {{uint64(capstone.MODE_RISCV32), "RISCV32"}, {uint64(capstone.MODE_RISCV64), "RISCV64"}, {uint64(capstone.MODE_RISCVC), "RISCVC"}}, + uint64(capstone.ARCH_SH): {{uint64(capstone.MODE_SH2), "SH2"}, {uint64(capstone.MODE_SH2A), "SH2A"}, {uint64(capstone.MODE_SH3), "SH3"}, {uint64(capstone.MODE_SH4), "SH4"}, {uint64(capstone.MODE_SH4A), "SH4A"}, {uint64(capstone.MODE_SHFPU), "SHFPU"}, {uint64(capstone.MODE_SHDSP), "SHDSP"}}, + uint64(capstone.ARCH_TRICORE): {{uint64(capstone.MODE_TRICORE_110), "TRICORE_110"}, {uint64(capstone.MODE_TRICORE_120), "TRICORE_120"}, {uint64(capstone.MODE_TRICORE_130), "TRICORE_130"}, {uint64(capstone.MODE_TRICORE_131), "TRICORE_131"}, {uint64(capstone.MODE_TRICORE_160), "TRICORE_160"}, {uint64(capstone.MODE_TRICORE_161), "TRICORE_161"}, {uint64(capstone.MODE_TRICORE_162), "TRICORE_162"}}, +} + +// var CapstoneSyntaxList = OptionSlice{} +// var CapstoneSyntaxOptions = map[uint64]OptionSlice{ +// uint64(capstone.ARCH_ARM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_ARM64): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_MIPS): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_X86): {{uint64(capstone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(capstone.OPT_SYNTAX_ATT), "ATT"}, {uint64(capstone.OPT_SYNTAX_MASM), "MASM"}}, +// uint64(capstone.ARCH_PPC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_SPARC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_SYSZ): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_XCORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_M68K): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_TMS320C64X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, +// uint64(capstone.ARCH_M680X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_EVM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, +// uint64(capstone.ARCH_WASM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_BPF): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_RISCV): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_SH): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// uint64(capstone.ARCH_TRICORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, +// } + +func Disassemble(arch capstone.Architecture, mode capstone.Mode, code []byte, offset uint64, bigEndian bool /*syntaxValue capstone.OptionValue, */, addAddress bool) (string, uint64, bool, error) { + defer func() { + if r := recover(); r != nil { + return + } + }() + + engine, err := capstone.New(arch, mode) + if err != nil { + return "", 0, false, err + } + defer engine.Close() + + // if syntaxValue != 0 { + // engine.Option(capstone.OPT_SYNTAX, capstone.OptionValue(syntaxValue)) + // } + + if bigEndian { + code, err = capstoneToBigEndian(code, arch, mode) + if err != nil { + return "", 0, false, err + } + } + + insns, err := engine.Disasm(code, offset, 0) + if err != nil { + return "", 0, false, err + } + + var result string + for _, insn := range insns { + if addAddress { + result += fmt.Sprintf("%08X:\t%-6s\t%-20s\n", insn.Address(), insn.Mnemonic(), insn.OpStr()) + } else { + result += fmt.Sprintf("%-6s\t%-20s\n", insn.Mnemonic(), insn.OpStr()) + } + } + + return result, uint64(len(insns)), true, nil +} +func Assemble(arch keystone.Architecture, mode keystone.Mode, code string, offset uint64, bigEndian bool /*, syntaxValue keystone.OptionValue*/) ([]byte, uint64, bool, error) { + defer func() { + if r := recover(); r != nil { + return + } + }() + + code = strings.TrimSpace(code) + if code == "" { + return nil, 0, false, fmt.Errorf("empty code") + } + if strings.HasPrefix(code, ";") { + return nil, 0, false, fmt.Errorf("commented code") + } + if idx := strings.Index(code, ";"); idx > 0 { + code = code[:idx] + } + + ks, err := keystone.New(keystone.Architecture(arch), keystone.Mode(mode)) + if err != nil { + return nil, 0, false, err + } + defer ks.Close() + + // if syntaxValue != 0 { + // ks.Option(keystone.OPT_SYNTAX, keystone.OptionValue(syntaxValue)) + // } + + encoding, stat_count, ok := ks.Assemble(code, offset) + if err := ks.LastError(); err != nil { + return nil, 0, false, err + } + + if ok && bigEndian { + encoding, err = keystoneToBigEndian(encoding, arch, mode) + if err != nil { + return nil, 0, false, err + } + } + + return encoding, stat_count, ok, nil +} diff --git a/archs/utils.go b/archs/utils.go index 7a769d8..39697bd 100644 --- a/archs/utils.go +++ b/archs/utils.go @@ -1,3 +1,5 @@ +//go:build !build_riscv + package archs import ( diff --git a/archs/utils_riscv.go b/archs/utils_riscv.go new file mode 100644 index 0000000..779f647 --- /dev/null +++ b/archs/utils_riscv.go @@ -0,0 +1,221 @@ +//go:build build_riscv + +package archs + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/suifei/asm2hex/bindings/capstone" + "github.com/suifei/asm2hex/bindings/keystone" +) + +func capstoneToBigEndian(data []byte, arch capstone.Architecture, mode capstone.Mode) ([]byte, error) { + if len(data) == 0 { + return nil, fmt.Errorf("input data is empty") + } + + instructionLength := getCapstoneInstructionLength(arch, mode) + if instructionLength == 0 { + return nil, fmt.Errorf("unsupported architecture or mode") + } + + if len(data)%instructionLength != 0 { + return nil, fmt.Errorf("input data size is not a multiple of instruction length") + } + + result := make([]byte, 0, len(data)) + + for i := 0; i < len(data); i += instructionLength { + instruction := data[i : i+instructionLength] + bigEndianInstruction, err := littleToBigEndian(instruction) + if err != nil { + return nil, fmt.Errorf("failed to convert instruction at offset %d: %v", i, err) + } + result = append(result, bigEndianInstruction...) + } + + return result, nil +} + +func keystoneToBigEndian(data []byte, arch keystone.Architecture, mode keystone.Mode) ([]byte, error) { + if len(data) == 0 { + return nil, fmt.Errorf("input data is empty") + } + + instructionLength := getKeystoneInstructionLength(arch, mode) + if instructionLength == 0 { + return nil, fmt.Errorf("unsupported architecture or mode") + } + + if len(data)%instructionLength != 0 { + return nil, fmt.Errorf("input data size is not a multiple of instruction length") + } + + result := make([]byte, 0, len(data)) + + for i := 0; i < len(data); i += instructionLength { + instruction := data[i : i+instructionLength] + bigEndianInstruction, err := littleToBigEndian(instruction) + if err != nil { + return nil, fmt.Errorf("failed to convert instruction at offset %d: %v", i, err) + } + result = append(result, bigEndianInstruction...) + } + + return result, nil +} + +func getCapstoneInstructionLength(arch capstone.Architecture, mode capstone.Mode) int { + switch arch { + case capstone.ARCH_ARM: + if mode&capstone.MODE_THUMB != 0 { + return 2 + } + return 4 + case capstone.ARCH_ARM64: + return 4 + case capstone.ARCH_MIPS: + if mode&capstone.MODE_MICRO != 0 { + return 2 + } + return 4 + case capstone.ARCH_X86: + if mode&capstone.MODE_16 != 0 { + return 2 + } + return 1 + case capstone.ARCH_PPC: + return 4 + case capstone.ARCH_SPARC: + return 4 + case capstone.ARCH_SYSZ: + return 2 + case capstone.ARCH_XCORE: + return 2 + case capstone.ARCH_M68K: + return 2 + case capstone.ARCH_TMS320C64X: + return 4 + case capstone.ARCH_M680X: + return 1 + case capstone.ARCH_EVM: + return 1 + case capstone.ARCH_MOS65XX: + return 1 + case capstone.ARCH_WASM: + return 1 + case capstone.ARCH_BPF: + return 8 + case capstone.ARCH_RISCV: + if mode&capstone.MODE_RISCV32 != 0 { + return 4 + } + return 2 + case capstone.ARCH_SH: + if mode&capstone.MODE_SH2 != 0 || mode&capstone.MODE_SH2A != 0 { + return 2 + } + return 2 + case capstone.ARCH_TRICORE: + return 2 + default: + return 0 + } +} + +func getKeystoneInstructionLength(arch keystone.Architecture, mode keystone.Mode) int { + switch arch { + case keystone.ARCH_ARM: + if mode&keystone.MODE_THUMB != 0 { + return 2 + } + return 4 + case keystone.ARCH_ARM64: + return 4 + case keystone.ARCH_MIPS: + if mode&keystone.MODE_MICRO != 0 { + return 2 + } + if mode&keystone.MODE_MIPS32 != 0 || mode&keystone.MODE_MIPS32R6 != 0 { + return 4 + } + if mode&keystone.MODE_MIPS64 != 0 { + return 4 + } + return 4 + case keystone.ARCH_X86: + if mode&keystone.MODE_16 != 0 { + return 2 + } + return 1 + case keystone.ARCH_PPC: + if mode&keystone.MODE_PPC32 != 0 { + return 4 + } + if mode&keystone.MODE_PPC64 != 0 { + return 4 + } + return 4 + case keystone.ARCH_SPARC: + if mode&keystone.MODE_SPARC32 != 0 { + return 4 + } + if mode&keystone.MODE_SPARC64 != 0 { + return 4 + } + return 4 + case keystone.ARCH_RISCV: + if mode&keystone.MODE_RISCV32 != 0 { + return 2 + } + if mode&keystone.MODE_RISCV64 != 0 { + return 4 + } + case keystone.ARCH_SYSTEMZ: + return 2 + case keystone.ARCH_HEXAGON: + return 4 + case keystone.ARCH_EVM: + return 1 + default: + return 0 + } +} + +func littleToBigEndian(data []byte) ([]byte, error) { + switch len(data) { + case 1: + return data, nil + case 2: + var num uint16 + err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &num) + if err != nil { + return nil, err + } + result := make([]byte, 2) + binary.BigEndian.PutUint16(result, num) + return result, nil + case 4: + var num uint32 + err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &num) + if err != nil { + return nil, err + } + result := make([]byte, 4) + binary.BigEndian.PutUint32(result, num) + return result, nil + case 8: + var num uint64 + err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &num) + if err != nil { + return nil, err + } + result := make([]byte, 8) + binary.BigEndian.PutUint64(result, num) + return result, nil + default: + return nil, fmt.Errorf("unsupported instruction size: %d", len(data)) + } +} diff --git a/bindings/keystone/keystone_const.go b/bindings/keystone/keystone_const.go index 434c097..dc44ee7 100644 --- a/bindings/keystone/keystone_const.go +++ b/bindings/keystone/keystone_const.go @@ -1,3 +1,5 @@ +//go:build !build_riscv + package keystone // For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.go] diff --git a/bindings/keystone/keystone_const_riscv.go b/bindings/keystone/keystone_const_riscv.go new file mode 100644 index 0000000..03f5060 --- /dev/null +++ b/bindings/keystone/keystone_const_riscv.go @@ -0,0 +1,111 @@ +//go:build build_riscv + +package keystone + +const ( + API_MAJOR = 0 + API_MINOR = 9 +) + +const ( + MODE_LITTLE_ENDIAN Mode = 0 + MODE_BIG_ENDIAN Mode = 1073741824 + MODE_ARM Mode = 1 + MODE_THUMB Mode = 16 + MODE_V8 Mode = 64 + MODE_MICRO Mode = 16 + MODE_MIPS3 Mode = 32 + MODE_MIPS32R6 Mode = 64 + MODE_MIPS32 Mode = 4 + MODE_MIPS64 Mode = 8 + MODE_16 Mode = 2 + MODE_32 Mode = 4 + MODE_64 Mode = 8 + MODE_PPC32 Mode = 4 + MODE_PPC64 Mode = 8 + MODE_QPX Mode = 16 + MODE_RISCV32 Mode = 4 + MODE_RISCV64 Mode = 8 + MODE_SPARC32 Mode = 4 + MODE_SPARC64 Mode = 8 + MODE_V9 Mode = 16 +) + +const ( + ARCH_ARM Architecture = 1 + ARCH_ARM64 Architecture = 2 + ARCH_MIPS Architecture = 3 + ARCH_X86 Architecture = 4 + ARCH_PPC Architecture = 5 + ARCH_RISCV Architecture = 6 + ARCH_SPARC Architecture = 7 + ARCH_SYSTEMZ Architecture = 8 + ARCH_HEXAGON Architecture = 9 + ARCH_EVM Architecture = 10 + ARCH_MAX Architecture = 11 +) + +const ( + OPT_SYNTAX OptionType = 1 +) + +const ( + OPT_SYM_RESOLVER OptionValue = 2 + OPT_SYNTAX_INTEL OptionValue = 1 + OPT_SYNTAX_ATT OptionValue = 2 + OPT_SYNTAX_NASM OptionValue = 4 + OPT_SYNTAX_MASM OptionValue = 8 + OPT_SYNTAX_GAS OptionValue = 16 + OPT_SYNTAX_RADIX16 OptionValue = 32 +) + +const ( + ERR_ASM Error = 128 + ERR_ASM_ARCH Error = 512 + ERR_OK Error = 0 + ERR_NOMEM Error = 1 + ERR_ARCH Error = 2 + ERR_HANDLE Error = 3 + ERR_MODE Error = 4 + ERR_VERSION Error = 5 + ERR_OPT_INVALID Error = 6 + ERR_ASM_EXPR_TOKEN Error = 128 + ERR_ASM_DIRECTIVE_VALUE_RANGE Error = 129 + ERR_ASM_DIRECTIVE_ID Error = 130 + ERR_ASM_DIRECTIVE_TOKEN Error = 131 + ERR_ASM_DIRECTIVE_STR Error = 132 + ERR_ASM_DIRECTIVE_COMMA Error = 133 + ERR_ASM_DIRECTIVE_RELOC_NAME Error = 134 + ERR_ASM_DIRECTIVE_RELOC_TOKEN Error = 135 + ERR_ASM_DIRECTIVE_FPOINT Error = 136 + ERR_ASM_DIRECTIVE_UNKNOWN Error = 137 + ERR_ASM_DIRECTIVE_EQU Error = 138 + ERR_ASM_DIRECTIVE_INVALID Error = 139 + ERR_ASM_VARIANT_INVALID Error = 140 + ERR_ASM_EXPR_BRACKET Error = 141 + ERR_ASM_SYMBOL_MODIFIER Error = 142 + ERR_ASM_SYMBOL_REDEFINED Error = 143 + ERR_ASM_SYMBOL_MISSING Error = 144 + ERR_ASM_RPAREN Error = 145 + ERR_ASM_STAT_TOKEN Error = 146 + ERR_ASM_UNSUPPORTED Error = 147 + ERR_ASM_MACRO_TOKEN Error = 148 + ERR_ASM_MACRO_PAREN Error = 149 + ERR_ASM_MACRO_EQU Error = 150 + ERR_ASM_MACRO_ARGS Error = 151 + ERR_ASM_MACRO_LEVELS_EXCEED Error = 152 + ERR_ASM_MACRO_STR Error = 153 + ERR_ASM_MACRO_INVALID Error = 154 + ERR_ASM_ESC_BACKSLASH Error = 155 + ERR_ASM_ESC_OCTAL Error = 156 + ERR_ASM_ESC_SEQUENCE Error = 157 + ERR_ASM_ESC_STR Error = 158 + ERR_ASM_TOKEN_INVALID Error = 159 + ERR_ASM_INSN_UNSUPPORTED Error = 160 + ERR_ASM_FIXUP_INVALID Error = 161 + ERR_ASM_LABEL_INVALID Error = 162 + ERR_ASM_FRAGMENT_INVALID Error = 163 + ERR_ASM_INVALIDOPERAND Error = 512 + ERR_ASM_MISSINGFEATURE Error = 513 + ERR_ASM_MNEMONICFAIL Error = 514 +) \ No newline at end of file diff --git a/bindings/keystone/riscv_const.go b/bindings/keystone/riscv_const.go new file mode 100644 index 0000000..e80444d --- /dev/null +++ b/bindings/keystone/riscv_const.go @@ -0,0 +1,9 @@ +//go:build build_riscv + +package keystone + +const ( + ERR_ASM_RISCV_INVALIDOPERAND Error = 512 + ERR_ASM_RISCV_MISSINGFEATURE Error = 513 + ERR_ASM_RISCV_MNEMONICFAIL Error = 514 +) \ No newline at end of file diff --git a/main.go b/main.go index eaae5df..8b720ac 100644 --- a/main.go +++ b/main.go @@ -44,113 +44,6 @@ var prefix_hex bool = false var offset uint64 = 0 var bigEndian bool = false var addAddress bool = false - -type Option struct { - Const uint64 - Name string -} - -type OptionSlice []Option - -var keystoneArchOptions = OptionSlice{ - {uint64(keystone.ARCH_ARM), "ARM"}, - {uint64(keystone.ARCH_ARM64), "ARM64"}, - {uint64(keystone.ARCH_MIPS), "MIPS"}, - {uint64(keystone.ARCH_X86), "X86"}, - {uint64(keystone.ARCH_PPC), "PPC"}, - {uint64(keystone.ARCH_SPARC), "SPARC"}, - {uint64(keystone.ARCH_SYSTEMZ), "SYSTEMZ"}, - {uint64(keystone.ARCH_HEXAGON), "HEXAGON"}, -} - -var _keystoneModeOptions = OptionSlice{} -var keystoneModeOptions = map[uint64]OptionSlice{ - uint64(keystone.ARCH_ARM): {{uint64(keystone.MODE_ARM), "ARM"}, {uint64(keystone.MODE_THUMB), "THUMB"}, {uint64(keystone.MODE_V8), "V8"}}, - uint64(keystone.ARCH_ARM64): {{uint64(keystone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, - uint64(keystone.ARCH_MIPS): {{uint64(keystone.MODE_MICRO), "MICRO"}, {uint64(keystone.MODE_MIPS3), "MIPS3"}, {uint64(keystone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(keystone.MODE_MIPS32), "MIPS32"}, {uint64(keystone.MODE_MIPS64), "MIPS64"}}, - uint64(keystone.ARCH_X86): {{uint64(keystone.MODE_16), "16"}, {uint64(keystone.MODE_32), "32"}, {uint64(keystone.MODE_64), "64"}}, - uint64(keystone.ARCH_PPC): {{uint64(keystone.MODE_PPC32), "PPC32"}, {uint64(keystone.MODE_PPC64), "PPC64"}, {uint64(keystone.MODE_QPX), "QPX"}}, - uint64(keystone.ARCH_SPARC): {{uint64(keystone.MODE_SPARC32), "SPARC32"}, {uint64(keystone.MODE_SPARC64), "SPARC64"}, {uint64(keystone.MODE_V9), "V9"}}, - uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, - uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, -} - -// var _keystoneSyntaxOptions = OptionSlice{} -// var keystoneSyntaxOptions = map[uint64]OptionSlice{ -// uint64(keystone.ARCH_ARM): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_ARM64): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_MIPS): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_X86): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}, {uint64(keystone.OPT_SYNTAX_NASM), "NASM"}, {uint64(keystone.OPT_SYNTAX_MASM), "MASM"}, {uint64(keystone.OPT_SYNTAX_GAS), "GAS"}, {uint64(keystone.OPT_SYNTAX_RADIX16), "Radix16"}}, -// uint64(keystone.ARCH_PPC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_SPARC): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_SYSTEMZ): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(keystone.OPT_SYNTAX_ATT), "ATT"}}, -// uint64(keystone.ARCH_HEXAGON): {{uint64(keystone.OPT_SYNTAX_INTEL), "Intel"}}, -// } - -var capstoneArchOptions = OptionSlice{ - {uint64(capstone.ARCH_ARM), "ARM"}, - {uint64(capstone.ARCH_ARM64), "ARM64"}, - {uint64(capstone.ARCH_MIPS), "MIPS"}, - {uint64(capstone.ARCH_X86), "X86"}, - {uint64(capstone.ARCH_PPC), "PPC"}, - {uint64(capstone.ARCH_SPARC), "SPARC"}, - {uint64(capstone.ARCH_SYSZ), "SYSZ"}, - {uint64(capstone.ARCH_XCORE), "XCORE"}, - {uint64(capstone.ARCH_M68K), "M68K"}, - {uint64(capstone.ARCH_TMS320C64X), "TMS320C64X"}, - {uint64(capstone.ARCH_M680X), "M680X"}, - {uint64(capstone.ARCH_EVM), "EVM"}, - {uint64(capstone.ARCH_MOS65XX), "MOS65XX"}, - {uint64(capstone.ARCH_WASM), "WASM"}, - {uint64(capstone.ARCH_BPF), "BPF"}, - {uint64(capstone.ARCH_RISCV), "RISCV"}, - {uint64(capstone.ARCH_SH), "SH"}, - {uint64(capstone.ARCH_TRICORE), "TRICORE"}, -} - -var _capstoneModeOptions = OptionSlice{} -var capstoneModeOptions = map[uint64]OptionSlice{ - uint64(capstone.ARCH_ARM): {{uint64(capstone.MODE_ARM), "ARM"}, {uint64(capstone.MODE_THUMB), "THUMB"}, {uint64(capstone.MODE_MCLASS), "MCLASS"}, {uint64(capstone.MODE_V8), "V8"}}, - uint64(capstone.ARCH_ARM64): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, - uint64(capstone.ARCH_MIPS): {{uint64(capstone.MODE_MIPS32), "MIPS32"}, {uint64(capstone.MODE_MIPS64), "MIPS64"}, {uint64(capstone.MODE_MICRO), "MICRO"}, {uint64(capstone.MODE_MIPS3), "MIPS3"}, {uint64(capstone.MODE_MIPS32R6), "MIPS32R6"}, {uint64(capstone.MODE_MIPS2), "MIPS2"}}, - uint64(capstone.ARCH_X86): {{uint64(capstone.MODE_16), "16"}, {uint64(capstone.MODE_32), "32"}, {uint64(capstone.MODE_64), "64"}}, - uint64(capstone.ARCH_PPC): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}, {uint64(capstone.MODE_QPX), "QPX"}, {uint64(capstone.MODE_SPE), "SPE"}, {uint64(capstone.MODE_BOOKE), "BOOKE"}}, - uint64(capstone.ARCH_SPARC): {{uint64(capstone.MODE_V9), "V9"}}, - uint64(capstone.ARCH_SYSZ): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, - uint64(capstone.ARCH_XCORE): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, - uint64(capstone.ARCH_M68K): {{uint64(capstone.MODE_M68K_000), "M68K_000"}, {uint64(capstone.MODE_M68K_010), "M68K_010"}, {uint64(capstone.MODE_M68K_020), "M68K_020"}, {uint64(capstone.MODE_M68K_030), "M68K_030"}, {uint64(capstone.MODE_M68K_040), "M68K_040"}, {uint64(capstone.MODE_M68K_060), "M68K_060"}}, - uint64(capstone.ARCH_M680X): {{uint64(capstone.MODE_M680X_6301), "M680X_6301"}, {uint64(capstone.MODE_M680X_6309), "M680X_6309"}, {uint64(capstone.MODE_M680X_6800), "M680X_6800"}, {uint64(capstone.MODE_M680X_6801), "M680X_6801"}, {uint64(capstone.MODE_M680X_6805), "M680X_6805"}, {uint64(capstone.MODE_M680X_6808), "M680X_6808"}, {uint64(capstone.MODE_M680X_6809), "M680X_6809"}, {uint64(capstone.MODE_M680X_6811), "M680X_6811"}, {uint64(capstone.MODE_M680X_CPU12), "M680X_CPU12"}, {uint64(capstone.MODE_M680X_HCS08), "M680X_HCS08"}}, - uint64(capstone.ARCH_EVM): {{uint64(capstone.MODE_BIG_ENDIAN), "BIG_ENDIAN"}}, - uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.MODE_MOS65XX_6502), "MOS65XX_6502"}, {uint64(capstone.MODE_MOS65XX_65C02), "MOS65XX_65C02"}, {uint64(capstone.MODE_MOS65XX_W65C02), "MOS65XX_W65C02"}, {uint64(capstone.MODE_MOS65XX_65816), "MOS65XX_65816"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_M), "MOS65XX_65816_LONG_M"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_X), "MOS65XX_65816_LONG_X"}, {uint64(capstone.MODE_MOS65XX_65816_LONG_MX), "MOS65XX_65816_LONG_MX"}}, - uint64(capstone.ARCH_WASM): {{uint64(capstone.MODE_LITTLE_ENDIAN), "LITTLE_ENDIAN"}}, - uint64(capstone.ARCH_BPF): {{uint64(capstone.MODE_BPF_CLASSIC), "BPF_CLASSIC"}, {uint64(capstone.MODE_BPF_EXTENDED), "BPF_EXTENDED"}}, - uint64(capstone.ARCH_RISCV): {{uint64(capstone.MODE_RISCV32), "RISCV32"}, {uint64(capstone.MODE_RISCV64), "RISCV64"}, {uint64(capstone.MODE_RISCVC), "RISCVC"}}, - uint64(capstone.ARCH_SH): {{uint64(capstone.MODE_SH2), "SH2"}, {uint64(capstone.MODE_SH2A), "SH2A"}, {uint64(capstone.MODE_SH3), "SH3"}, {uint64(capstone.MODE_SH4), "SH4"}, {uint64(capstone.MODE_SH4A), "SH4A"}, {uint64(capstone.MODE_SHFPU), "SHFPU"}, {uint64(capstone.MODE_SHDSP), "SHDSP"}}, - uint64(capstone.ARCH_TRICORE): {{uint64(capstone.MODE_TRICORE_110), "TRICORE_110"}, {uint64(capstone.MODE_TRICORE_120), "TRICORE_120"}, {uint64(capstone.MODE_TRICORE_130), "TRICORE_130"}, {uint64(capstone.MODE_TRICORE_131), "TRICORE_131"}, {uint64(capstone.MODE_TRICORE_160), "TRICORE_160"}, {uint64(capstone.MODE_TRICORE_161), "TRICORE_161"}, {uint64(capstone.MODE_TRICORE_162), "TRICORE_162"}}, -} - -// var _capstoneSyntaxOptions = OptionSlice{} -// var capstoneSyntaxOptions = map[uint64]OptionSlice{ -// uint64(capstone.ARCH_ARM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_ARM64): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_MIPS): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_X86): {{uint64(capstone.OPT_SYNTAX_INTEL), "Intel"}, {uint64(capstone.OPT_SYNTAX_ATT), "ATT"}, {uint64(capstone.OPT_SYNTAX_MASM), "MASM"}}, -// uint64(capstone.ARCH_PPC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_SPARC): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_SYSZ): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_XCORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_M68K): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, -// uint64(capstone.ARCH_TMS320C64X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}}, -// uint64(capstone.ARCH_M680X): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_NOREGNAME), "NOREGNAME"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, -// uint64(capstone.ARCH_EVM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// uint64(capstone.ARCH_MOS65XX): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}, {uint64(capstone.OPT_SYNTAX_MOTOROLA), "Motorola"}}, -// uint64(capstone.ARCH_WASM): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// uint64(capstone.ARCH_BPF): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// uint64(capstone.ARCH_RISCV): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// uint64(capstone.ARCH_SH): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// uint64(capstone.ARCH_TRICORE): {{uint64(capstone.OPT_SYNTAX_DEFAULT), "Default"}}, -// } - type Param struct { Arch uint64 Mode uint64 @@ -186,7 +79,7 @@ var asm2hexTools *fyne.Container var hex2asmTools *fyne.Container var output1_info *widget.Label -func getOptionNames(options OptionSlice) []string { +func getOptionNames(options archs.OptionSlice) []string { names := make([]string, len(options)) for i, option := range options { names[i] = option.Name @@ -199,40 +92,40 @@ func toJson(o interface{}) string { } func updateSelectParam() { if keystoneArchDropdown != nil && keystoneArchDropdown.SelectedIndex() != -1 { - mapKey := keystoneArchOptions[keystoneArchDropdown.SelectedIndex()].Const + mapKey := archs.KeystoneArchOptions[keystoneArchDropdown.SelectedIndex()].Const KSSelectParam.Arch = mapKey KSSelectParam.Info = keystoneArchDropdown.Selected } if capstoneArchDropdown != nil && capstoneArchDropdown.SelectedIndex() != -1 { - mapKey := capstoneArchOptions[capstoneArchDropdown.SelectedIndex()].Const + mapKey := archs.CapstoneArchOptions[capstoneArchDropdown.SelectedIndex()].Const CSSelectParam.Arch = mapKey CSSelectParam.Info = capstoneArchDropdown.Selected } - if keystoneModeDropdown != nil && _keystoneModeOptions != nil { + if keystoneModeDropdown != nil && archs.KeystoneModeList != nil { index := keystoneModeDropdown.SelectedIndex() - if index >= 0 && index < len(_keystoneModeOptions) { - KSSelectParam.Mode = _keystoneModeOptions[index].Const + if index >= 0 && index < len(archs.KeystoneModeList) { + KSSelectParam.Mode = archs.KeystoneModeList[index].Const KSSelectParam.Info += " " + keystoneModeDropdown.Selected } } - if capstoneModeDropdown != nil && _capstoneModeOptions != nil { + if capstoneModeDropdown != nil && archs.CapstoneModeList != nil { index := capstoneModeDropdown.SelectedIndex() - if index >= 0 && index < len(_capstoneModeOptions) { - CSSelectParam.Mode = _capstoneModeOptions[index].Const + if index >= 0 && index < len(archs.CapstoneModeList) { + CSSelectParam.Mode = archs.CapstoneModeList[index].Const CSSelectParam.Info += " " + capstoneModeDropdown.Selected } } - // if keystoneSyntaxDropdown != nil && _keystoneSyntaxOptions != nil { + // if keystoneSyntaxDropdown != nil && archs.KeystoneSyntaxList != nil { // index := keystoneSyntaxDropdown.SelectedIndex() - // if index >= 0 && index < len(_keystoneSyntaxOptions) { - // KSSelectParam.Syntax = _keystoneSyntaxOptions[index].Const + // if index >= 0 && index < len(archs.KeystoneSyntaxList) { + // KSSelectParam.Syntax = archs.KeystoneSyntaxList[index].Const // KSSelectParam.Info += " " + keystoneSyntaxDropdown.Selected // } // } - // if capstoneSyntaxDropdown != nil && _capstoneSyntaxOptions != nil { + // if capstoneSyntaxDropdown != nil && archs.CapstoneSyntaxList != nil { // index := capstoneSyntaxDropdown.SelectedIndex() - // if index >= 0 && index < len(_capstoneSyntaxOptions) { - // CSSelectParam.Syntax = _capstoneSyntaxOptions[index].Const + // if index >= 0 && index < len(archs.CapstoneSyntaxList) { + // CSSelectParam.Syntax = archs.CapstoneSyntaxList[index].Const // CSSelectParam.Info += " " + capstoneSyntaxDropdown.Selected // } // } @@ -256,18 +149,18 @@ func updateSelectParam() { func createDropdowns() *fyne.Container { keystoneArchDropdown = &widget.Select{} keystoneArchDropdown.ExtendBaseWidget(keystoneArchDropdown) - keystoneArchDropdown.SetOptions(getOptionNames(keystoneArchOptions)) + keystoneArchDropdown.SetOptions(getOptionNames(archs.KeystoneArchOptions)) keystoneArchDropdown.OnChanged = func(s string) { // fmt.Println("Keystone Arch:", s) // fmt.Println(keystoneArchDropdown.SelectedIndex()) - mapKey := keystoneArchOptions[keystoneArchDropdown.SelectedIndex()].Const - if options, ok := keystoneModeOptions[mapKey]; ok && keystoneModeDropdown != nil { - _keystoneModeOptions = options + mapKey := archs.KeystoneArchOptions[keystoneArchDropdown.SelectedIndex()].Const + if options, ok := archs.KeystoneModeOptions[mapKey]; ok && keystoneModeDropdown != nil { + archs.KeystoneModeList = options keystoneModeDropdown.SetOptions(getOptionNames(options)) keystoneModeDropdown.SetSelectedIndex(0) } - // if options, ok := keystoneSyntaxOptions[mapKey]; ok && keystoneSyntaxDropdown != nil { - // _keystoneSyntaxOptions = options + // if options, ok := KeystoneSyntaxOptions[mapKey]; ok && keystoneSyntaxDropdown != nil { + // KeystoneSyntaxList = options // keystoneSyntaxDropdown.SetOptions(getOptionNames(options)) // keystoneSyntaxDropdown.SetSelectedIndex(0) // } @@ -290,18 +183,18 @@ func createDropdowns() *fyne.Container { capstoneArchDropdown = &widget.Select{} capstoneArchDropdown.ExtendBaseWidget(capstoneArchDropdown) - capstoneArchDropdown.SetOptions(getOptionNames(capstoneArchOptions)) + capstoneArchDropdown.SetOptions(getOptionNames(archs.CapstoneArchOptions)) capstoneArchDropdown.OnChanged = func(s string) { // fmt.Println("Capstone Arch:", s) // fmt.Println(capstoneArchDropdown.SelectedIndex()) - mapKey := capstoneArchOptions[capstoneArchDropdown.SelectedIndex()].Const - if options, ok := capstoneModeOptions[mapKey]; ok && capstoneModeDropdown != nil { - _capstoneModeOptions = options + mapKey := archs.CapstoneArchOptions[capstoneArchDropdown.SelectedIndex()].Const + if options, ok := archs.CapstoneModeOptions[mapKey]; ok && capstoneModeDropdown != nil { + archs.CapstoneModeList = options capstoneModeDropdown.SetOptions(getOptionNames(options)) capstoneModeDropdown.SetSelectedIndex(0) } - // if options, ok := capstoneSyntaxOptions[mapKey]; ok && capstoneSyntaxDropdown != nil { - // _capstoneSyntaxOptions = options + // if options, ok := CapstoneSyntaxOptions[mapKey]; ok && capstoneSyntaxDropdown != nil { + // CapstoneSyntaxList = options // capstoneSyntaxDropdown.SetOptions(getOptionNames(options)) // capstoneSyntaxDropdown.SetSelectedIndex(0) // } @@ -484,8 +377,12 @@ cbnz r0, #0x682c4 app_title := canvas.NewText(ApplicationTitle, color.NRGBA{0, 0x80, 0, 0xff}) app_title.TextSize = 24 + app_ver := fyne.CurrentApp().Metadata().Version + if archs.WithRiscv { + app_ver += " (RISC-V)" + } about_messages := "ASM to HEX Converter\n\n" + - "Version: " + fyne.CurrentApp().Metadata().Version + "\n" + + "Version: " + app_ver + "\n" + "Author: suifei suifei@gmail.com\n" + "License: MIT\n" + "Source code: https://github.com/suifei/asm2hex\n\n" +