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
+
+
+
+
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