commit fea9c6052fa60ba34fd44d6b85a48aca19d4534c Author: wingsummer <1326224942@qq.com> Date: Tue Aug 23 18:17:27 2022 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..5ee5d2c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/*.pro.user +push.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc2a911 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +

WingSummer.WingHexAsm

+ +

+WingHexPy +

WingHexAsm

+

+ +

+作者 +开源协议 +

+ +- 开源不易,给个 Star 或者 [捐助](#捐助) 吧 + +## WingHexDisasm + +  `WingHexAsm`是一个羽云十六进制编辑器插件,它具将汇编语句转为硬编码的能力,基于`keystone`反汇编引擎框架。 + +### 协议 + +  本插件仓库将采用`AGPL-3.0`协议,不得将该插件代码用于改协议之外的用途。 + +## 效果图 + +

+效果图 +

WingHexAsm

+

+ +## 注意事项 + +  本插件仅支持`SDKVERSION >= 8`以上的“羽云十六进制编辑器”,也就是 1.4.8 及其以上的版本(该版本未被发布,请自行编译,预计 2022/8/25 发布该版本)。 + +## 捐助 + +**

您的每一份支持都将是本项目推进的强大动力,十分感谢您的支持

** + +

+ +支付宝 +

感谢支持

+ +

+ +

+微信 +

感谢支持

+ +

+ +## 有关仓库 + +* Gitea : https://code.gitlink.org.cn/wingsummer/WingHexAsm +* Gitee : https://gitee.com/wing-cloud/wing-hex-asm diff --git a/WingHexAsm.json b/WingHexAsm.json new file mode 100644 index 0000000..1e81138 --- /dev/null +++ b/WingHexAsm.json @@ -0,0 +1,3 @@ +{ + "Keys" : [ ] +} diff --git a/WingHexAsm.pro b/WingHexAsm.pro new file mode 100644 index 0000000..9ea65ae --- /dev/null +++ b/WingHexAsm.pro @@ -0,0 +1,52 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2022-08-22T22:25:35 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = WingHexAsm +TEMPLATE = lib +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + winghexasm.cpp + +HEADERS += \ + winghexasm.h \ + ../WingHexExplorer/wing-hex-explorer.sourcecode/WingHexExplorer/plugin/iwingplugin.h \ + keystone/arm.h \ + keystone/arm64.h \ + keystone/evm.h \ + keystone/hexagon.h \ + keystone/keystone.h \ + keystone/mips.h \ + keystone/ppc.h \ + keystone/sparc.h \ + keystone/systemz.h \ + keystone/x86.h + +LIBS += $$PWD/keystone/libkeystone.a + +DISTFILES += WingHexAsm.json + +RESOURCES += \ + resource.qrc + +TRANSLATIONS += \ + $$PWD/WingHexAsm.ts + diff --git a/WingHexAsm.qm b/WingHexAsm.qm new file mode 100644 index 0000000..cd1fc8d Binary files /dev/null and b/WingHexAsm.qm differ diff --git a/WingHexAsm.ts b/WingHexAsm.ts new file mode 100644 index 0000000..6e8362b --- /dev/null +++ b/WingHexAsm.ts @@ -0,0 +1,69 @@ + + + + + WingHexAsm + + + Arch : + 架构: + + + + Mode : + 模式: + + + + AsmCode + 汇编 + + + + No Asm + 无汇编语句! + + + + + AsmWindow + 汇编窗口 + + + + + WingHexAsm + 羽云汇编器 + + + + Author + 作者 + + + + Sponsor + 赞助 + + + + A small assembly plugin for WingHexExplorer. + 一个轻量的羽云十六进制编辑器的汇编插件。 + + + + ERROR: failed on ks_open() + 【错误】ks_open() 执行错误 + + + + ERROR: failed on ks_asm() with count = %1, error code = %2 + 【错误】执行 ks_asm() 失败,此时 count = %1, error code = %2 + + + + ASMSuccessfully + 汇编成功! + + + diff --git a/img/README.md b/img/README.md new file mode 100644 index 0000000..815d761 --- /dev/null +++ b/img/README.md @@ -0,0 +1,16 @@ +## WingHexAsm + +  `WingHexAsm`是一个羽云十六进制编辑器插件,它具将汇编语句转为硬编码的能力,基于`keystone`反汇编引擎框架。 + +### 协议 + +  本插件仓库将采用`AGPL-3.0`协议,不得将该插件代码用于改协议之外的用途。 + +## 如何使用 + +  将插件注册到软件的插件系统当中之后,只需在文档中用鼠标框选字节,执行反汇编命令即可。 + +## 有关仓库 + +* Gitea : https://code.gitlink.org.cn/wingsummer/WingHexAsm +* Gitee : https://gitee.com/wing-cloud/wing-hex-asm diff --git a/img/icon.png b/img/icon.png new file mode 100644 index 0000000..c3aa204 Binary files /dev/null and b/img/icon.png differ diff --git a/keystone/arm.h b/keystone/arm.h new file mode 100644 index 0000000..f4d2489 --- /dev/null +++ b/keystone/arm.h @@ -0,0 +1,23 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_ARM_H +#define KEYSTONE_ARM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_arm { + KS_ERR_ASM_ARM_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_ARM_MISSINGFEATURE, + KS_ERR_ASM_ARM_MNEMONICFAIL, +} ks_err_asm_arm; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/arm64.h b/keystone/arm64.h new file mode 100644 index 0000000..7a7af41 --- /dev/null +++ b/keystone/arm64.h @@ -0,0 +1,23 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_ARM64_H +#define KEYSTONE_ARM64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_arm64 { + KS_ERR_ASM_ARM64_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_ARM64_MISSINGFEATURE, + KS_ERR_ASM_ARM64_MNEMONICFAIL, +} ks_err_asm_arm64; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/evm.h b/keystone/evm.h new file mode 100644 index 0000000..60ac408 --- /dev/null +++ b/keystone/evm.h @@ -0,0 +1,23 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016-2018 */ + +#ifndef KEYSTONE_EVM_H +#define KEYSTONE_EVM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_evm { + KS_ERR_ASM_EVM_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_EVM_MISSINGFEATURE, + KS_ERR_ASM_EVM_MNEMONICFAIL, +} ks_err_asm_evm; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/hexagon.h b/keystone/hexagon.h new file mode 100644 index 0000000..e615812 --- /dev/null +++ b/keystone/hexagon.h @@ -0,0 +1,24 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_HEXAGON_H +#define KEYSTONE_HEXAGON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_hexagon { + KS_ERR_ASM_HEXAGON_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_HEXAGON_MISSINGFEATURE, + KS_ERR_ASM_HEXAGON_MNEMONICFAIL, +} ks_err_asm_hexagon; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/keystone.h b/keystone/keystone.h new file mode 100644 index 0000000..e29235e --- /dev/null +++ b/keystone/keystone.h @@ -0,0 +1,341 @@ +/* Keystone Assembler Engine (www.keystone-engine.org) */ +/* By Nguyen Anh Quynh , 2016 */ + +#ifndef KEYSTONE_ENGINE_H +#define KEYSTONE_ENGINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#ifdef _MSC_VER // MSVC compiler +#pragma warning(disable:4201) +#pragma warning(disable:4100) +#ifndef KEYSTONE_STATIC +#define KEYSTONE_EXPORT __declspec(dllexport) +#else +#define KEYSTONE_EXPORT +#endif +#else +#ifdef __GNUC__ +#include +#ifndef KEYSTONE_STATIC +#define KEYSTONE_EXPORT __attribute__((visibility("default"))) +#else +#define KEYSTONE_EXPORT +#endif +#else +#define KEYSTONE_EXPORT +#endif +#endif + + +struct ks_struct; +typedef struct ks_struct ks_engine; + +// Keystone API version +#define KS_API_MAJOR 0 +#define KS_API_MINOR 9 + +// Package version +#define KS_VERSION_MAJOR KS_API_MAJOR +#define KS_VERSION_MINOR KS_API_MINOR +#define KS_VERSION_EXTRA 2 + +/* + Macro to create combined version which can be compared to + result of ks_version() API. +*/ +#define KS_MAKE_VERSION(major, minor) ((major << 8) + minor) + +// Architecture type +typedef enum ks_arch { + KS_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2) + KS_ARCH_ARM64, // ARM-64, also called AArch64 + KS_ARCH_MIPS, // Mips architecture + KS_ARCH_X86, // X86 architecture (including x86 & x86-64) + KS_ARCH_PPC, // PowerPC architecture (currently unsupported) + KS_ARCH_SPARC, // Sparc architecture + KS_ARCH_SYSTEMZ, // SystemZ architecture (S390X) + KS_ARCH_HEXAGON, // Hexagon architecture + KS_ARCH_EVM, // Ethereum Virtual Machine architecture + KS_ARCH_MAX, +} ks_arch; + +// Mode type +typedef enum ks_mode { + KS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode) + KS_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode + // arm / arm64 + KS_MODE_ARM = 1 << 0, // ARM mode + KS_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2) + KS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM + // mips + KS_MODE_MICRO = 1 << 4, // MicroMips mode + KS_MODE_MIPS3 = 1 << 5, // Mips III ISA + KS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA + KS_MODE_MIPS32 = 1 << 2, // Mips32 ISA + KS_MODE_MIPS64 = 1 << 3, // Mips64 ISA + // x86 / x64 + KS_MODE_16 = 1 << 1, // 16-bit mode + KS_MODE_32 = 1 << 2, // 32-bit mode + KS_MODE_64 = 1 << 3, // 64-bit mode + // ppc + KS_MODE_PPC32 = 1 << 2, // 32-bit mode + KS_MODE_PPC64 = 1 << 3, // 64-bit mode + KS_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode + // sparc + KS_MODE_SPARC32 = 1 << 2, // 32-bit mode + KS_MODE_SPARC64 = 1 << 3, // 64-bit mode + KS_MODE_V9 = 1 << 4, // SparcV9 mode +} ks_mode; + +// All generic errors related to input assembly >= KS_ERR_ASM +#define KS_ERR_ASM 128 + +// All architecture-specific errors related to input assembly >= KS_ERR_ASM_ARCH +#define KS_ERR_ASM_ARCH 512 + +// All type of errors encountered by Keystone API. +typedef enum ks_err { + KS_ERR_OK = 0, // No error: everything was fine + KS_ERR_NOMEM, // Out-Of-Memory error: ks_open(), ks_emulate() + KS_ERR_ARCH, // Unsupported architecture: ks_open() + KS_ERR_HANDLE, // Invalid handle + KS_ERR_MODE, // Invalid/unsupported mode: ks_open() + KS_ERR_VERSION, // Unsupported version (bindings) + KS_ERR_OPT_INVALID, // Unsupported option + + // generic input assembly errors - parser specific + KS_ERR_ASM_EXPR_TOKEN = KS_ERR_ASM, // unknown token in expression + KS_ERR_ASM_DIRECTIVE_VALUE_RANGE, // literal value out of range for directive + KS_ERR_ASM_DIRECTIVE_ID, // expected identifier in directive + KS_ERR_ASM_DIRECTIVE_TOKEN, // unexpected token in directive + KS_ERR_ASM_DIRECTIVE_STR, // expected string in directive + KS_ERR_ASM_DIRECTIVE_COMMA, // expected comma in directive + KS_ERR_ASM_DIRECTIVE_RELOC_NAME, // expected relocation name in directive + KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN, // unexpected token in .reloc directive + KS_ERR_ASM_DIRECTIVE_FPOINT, // invalid floating point in directive + KS_ERR_ASM_DIRECTIVE_UNKNOWN, // unknown directive + KS_ERR_ASM_DIRECTIVE_EQU, // invalid equal directive + KS_ERR_ASM_DIRECTIVE_INVALID, // (generic) invalid directive + KS_ERR_ASM_VARIANT_INVALID, // invalid variant + KS_ERR_ASM_EXPR_BRACKET, // brackets expression not supported on this target + KS_ERR_ASM_SYMBOL_MODIFIER, // unexpected symbol modifier following '@' + KS_ERR_ASM_SYMBOL_REDEFINED, // invalid symbol redefinition + KS_ERR_ASM_SYMBOL_MISSING, // cannot find a symbol + KS_ERR_ASM_RPAREN, // expected ')' in parentheses expression + KS_ERR_ASM_STAT_TOKEN, // unexpected token at start of statement + KS_ERR_ASM_UNSUPPORTED, // unsupported token yet + KS_ERR_ASM_MACRO_TOKEN, // unexpected token in macro instantiation + KS_ERR_ASM_MACRO_PAREN, // unbalanced parentheses in macro argument + KS_ERR_ASM_MACRO_EQU, // expected '=' after formal parameter identifier + KS_ERR_ASM_MACRO_ARGS, // too many positional arguments + KS_ERR_ASM_MACRO_LEVELS_EXCEED, // macros cannot be nested more than 20 levels deep + KS_ERR_ASM_MACRO_STR, // invalid macro string + KS_ERR_ASM_MACRO_INVALID, // invalid macro (generic error) + KS_ERR_ASM_ESC_BACKSLASH, // unexpected backslash at end of escaped string + KS_ERR_ASM_ESC_OCTAL, // invalid octal escape sequence (out of range) + KS_ERR_ASM_ESC_SEQUENCE, // invalid escape sequence (unrecognized character) + KS_ERR_ASM_ESC_STR, // broken escape string + KS_ERR_ASM_TOKEN_INVALID, // invalid token + KS_ERR_ASM_INSN_UNSUPPORTED, // this instruction is unsupported in this mode + KS_ERR_ASM_FIXUP_INVALID, // invalid fixup + KS_ERR_ASM_LABEL_INVALID, // invalid label + KS_ERR_ASM_FRAGMENT_INVALID, // invalid fragment + + // generic input assembly errors - architecture specific + KS_ERR_ASM_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_MISSINGFEATURE, + KS_ERR_ASM_MNEMONICFAIL, +} ks_err; + +// Resolver callback to provide value for a missing symbol in @symbol. +// To handle a symbol, the resolver must put value of the symbol in @value, +// then returns True. +// If we do not resolve a missing symbol, this function must return False. +// In that case, ks_asm() would eventually return with error KS_ERR_ASM_SYMBOL_MISSING. + +// To register the resolver, pass its function address to ks_option(), using +// option KS_OPT_SYM_RESOLVER. For example, see samples/sample.c. +typedef bool (*ks_sym_resolver)(const char *symbol, uint64_t *value); + +// Runtime option for the Keystone engine +typedef enum ks_opt_type { + KS_OPT_SYNTAX = 1, // Choose syntax for input assembly + KS_OPT_SYM_RESOLVER, // Set symbol resolver callback +} ks_opt_type; + + +// Runtime option value (associated with ks_opt_type above) +typedef enum ks_opt_value { + KS_OPT_SYNTAX_INTEL = 1 << 0, // X86 Intel syntax - default on X86 (KS_OPT_SYNTAX). + KS_OPT_SYNTAX_ATT = 1 << 1, // X86 ATT asm syntax (KS_OPT_SYNTAX). + KS_OPT_SYNTAX_NASM = 1 << 2, // X86 Nasm syntax (KS_OPT_SYNTAX). + KS_OPT_SYNTAX_MASM = 1 << 3, // X86 Masm syntax (KS_OPT_SYNTAX) - unsupported yet. + KS_OPT_SYNTAX_GAS = 1 << 4, // X86 GNU GAS syntax (KS_OPT_SYNTAX). + KS_OPT_SYNTAX_RADIX16 = 1 << 5, // All immediates are in hex format (i.e 12 is 0x12) +} ks_opt_value; + + +#include "arm64.h" +#include "arm.h" +#include "evm.h" +#include "hexagon.h" +#include "mips.h" +#include "ppc.h" +#include "sparc.h" +#include "systemz.h" +#include "x86.h" + +/* + Return combined API version & major and minor version numbers. + + @major: major number of API version + @minor: minor number of API version + + @return hexical number as (major << 8 | minor), which encodes both + major & minor versions. + NOTE: This returned value can be compared with version number made + with macro KS_MAKE_VERSION + + For example, second API version would return 1 in @major, and 1 in @minor + The return value would be 0x0101 + + NOTE: if you only care about returned value, but not major and minor values, + set both @major & @minor arguments to NULL. +*/ +KEYSTONE_EXPORT +unsigned int ks_version(unsigned int *major, unsigned int *minor); + + +/* + Determine if the given architecture is supported by this library. + + @arch: architecture type (KS_ARCH_*) + + @return True if this library supports the given arch. +*/ +KEYSTONE_EXPORT +bool ks_arch_supported(ks_arch arch); + + +/* + Create new instance of Keystone engine. + + @arch: architecture type (KS_ARCH_*) + @mode: hardware mode. This is combined of KS_MODE_* + @ks: pointer to ks_engine, which will be updated at return time + + @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum + for detailed error). +*/ +KEYSTONE_EXPORT +ks_err ks_open(ks_arch arch, int mode, ks_engine **ks); + + +/* + Close KS instance: MUST do to release the handle when it is not used anymore. + NOTE: this must be called only when there is no longer usage of Keystone. + The reason is the this API releases some cached memory, thus access to any + Keystone API after ks_close() might crash your application. + After this, @ks is invalid, and nolonger usable. + + @ks: pointer to a handle returned by ks_open() + + @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum + for detailed error). +*/ +KEYSTONE_EXPORT +ks_err ks_close(ks_engine *ks); + + +/* + Report the last error number when some API function fail. + Like glibc's errno, ks_errno might not retain its old error once accessed. + + @ks: handle returned by ks_open() + + @return: error code of ks_err enum type (KS_ERR_*, see above) +*/ +KEYSTONE_EXPORT +ks_err ks_errno(ks_engine *ks); + + +/* + Return a string describing given error code. + + @code: error code (see KS_ERR_* above) + + @return: returns a pointer to a string that describes the error code + passed in the argument @code + */ +KEYSTONE_EXPORT +const char *ks_strerror(ks_err code); + + +/* + Set option for Keystone engine at runtime + + @ks: handle returned by ks_open() + @type: type of option to be set. See ks_opt_type + @value: option value corresponding with @type + + @return: KS_ERR_OK on success, or other value on failure. + Refer to ks_err enum for detailed error. +*/ +KEYSTONE_EXPORT +ks_err ks_option(ks_engine *ks, ks_opt_type type, size_t value); + + +/* + Assemble a string given its the buffer, size, start address and number + of instructions to be decoded. + This API dynamically allocate memory to contain assembled instruction. + Resulted array of bytes containing the machine code is put into @*encoding + + NOTE 1: this API will automatically determine memory needed to contain + output bytes in *encoding. + + NOTE 2: caller must free the allocated memory itself to avoid memory leaking. + + @ks: handle returned by ks_open() + @str: NULL-terminated assembly string. Use ; or \n to separate statements. + @address: address of the first assembly instruction, or 0 to ignore. + @encoding: array of bytes containing encoding of input assembly string. + NOTE: *encoding will be allocated by this function, and should be freed + with ks_free() function. + @encoding_size: size of *encoding + @stat_count: number of statements successfully processed + + @return: 0 on success, or -1 on failure. + + On failure, call ks_errno() for error code. +*/ +KEYSTONE_EXPORT +int ks_asm(ks_engine *ks, + const char *string, + uint64_t address, + unsigned char **encoding, size_t *encoding_size, + size_t *stat_count); + + +/* + Free memory allocated by ks_asm() + + @p: memory allocated in @encoding argument of ks_asm() +*/ +KEYSTONE_EXPORT +void ks_free(unsigned char *p); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/libkeystone.a b/keystone/libkeystone.a new file mode 100644 index 0000000..1193228 Binary files /dev/null and b/keystone/libkeystone.a differ diff --git a/keystone/mips.h b/keystone/mips.h new file mode 100644 index 0000000..e71c553 --- /dev/null +++ b/keystone/mips.h @@ -0,0 +1,23 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_MIPS_H +#define KEYSTONE_MIPS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_mips { + KS_ERR_ASM_MIPS_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_MIPS_MISSINGFEATURE, + KS_ERR_ASM_MIPS_MNEMONICFAIL, +} ks_err_asm_mips; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/ppc.h b/keystone/ppc.h new file mode 100644 index 0000000..39a602c --- /dev/null +++ b/keystone/ppc.h @@ -0,0 +1,24 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_PPC_H +#define KEYSTONE_PPC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_ppc { + KS_ERR_ASM_PPC_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_PPC_MISSINGFEATURE, + KS_ERR_ASM_PPC_MNEMONICFAIL, +} ks_err_asm_ppc; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/sparc.h b/keystone/sparc.h new file mode 100644 index 0000000..e49c426 --- /dev/null +++ b/keystone/sparc.h @@ -0,0 +1,24 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_SPARC_H +#define KEYSTONE_SPARC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_sparc { + KS_ERR_ASM_SPARC_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_SPARC_MISSINGFEATURE, + KS_ERR_ASM_SPARC_MNEMONICFAIL, +} ks_err_asm_sparc; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/systemz.h b/keystone/systemz.h new file mode 100644 index 0000000..ec2b07a --- /dev/null +++ b/keystone/systemz.h @@ -0,0 +1,24 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_SYSTEMZ_H +#define KEYSTONE_SYSTEMZ_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_systemz { + KS_ERR_ASM_SYSTEMZ_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_SYSTEMZ_MISSINGFEATURE, + KS_ERR_ASM_SYSTEMZ_MNEMONICFAIL, +} ks_err_asm_systemz; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/keystone/x86.h b/keystone/x86.h new file mode 100644 index 0000000..1fac684 --- /dev/null +++ b/keystone/x86.h @@ -0,0 +1,23 @@ +/* Keystone Assembler Engine */ +/* By Nguyen Anh Quynh, 2016 */ + +#ifndef KEYSTONE_X86_H +#define KEYSTONE_X86_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "keystone.h" + +typedef enum ks_err_asm_x86 { + KS_ERR_ASM_X86_INVALIDOPERAND = KS_ERR_ASM_ARCH, + KS_ERR_ASM_X86_MISSINGFEATURE, + KS_ERR_ASM_X86_MNEMONICFAIL, +} ks_err_asm_x86; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..f918310 --- /dev/null +++ b/resource.qrc @@ -0,0 +1,6 @@ + + + img/icon.png + img/README.md + + diff --git a/winghexasm.cpp b/winghexasm.cpp new file mode 100644 index 0000000..dabf86f --- /dev/null +++ b/winghexasm.cpp @@ -0,0 +1,255 @@ +#include "winghexasm.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define ICONRES(name) QIcon(":/WingHexAsm/img/" name ".png") +#define HOSTICONRES(name) QIcon(HOSTRESPIMG(name)) + +WingHexAsm::WingHexAsm(QObject *parent) { Q_UNUSED(parent) } + +bool WingHexAsm::init(QList loadedplugin) { + Q_UNUSED(loadedplugin); + + if (SDKVERSION < 8) { + QMessageBox::critical(nullptr, "Error", + "UnSupported Plugin System Version!", + QMessageBox::Ok); + return false; + } + + auto translator = new QTranslator(this); + + auto s = GETPLUGINQM("WingHexAsm.qm"); + if (!translator->load(s) || !QApplication::installTranslator(translator)) { + QMessageBox::critical(nullptr, "Error", "Error Loading Translation File!", + QMessageBox::Ok); + return false; + } + + w = new QWidget; + auto vlayout = new QVBoxLayout(w); + auto hlayout = new QHBoxLayout(w); + + hlayout->addWidget(new QLabel(tr("Arch :"), w)); + hlayout->addSpacing(10); + + // 默认 x86_64 64 位指令 + arch = new QComboBox(w); + QStringList archs( + {"ARM", "ARM64", "MIPS", "X86_64", "PPC", "SPARC", "EVM", "MOS65XX"}); + arch->addItems(archs); + arch->setCurrentIndex(3); + + void (QComboBox::*indexChanged)(int index) = &QComboBox::currentIndexChanged; + connect(arch, indexChanged, [=](int index) { + switch (index) { + case 0: + karch = ks_arch::KS_ARCH_ARM; + break; + case 1: + karch = ks_arch::KS_ARCH_ARM64; + break; + case 2: + karch = ks_arch::KS_ARCH_MIPS; + break; + case 3: + karch = ks_arch::KS_ARCH_X86; + break; + case 4: + karch = ks_arch::KS_ARCH_PPC; + break; + case 5: + karch = ks_arch::KS_ARCH_SPARC; + break; + case 6: + karch = ks_arch::KS_ARCH_EVM; + break; + } + }); + + hlayout->addWidget(arch); + hlayout->addSpacing(30); + + hlayout->addWidget(new QLabel(tr("Mode :"), w)); + hlayout->addSpacing(10); + + mode = new QComboBox(w); + QStringList modes({"x16", "x32", "x64", "THUMB", "MIPS32", "MIPS64"}); + mode->addItems(modes); + mode->setCurrentIndex(2); + + connect(mode, indexChanged, [=](int index) { + switch (index) { + case 0: + kmode = ks_mode::KS_MODE_16; + break; + case 1: + kmode = ks_mode::KS_MODE_32; + break; + case 2: + kmode = ks_mode::KS_MODE_64; + break; + case 3: + kmode = ks_mode::KS_MODE_THUMB; + break; + case 4: + kmode = ks_mode::KS_MODE_MIPS32; + break; + case 5: + kmode = ks_mode::KS_MODE_MIPS64; + break; + } + }); + + hlayout->addWidget(mode); + hlayout->addSpacing(10); + + cbintel = new QCheckBox("Intel", w); + cbintel->setChecked(true); + hlayout->addWidget(cbintel); + + hlayout->addStretch(); + + vlayout->addSpacing(10); + + txtAsm = new QTextBrowser(w); + txtAsm->setReadOnly(false); + vlayout->addItem(hlayout); + vlayout->addWidget(txtAsm); + + vlayout->addSpacing(10); + auto asmbtn = new QPushButton(tr("AsmCode"), w); + connect(asmbtn, &QPushButton::clicked, this, [=] { + auto txt = txtAsm->toPlainText(); + if (txt.length()) { + this->asmCode(txt); + } else { + this->toast(ICONRES("icon"), tr("No Asm")); + } + }); + vlayout->addWidget(asmbtn); + + PluginDockWidgetInit(dw, w, tr("AsmWindow"), "AsmWindow"); + + PluginMenuInitBegin(menu, tr("WingHexAsm")) { + menu->setIcon(ICONRES("icon")); + PluginMenuAddItemIconLamba(menu, tr("AsmWindow"), ICONRES("icon"), [=] { + dw->show(); + dw->raise(); + }); + PluginMenuAddItemIconLamba(menu, tr("Author"), HOSTICONRES("author"), [=] { + auto authord = + newAboutDialog(QPixmap(), {":/WingHexAsm", ":/WingHexAsm/img"}); + authord->exec(); + delete authord; + }); + PluginMenuAddItemIconLamba(menu, tr("Sponsor"), HOSTICONRES("sponsor"), + [=] { + auto sponsor = newSponsorDialog(); + sponsor->exec(); + delete sponsor; + }); + } + PluginMenuInitEnd(); + + tbtn = new QToolButton; + tbtn->setIcon(ICONRES("icon")); + + connect(tbtn, &QToolButton::clicked, this, [=] { + dw->show(); + dw->raise(); + }); + + return true; +} + +WingHexAsm::~WingHexAsm() {} + +void WingHexAsm::unload() {} + +int WingHexAsm::sdkVersion() { return SDKVERSION; } + +QMenu *WingHexAsm::registerMenu() { return menu; } + +QToolButton *WingHexAsm::registerToolButton() { return tbtn; } + +void WingHexAsm::registerDockWidget( + QMap &rdw) { + rdw.insert(dw, Qt::DockWidgetArea::BottomDockWidgetArea); +} + +QString WingHexAsm::pluginName() { return tr("WingHexAsm"); } + +QString WingHexAsm::pluginAuthor() { return WINGSUMMER; } + +uint WingHexAsm::pluginVersion() { return 1; } + +QString WingHexAsm::signature() { return WINGSUMMER; } + +QString WingHexAsm::pluginComment() { + return tr("A small assembly plugin for WingHexExplorer."); +} + +void WingHexAsm::plugin2MessagePipe(WingPluginMessage type, + QList msg) { + Q_UNUSED(type); + Q_UNUSED(msg); +} + +void WingHexAsm::asmCode(QString code) { + ks_engine *ks; + ks_err err; + size_t count; + unsigned char *encode; + size_t size; + + QIcon icon = ICONRES("icon"); + + err = ks_open(karch, kmode, &ks); + if (err != KS_ERR_OK) { + toast(icon, tr("ERROR: failed on ks_open()")); + return; + } + + if (cbintel->isChecked()) { + ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_INTEL); + } else { + ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_ATT); + } + + if (ks_asm(ks, code.toUtf8().constData(), 0, &encode, &size, &count)) { + toast(icon, tr("ERROR: failed on ks_asm() with count = %1, error code = %2") + .arg(count) + .arg(ks_errno(ks))); + } else { + QByteArray buffer(reinterpret_cast(encode), int(size)); + if (reader.currentDoc() < 0) { + USINGCONTROL({ + controller.newFile(); + controller.insert(0, buffer); // 直接使用 insert 会比 append 更高效一点 + }); + } else { + USINGCONTROL({ + auto pos = reader.currentOffset(); + controller.insert(qint64(pos), buffer); + }); + } + toast(icon, tr("ASMSuccessfully")); + } + + // NOTE: free encode after usage to avoid leaking memory + ks_free(encode); + + // close Keystone instance when done + ks_close(ks); +} + +#if QT_VERSION < 0x050000 +Q_EXPORT_PLUGIN2(WingHexAsm, WingHexAsm) +#endif // QT_VERSION < 0x050000 diff --git a/winghexasm.h b/winghexasm.h new file mode 100644 index 0000000..e4f008e --- /dev/null +++ b/winghexasm.h @@ -0,0 +1,52 @@ +#ifndef WINGHEXASM_H +#define WINGHEXASM_H + +#include "../WingHexExplorer/wing-hex-explorer.sourcecode/WingHexExplorer/plugin/iwingplugin.h" +#include "keystone/keystone.h" +#include +#include +#include + +class WingHexAsm : public IWingPlugin { + Q_OBJECT +#if QT_VERSION >= 0x050000 + Q_PLUGIN_METADATA(IID IWINGPLUGIN_INTERFACE_IID FILE "WingHexAsm.json") +#endif // QT_VERSION >= 0x050000 + + Q_INTERFACES(IWingPlugin) + +public: + WingHexAsm(QObject *parent = nullptr); + bool init(QList loadedplugin) override; + ~WingHexAsm() override; + void unload() override; + int sdkVersion() override; + QMenu *registerMenu() override; + QToolButton *registerToolButton() override; + void + registerDockWidget(QMap &rdw) override; + QString pluginName() override; + QString pluginAuthor() override; + uint pluginVersion() override; + QString signature() override; + QString pluginComment() override; + void plugin2MessagePipe(WingPluginMessage type, QList msg) override; + +private: + void asmCode(QString code); + +private: + QMenu *menu; + QToolButton *tbtn; + QWidget *w; + QDockWidget *dw; + QTextBrowser *txtAsm; + QComboBox *arch, *mode; + + QCheckBox *cbintel; + + ks_arch karch = ks_arch::KS_ARCH_X86; + ks_mode kmode = ks_mode::KS_MODE_64; +}; + +#endif // WINGHEXASM_H diff --git a/微信捐助.png b/微信捐助.png new file mode 100755 index 0000000..a7bce63 Binary files /dev/null and b/微信捐助.png differ diff --git a/支付宝捐助.jpg b/支付宝捐助.jpg new file mode 100755 index 0000000..5e443f8 Binary files /dev/null and b/支付宝捐助.jpg differ