NCPrePatcher 0.2.0-arm64-darwin-23 → 0.3.1-arm64-darwin-23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -6
- data/lib/keystone/arm_const.rb +7 -0
- data/lib/keystone/keystone.dylib +0 -0
- data/lib/keystone/keystone.rb +76 -0
- data/lib/keystone/keystone_const.rb +97 -0
- data/lib/keystone/version.rb +3 -0
- data/lib/ncpp/commands.rb +76 -3
- data/lib/ncpp/interpreter.rb +2 -1
- data/lib/ncpp/utils.rb +82 -1
- data/lib/ncpp/version.rb +1 -1
- data/lib/ncpp.rb +11 -17
- data/lib/nitro/nitro.dylib +0 -0
- data/lib/nitro/nitro.rb +27 -5
- data/lib/unarm/unarm.dylib +0 -0
- data/lib/unicorn/arm_const.rb +196 -0
- data/lib/unicorn/unicorn.dylib +0 -0
- data/lib/unicorn/unicorn.rb +204 -0
- data/lib/unicorn/unicorn_const.rb +152 -0
- data/lib/unicorn/version.rb +3 -0
- metadata +12 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37692a1442bcc5997344dc3f71242341872479f65af528919b0c839470282f80
|
|
4
|
+
data.tar.gz: 47e53518bad77f58a88e4595c51344eafa80d8a71359b0f7757f4e20d961790d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ee086281238d3e3a4d17fa7a09c7832f715fda726c3f8f2095f80593d272015d785ada46ec39983692fad698d96b5ac61d73b9b64882f4982f5bde23ef8aae6
|
|
7
|
+
data.tar.gz: ed9396fa204a4a376bf9577261f26b1a9d26aae045d3ff58f5118717efdc5a3418bb2910f7cf52e9273c472be27a3a30fd06b7efa0a284411c3593ff569b21f5
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# NCPrePatcher
|
|
2
2
|
|
|
3
|
-
A preprocessor for [NCPatcher](https://github.com/TheGameratorT/NCPatcher) with access to your NDS ROM and
|
|
3
|
+
A preprocessor for [NCPatcher](https://github.com/TheGameratorT/NCPatcher) with access to your NDS ROM, a disassembler, an assembler, and an emulator.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,9 +8,9 @@ A preprocessor for [NCPatcher](https://github.com/TheGameratorT/NCPatcher) with
|
|
|
8
8
|
|
|
9
9
|
- [Ruby (≥ 3.4 required)](https://www.ruby-lang.org/en/downloads/)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
From the command line, enter:
|
|
12
12
|
```console
|
|
13
|
-
gem install NCPrePatcher
|
|
13
|
+
gem install NCPrePatcher
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
The `ncpp` command should now be available at your command line (a system reboot may be required).
|
|
@@ -47,13 +47,19 @@ ncpp --help
|
|
|
47
47
|
- Ruby
|
|
48
48
|
- CMake and a modern C++ compiler
|
|
49
49
|
- Rust and Cargo
|
|
50
|
+
- vcpkg
|
|
50
51
|
|
|
51
|
-
To build the
|
|
52
|
+
To build the nitro and unarm native libraries, go to /ext/ and run:
|
|
52
53
|
```console
|
|
53
54
|
ruby build.rb
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
To build the unicorn and keystone native libraries run:
|
|
58
|
+
```console
|
|
59
|
+
vcpkg install unicorn keystone --triplet [your platform]-dynamic
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Move the built binaries to `lib/unicorn` and `lib/keystone` respectively, and finally, go back to the base directory and run:
|
|
57
63
|
```console
|
|
58
64
|
gem build ncpp.gemspec
|
|
59
65
|
```
|
|
@@ -63,4 +69,6 @@ gem build ncpp.gemspec
|
|
|
63
69
|
- Code from NCPatcher used by the **nitro** library
|
|
64
70
|
- [unarm](https://github.com/AetiasHax/unarm) used for disassembling
|
|
65
71
|
- [Ruby-FFI](https://github.com/ffi/ffi) used for binding the above libraries to Ruby
|
|
66
|
-
- [Parslet](https://github.com/kschiess/parslet) used for parsing the DSL
|
|
72
|
+
- [Parslet](https://github.com/kschiess/parslet) used for parsing the DSL
|
|
73
|
+
- [Unicorn](https://github.com/unicorn-engine/unicorn/tree/master) used for emulating
|
|
74
|
+
- [Keystone](https://github.com/keystone-engine/keystone/tree/master) used for assembling
|
|
Binary file
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'ffi'
|
|
2
|
+
|
|
3
|
+
require_relative 'arm_const.rb'
|
|
4
|
+
require_relative 'keystone_const.rb'
|
|
5
|
+
require_relative 'version.rb'
|
|
6
|
+
|
|
7
|
+
module KeystoneBind
|
|
8
|
+
extend FFI::Library
|
|
9
|
+
ffi_lib [
|
|
10
|
+
File.expand_path("keystone", __dir__),
|
|
11
|
+
File.expand_path("keystone.dylib", __dir__),
|
|
12
|
+
File.expand_path("keystone.so", __dir__),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
typedef :pointer, :ks_engine
|
|
16
|
+
typedef :pointer, :ks_engine_handle
|
|
17
|
+
typedef :uint, :ks_arch
|
|
18
|
+
typedef :uint, :ks_err
|
|
19
|
+
typedef :uint, :ks_opt_type
|
|
20
|
+
|
|
21
|
+
attach_function :ks_version, [:pointer, :pointer], :uint
|
|
22
|
+
attach_function :ks_arch_supported, [:ks_arch], :bool
|
|
23
|
+
attach_function :ks_open, [:ks_arch, :int, :ks_engine_handle], :ks_err
|
|
24
|
+
attach_function :ks_close, [:ks_engine], :ks_err
|
|
25
|
+
attach_function :ks_errno, [:ks_engine], :ks_err
|
|
26
|
+
attach_function :ks_strerror, [:ks_err], :string
|
|
27
|
+
attach_function :ks_option, [:ks_engine, :ks_opt_type, :size_t], :ks_err
|
|
28
|
+
attach_function :ks_asm, [:ks_engine, :string, :uint64, :pointer, :pointer, :pointer], :int
|
|
29
|
+
attach_function :ks_free, [:pointer], :void
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Keystone
|
|
33
|
+
extend KeystoneBind
|
|
34
|
+
|
|
35
|
+
def self.major_version
|
|
36
|
+
ks_version(nil, nil)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.arch_supported?(ks_arch)
|
|
40
|
+
ks_arch_supported(ks_arch)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Assembler
|
|
44
|
+
include KeystoneBind
|
|
45
|
+
|
|
46
|
+
def initialize(arch: KS_ARCH_ARM, mode: KS_MODE_ARM)
|
|
47
|
+
|
|
48
|
+
FFI::MemoryPointer.new(:pointer,1) do |ptr|
|
|
49
|
+
safe_call(:ks_open, arch, mode, ptr)
|
|
50
|
+
@engine = FFI::AutoPointer.new(ptr.read_pointer, method(:ks_close))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def assemble(asm_str, addr: 0)
|
|
55
|
+
encoding_ptr = FFI::MemoryPointer.new(:pointer)
|
|
56
|
+
encoding_size = FFI::MemoryPointer.new(:size_t)
|
|
57
|
+
stat_count = FFI::MemoryPointer.new(:size_t)
|
|
58
|
+
safe_call(:ks_asm, @engine, asm_str, addr, encoding_ptr, encoding_size, stat_count)
|
|
59
|
+
encoded_bytes = encoding_ptr.read_pointer.read_array_of_uint8(encoding_size.read_uint)
|
|
60
|
+
ks_free(encoding_ptr.read_pointer)
|
|
61
|
+
encoded_bytes.pack('C*')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def set_option(ks_opt_type, value)
|
|
65
|
+
safe_call(:ks_option, @engine, ks_opt_type, value)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
def safe_call(meth_sym, *args)
|
|
70
|
+
err = send(meth_sym, *args)
|
|
71
|
+
raise "Error from #{meth_sym}: #{ks_strerror(err)}" if err != KS_ERR_OK
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Ks = Keystone
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.rb]
|
|
2
|
+
|
|
3
|
+
module Keystone
|
|
4
|
+
KS_API_MAJOR = 0
|
|
5
|
+
KS_API_MINOR = 9
|
|
6
|
+
KS_VERSION_MAJOR = 0
|
|
7
|
+
KS_VERSION_MINOR = 9
|
|
8
|
+
KS_VERSION_EXTRA = 2
|
|
9
|
+
KS_ARCH_ARM = 1
|
|
10
|
+
KS_ARCH_ARM64 = 2
|
|
11
|
+
KS_ARCH_MIPS = 3
|
|
12
|
+
KS_ARCH_X86 = 4
|
|
13
|
+
KS_ARCH_PPC = 5
|
|
14
|
+
KS_ARCH_SPARC = 6
|
|
15
|
+
KS_ARCH_SYSTEMZ = 7
|
|
16
|
+
KS_ARCH_HEXAGON = 8
|
|
17
|
+
KS_ARCH_EVM = 9
|
|
18
|
+
KS_ARCH_RISCV = 10
|
|
19
|
+
KS_ARCH_MAX = 11
|
|
20
|
+
KS_MODE_LITTLE_ENDIAN = 0
|
|
21
|
+
KS_MODE_BIG_ENDIAN = 1073741824
|
|
22
|
+
KS_MODE_ARM = 1
|
|
23
|
+
KS_MODE_THUMB = 16
|
|
24
|
+
KS_MODE_V8 = 64
|
|
25
|
+
KS_MODE_MICRO = 16
|
|
26
|
+
KS_MODE_MIPS3 = 32
|
|
27
|
+
KS_MODE_MIPS32R6 = 64
|
|
28
|
+
KS_MODE_MIPS32 = 4
|
|
29
|
+
KS_MODE_MIPS64 = 8
|
|
30
|
+
KS_MODE_16 = 2
|
|
31
|
+
KS_MODE_32 = 4
|
|
32
|
+
KS_MODE_64 = 8
|
|
33
|
+
KS_MODE_PPC32 = 4
|
|
34
|
+
KS_MODE_PPC64 = 8
|
|
35
|
+
KS_MODE_QPX = 16
|
|
36
|
+
KS_MODE_RISCV32 = 4
|
|
37
|
+
KS_MODE_RISCV64 = 8
|
|
38
|
+
KS_MODE_SPARC32 = 4
|
|
39
|
+
KS_MODE_SPARC64 = 8
|
|
40
|
+
KS_MODE_V9 = 16
|
|
41
|
+
KS_ERR_ASM = 128
|
|
42
|
+
KS_ERR_ASM_ARCH = 512
|
|
43
|
+
KS_ERR_OK = 0
|
|
44
|
+
KS_ERR_NOMEM = 1
|
|
45
|
+
KS_ERR_ARCH = 2
|
|
46
|
+
KS_ERR_HANDLE = 3
|
|
47
|
+
KS_ERR_MODE = 4
|
|
48
|
+
KS_ERR_VERSION = 5
|
|
49
|
+
KS_ERR_OPT_INVALID = 6
|
|
50
|
+
KS_ERR_ASM_EXPR_TOKEN = 128
|
|
51
|
+
KS_ERR_ASM_DIRECTIVE_VALUE_RANGE = 129
|
|
52
|
+
KS_ERR_ASM_DIRECTIVE_ID = 130
|
|
53
|
+
KS_ERR_ASM_DIRECTIVE_TOKEN = 131
|
|
54
|
+
KS_ERR_ASM_DIRECTIVE_STR = 132
|
|
55
|
+
KS_ERR_ASM_DIRECTIVE_COMMA = 133
|
|
56
|
+
KS_ERR_ASM_DIRECTIVE_RELOC_NAME = 134
|
|
57
|
+
KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN = 135
|
|
58
|
+
KS_ERR_ASM_DIRECTIVE_FPOINT = 136
|
|
59
|
+
KS_ERR_ASM_DIRECTIVE_UNKNOWN = 137
|
|
60
|
+
KS_ERR_ASM_DIRECTIVE_EQU = 138
|
|
61
|
+
KS_ERR_ASM_DIRECTIVE_INVALID = 139
|
|
62
|
+
KS_ERR_ASM_VARIANT_INVALID = 140
|
|
63
|
+
KS_ERR_ASM_EXPR_BRACKET = 141
|
|
64
|
+
KS_ERR_ASM_SYMBOL_MODIFIER = 142
|
|
65
|
+
KS_ERR_ASM_SYMBOL_REDEFINED = 143
|
|
66
|
+
KS_ERR_ASM_SYMBOL_MISSING = 144
|
|
67
|
+
KS_ERR_ASM_RPAREN = 145
|
|
68
|
+
KS_ERR_ASM_STAT_TOKEN = 146
|
|
69
|
+
KS_ERR_ASM_UNSUPPORTED = 147
|
|
70
|
+
KS_ERR_ASM_MACRO_TOKEN = 148
|
|
71
|
+
KS_ERR_ASM_MACRO_PAREN = 149
|
|
72
|
+
KS_ERR_ASM_MACRO_EQU = 150
|
|
73
|
+
KS_ERR_ASM_MACRO_ARGS = 151
|
|
74
|
+
KS_ERR_ASM_MACRO_LEVELS_EXCEED = 152
|
|
75
|
+
KS_ERR_ASM_MACRO_STR = 153
|
|
76
|
+
KS_ERR_ASM_MACRO_INVALID = 154
|
|
77
|
+
KS_ERR_ASM_ESC_BACKSLASH = 155
|
|
78
|
+
KS_ERR_ASM_ESC_OCTAL = 156
|
|
79
|
+
KS_ERR_ASM_ESC_SEQUENCE = 157
|
|
80
|
+
KS_ERR_ASM_ESC_STR = 158
|
|
81
|
+
KS_ERR_ASM_TOKEN_INVALID = 159
|
|
82
|
+
KS_ERR_ASM_INSN_UNSUPPORTED = 160
|
|
83
|
+
KS_ERR_ASM_FIXUP_INVALID = 161
|
|
84
|
+
KS_ERR_ASM_LABEL_INVALID = 162
|
|
85
|
+
KS_ERR_ASM_FRAGMENT_INVALID = 163
|
|
86
|
+
KS_ERR_ASM_INVALIDOPERAND = 512
|
|
87
|
+
KS_ERR_ASM_MISSINGFEATURE = 513
|
|
88
|
+
KS_ERR_ASM_MNEMONICFAIL = 514
|
|
89
|
+
KS_OPT_SYNTAX = 1
|
|
90
|
+
KS_OPT_SYM_RESOLVER = 2
|
|
91
|
+
KS_OPT_SYNTAX_INTEL = 1
|
|
92
|
+
KS_OPT_SYNTAX_ATT = 2
|
|
93
|
+
KS_OPT_SYNTAX_NASM = 4
|
|
94
|
+
KS_OPT_SYNTAX_MASM = 8
|
|
95
|
+
KS_OPT_SYNTAX_GAS = 16
|
|
96
|
+
KS_OPT_SYNTAX_RADIX16 = 32
|
|
97
|
+
end
|
data/lib/ncpp/commands.rb
CHANGED
|
@@ -206,6 +206,9 @@ module NCPP
|
|
|
206
206
|
hex: ->(i) { Utils.integer_check(i,'hex'); i.to_hex }.returns(String)
|
|
207
207
|
.describe('Returns a hexadecimal representation of the given Integer.'),
|
|
208
208
|
|
|
209
|
+
ord: ->(s) { s.ord }.returns(Integer)
|
|
210
|
+
.describe('Gets the Integer ordinal of the first character in the given String.'),
|
|
211
|
+
|
|
209
212
|
string: ->(x) { String(x) }.returns(String)
|
|
210
213
|
.describe('Gets the given argument as a String.'),
|
|
211
214
|
|
|
@@ -587,6 +590,7 @@ module NCPP
|
|
|
587
590
|
exp: ->(n) { Math.exp(n) }.returns(Float).describe('Gets e raised to the power of the given number.'),
|
|
588
591
|
log: ->(n) { Math.log(n) }.returns(Float).describe('Gets the base logarithm of the given number.'),
|
|
589
592
|
sqrt: ->(n) { Math.sqrt(n) }.returns(Float).describe('Gets the square root of the given number.'),
|
|
593
|
+
round: ->(f, n_digits=0) { f.round(n_digits) }.returns(Numeric),
|
|
590
594
|
clamp: ->(n, min,max=nil) { n.clamp(min,max) }.returns(Numeric)
|
|
591
595
|
.describe('Clamps number between given min and max values.'),
|
|
592
596
|
|
|
@@ -644,7 +648,7 @@ module NCPP
|
|
|
644
648
|
"the original ASM with the immediate swapped to the value given."),
|
|
645
649
|
|
|
646
650
|
repl_array: ->(loc, ov, dtype, arr) { Utils.gen_repl_array(loc,ov,dtype,arr) }.returns(String),
|
|
647
|
-
|
|
651
|
+
|
|
648
652
|
repl_u64_array: ->(loc,ov_or_arr,arr=nil) { Utils.gen_repl_type_array(loc, ov_or_arr, :u64, arr) }.returns(String),
|
|
649
653
|
repl_s64_array: ->(loc,ov_or_arr,arr=nil) { Utils.gen_repl_type_array(loc, ov_or_arr, :s64, arr) }.returns(String),
|
|
650
654
|
repl_u32_array: ->(loc,ov_or_arr,arr=nil) { Utils.gen_repl_type_array(loc, ov_or_arr, :u32, arr) }.returns(String),
|
|
@@ -677,11 +681,15 @@ module NCPP
|
|
|
677
681
|
get_signed_byte: ->(addr,ov=nil) { Utils.get_signed_byte(addr,ov) }.returns(Integer),
|
|
678
682
|
get_cstring: ->(addr,ov=nil) { Utils.get_cstring(addr,ov) }.returns(String),
|
|
679
683
|
get_array: ->(addr,ov,e_type_id,e_count=1) { Utils.get_array(addr,ov,e_type_id,e_count) }.returns(Array),
|
|
684
|
+
get_chars: ->(addr,ov, char_count) { Utils.get_array(addr,ov,Utils::DTYPE_IDS[:u8],char_count).map { it.chr } }
|
|
685
|
+
.returns(Array),
|
|
680
686
|
|
|
681
687
|
get_c_array: ->(addr,ov,e_type_id,e_count=1) {
|
|
682
688
|
Utils.to_c_array(Utils.get_array(addr,ov,e_type_id,e_count))
|
|
683
689
|
}.returns(Array),
|
|
684
690
|
|
|
691
|
+
get_byte_str: ->(loc,ov,size) { Utils.get_byte_str(loc,ov,size) }.returns(String),
|
|
692
|
+
|
|
685
693
|
find_first_branch_to: ->(branch_dest, start_loc,start_ov=nil) {
|
|
686
694
|
Utils.find_branch_to(branch_dest, start_loc,start_ov)
|
|
687
695
|
}.returns(Integer),
|
|
@@ -772,6 +780,14 @@ module NCPP
|
|
|
772
780
|
s16: ->(n) { n.signed(16) }.returns(Integer).describe('Gets the given number as a signed 16-bit Integer.'),
|
|
773
781
|
u8: ->(n) { n.unsigned(8) }.returns(Integer).describe('Gets the given number as an unsigned 8-bit Integer.'),
|
|
774
782
|
s8: ->(n) { n.signed(8) }.returns(Integer).describe('Gets the given number as a signed 8-bit Integer.'),
|
|
783
|
+
char: ->(n) { n.unsigned(8).chr }.returns(String).describe('Gets the given number as an ASCII character.'),
|
|
784
|
+
|
|
785
|
+
sizeof: ->(dtype) { Utils::DTYPES[dtype][:size] }.returns(Integer),
|
|
786
|
+
|
|
787
|
+
f32: ->(n) { [n].pack('g').unpack('L>') }.returns(Integer),
|
|
788
|
+
f64: ->(n) { [n].pack('G').unpack('Q>') }.returns(Integer),
|
|
789
|
+
from_f32: ->(n) { [n].pack('L>').unpack('g')[0] }.returns(Float),
|
|
790
|
+
from_f64: ->(n) { [n].pack('Q>').unpack('G')[0] }.returns(Float),
|
|
775
791
|
|
|
776
792
|
from_fx_deg: ->(fx_num) {
|
|
777
793
|
Float(fx_num) / 0x10000 * 360
|
|
@@ -794,7 +810,36 @@ module NCPP
|
|
|
794
810
|
from_gx_rgb: ->(n) { [(n >> 0) & 31, (n >> 5) & 31, (n >> 10) & 31] }.returns(Array)
|
|
795
811
|
.describe('Unpacks the given RGB x1B5G5R5 value as an Array ([R,G,B]).'),
|
|
796
812
|
from_gx_rgba: ->(n) { [(n >> 0) & 31, (n >> 5) & 31, (n >> 10) & 31, (n >> 15) & 1] }.returns(Array)
|
|
797
|
-
.describe('Unpacks the given packed RGB A1B5G5R5 value as an Array ([R,G,B,A]).')
|
|
813
|
+
.describe('Unpacks the given packed RGB A1B5G5R5 value as an Array ([R,G,B,A]).'),
|
|
814
|
+
|
|
815
|
+
pack_u64_array: ->(arr) { arr.pack('Q*') }.returns(String),
|
|
816
|
+
pack_u32_array: ->(arr) { arr.pack('L*') }.returns(String),
|
|
817
|
+
pack_u16_array: ->(arr) { arr.pack('S*') }.returns(String),
|
|
818
|
+
pack_u8_array: ->(arr) { arr.pack('C*') }.returns(String),
|
|
819
|
+
pack_s64_array: ->(arr) { arr.pack('q*') }.returns(String),
|
|
820
|
+
pack_s32_array: ->(arr) { arr.pack('l*') }.returns(String),
|
|
821
|
+
pack_s16_array: ->(arr) { arr.pack('s*') }.returns(String),
|
|
822
|
+
pack_s8_array: ->(arr) { arr.pack('c*') }.returns(String),
|
|
823
|
+
|
|
824
|
+
unpack_u64_array: ->(byte_str) { byte_str.unpack('Q*') }.returns(Array),
|
|
825
|
+
unpack_u32_array: ->(byte_str) { byte_str.unpack('L*') }.returns(Array),
|
|
826
|
+
unpack_u16_array: ->(byte_str) { byte_str.unpack('S*') }.returns(Array),
|
|
827
|
+
unpack_u8_array: ->(byte_str) { byte_str.unpack('C*') }.returns(Array),
|
|
828
|
+
unpack_s64_array: ->(byte_str) { byte_str.unpack('q*') }.returns(Array),
|
|
829
|
+
unpack_s32_array: ->(byte_str) { byte_str.unpack('l*') }.returns(Array),
|
|
830
|
+
unpack_s16_array: ->(byte_str) { byte_str.unpack('s*') }.returns(Array),
|
|
831
|
+
unpack_s8_array: ->(byte_str) { byte_str.unpack('c*') }.returns(Array),
|
|
832
|
+
|
|
833
|
+
emulate_func: ->(loc,ov,*args) { Utils.emulate_func(loc,ov,*args) }.returns(Object).impure,
|
|
834
|
+
emu_get_reg: ->(reg_s) { $emu.read_reg(reg_s.to_sym) }.returns(Integer).impure,
|
|
835
|
+
emu_set_reg: ->(reg_s,val) { $emu.write_reg(reg_s.to_sym,val) }.impure,
|
|
836
|
+
emu_get_mem: ->(loc,size) { Utils.emu_get_mem(loc,size) }.returns(String).impure,
|
|
837
|
+
emu_set_mem: ->(loc,byte_str) { Utils.emu_set_mem(loc,byte_str) }.impure,
|
|
838
|
+
emu_load_ov: ->(ov_id) { $emu.load_overlay(ov_id) }.impure,
|
|
839
|
+
emu_reset: -> { $emu = Uc::Emu.new(); $emu.load_arm9 }.impure,
|
|
840
|
+
|
|
841
|
+
assemble_arm: ->(asm,addr=0) { Utils.assemble_arm(asm,addr:addr) }.returns(Integer),
|
|
842
|
+
assemble_thumb: ->(asm,addr=0) { Utils.assemble_thumb(asm,addr:addr) }.returns(Integer),
|
|
798
843
|
|
|
799
844
|
},
|
|
800
845
|
|
|
@@ -839,6 +884,7 @@ module NCPP
|
|
|
839
884
|
get_s8: :get_signed_byte,
|
|
840
885
|
get_cstr: :get_cstring,
|
|
841
886
|
disasm_ins: :disasm_arm_ins,
|
|
887
|
+
disasm: :disasm_arm_ins,
|
|
842
888
|
disasm_hex_seq: :disasm_arm_hex_seq,
|
|
843
889
|
disasm_hex_str: :disasm_arm_hex_seq,
|
|
844
890
|
disasm_arm_hex_str: :disasm_arm_hex_seq,
|
|
@@ -876,7 +922,34 @@ module NCPP
|
|
|
876
922
|
is_addr_in_ov: :is_address_in_overlay,
|
|
877
923
|
is_addr_in_arm9: :is_address_in_arm9,
|
|
878
924
|
is_addr_in_arm7: :is_address_in_arm7,
|
|
879
|
-
find_hex_seq: :find_hex_bytes
|
|
925
|
+
find_hex_seq: :find_hex_bytes,
|
|
926
|
+
pack_u64_arr: :pack_u64_array,
|
|
927
|
+
pack_u32_arr: :pack_u32_array,
|
|
928
|
+
pack_u16_arr: :pack_u16_array,
|
|
929
|
+
pack_u8_arr: :pack_u8_array,
|
|
930
|
+
pack_s64_arr: :pack_s64_array,
|
|
931
|
+
pack_s32_arr: :pack_s32_array,
|
|
932
|
+
pack_s16_arr: :pack_s16_array,
|
|
933
|
+
pack_s8_arr: :pack_s8_array,
|
|
934
|
+
unpack_u64_arr: :unpack_u64_array,
|
|
935
|
+
unpack_u32_arr: :unpack_u32_array,
|
|
936
|
+
unpack_u16_arr: :unpack_u16_array,
|
|
937
|
+
unpack_u8_arr: :unpack_u8_array,
|
|
938
|
+
unpack_s64_arr: :unpack_s64_array,
|
|
939
|
+
unpack_s32_arr: :unpack_s32_array,
|
|
940
|
+
unpack_s16_arr: :unpack_s16_array,
|
|
941
|
+
unpack_s8_arr: :unpack_s8_array,
|
|
942
|
+
emulate_function: :emulate_func,
|
|
943
|
+
emu_call_func: :emulate_func,
|
|
944
|
+
emu_get_register: :emu_get_reg,
|
|
945
|
+
emu_set_register: :emu_set_reg,
|
|
946
|
+
emu_get_memory: :emu_get_mem,
|
|
947
|
+
emu_set_memory: :emu_set_mem,
|
|
948
|
+
emu_load_overlay: :emu_load_ov,
|
|
949
|
+
assemble: :assemble_arm,
|
|
950
|
+
assemble_ins: :assemble_arm,
|
|
951
|
+
assemble_arm_ins: :assemble_arm,
|
|
952
|
+
assemble_thumb_ins: :assemble_thumb
|
|
880
953
|
}).freeze
|
|
881
954
|
|
|
882
955
|
|
data/lib/ncpp/interpreter.rb
CHANGED
data/lib/ncpp/utils.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative '../nitro/nitro.rb'
|
|
2
2
|
require_relative '../unarm/unarm.rb'
|
|
3
|
+
require_relative '../unicorn/unicorn.rb'
|
|
3
4
|
|
|
4
5
|
require 'did_you_mean/jaro_winkler'
|
|
5
6
|
require 'did_you_mean/levenshtein'
|
|
@@ -265,6 +266,11 @@ module NCPP
|
|
|
265
266
|
end
|
|
266
267
|
end
|
|
267
268
|
|
|
269
|
+
def self.get_byte_str(loc, ov, size)
|
|
270
|
+
addr, _ov, code_bin = resolve_code_loc(loc, ov)
|
|
271
|
+
code_bin.get_sect_ptr(addr,size).read_array_of_uint8(size).pack('C*')
|
|
272
|
+
end
|
|
273
|
+
|
|
268
274
|
def self.find_branch_to(branch_dest, start_loc, start_ov=nil, from_func: false, find_all: false)
|
|
269
275
|
start_addr, _ov, code_bin = resolve_code_loc(start_loc, start_ov)
|
|
270
276
|
if branch_dest.is_a? Array
|
|
@@ -423,6 +429,40 @@ module NCPP
|
|
|
423
429
|
gen_repl_array(addr, ov, DTYPE_IDS[:u8], [new_hex_str].pack('H*').unpack('C*'))
|
|
424
430
|
end
|
|
425
431
|
|
|
432
|
+
def self.emulate_func(func_loc, ov, *args)
|
|
433
|
+
addr, ov, code_bin = resolve_code_loc(func_loc,ov)
|
|
434
|
+
$emu.load_overlay(ov) if !ov.nil? && ov >= 0
|
|
435
|
+
$emu.call_func(addr, *args)
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def self.emu_get_mem(loc, size)
|
|
439
|
+
addr, ov = resolve_loc(loc)
|
|
440
|
+
$emu.load_overlay(ov) if !ov.nil? && ov >= 0
|
|
441
|
+
$emu.read_mem(addr, size)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def self.emu_set_mem(loc, byte_str)
|
|
445
|
+
addr, ov = resolve_loc(loc)
|
|
446
|
+
$emu.load_overlay(ov) if !ov.nil? && ov >= 0
|
|
447
|
+
$emu.write_mem(addr, byte_str)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def self.assemble_arm(asm, addr: 0)
|
|
451
|
+
if asm.is_a? Array
|
|
452
|
+
asm.map.with_index {|ins,idx| $arm_assembler.assemble(ins,addr+4*idx).unpack('L')[0] }
|
|
453
|
+
else
|
|
454
|
+
$arm_assembler.assemble(asm).unpack('L')[0]
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def self.assemble_thumb(asm, addr: 0)
|
|
459
|
+
if asm.is_a? Array
|
|
460
|
+
asm.map.with_index {|ins,idx| $thumb_assembler.assemble(ins,addr+2*idx).unpack('S')[0] }
|
|
461
|
+
else
|
|
462
|
+
$thumb_assembler.assemble(asm).unpack('S')[0]
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
426
466
|
class << self
|
|
427
467
|
alias_method :get_u64, :get_dword
|
|
428
468
|
alias_method :get_u32, :get_word
|
|
@@ -596,7 +636,7 @@ class Nitro::CodeBin
|
|
|
596
636
|
|
|
597
637
|
instructions << ins
|
|
598
638
|
|
|
599
|
-
if target = ins.target_addr
|
|
639
|
+
if target = ins.target_addr # if target addr not nil
|
|
600
640
|
pool[target] ||= Unarm::Data.new(read_word(target), addr: target, loc: get_loc)
|
|
601
641
|
end
|
|
602
642
|
|
|
@@ -698,3 +738,44 @@ class Nitro::CodeBin
|
|
|
698
738
|
end
|
|
699
739
|
|
|
700
740
|
end
|
|
741
|
+
|
|
742
|
+
#
|
|
743
|
+
# Various utility methods tying Unicorn to the Unarm and Nitro modules
|
|
744
|
+
#
|
|
745
|
+
class Unicorn::Emulator
|
|
746
|
+
|
|
747
|
+
def load_arm9
|
|
748
|
+
arm = $rom.arm9
|
|
749
|
+
main_added = false
|
|
750
|
+
arm.autoload_entries.sort_by {|e| e[:address] }.each do |e|
|
|
751
|
+
if e[:address] > arm.end_addr # DTCM found
|
|
752
|
+
add_region(Uc::Region.new(e[:address], 16*1024))
|
|
753
|
+
next
|
|
754
|
+
end
|
|
755
|
+
if !main_added && e[:address] > arm.start_addr # Main section found
|
|
756
|
+
size = e[:address] - arm.start_addr
|
|
757
|
+
add_section(Uc::Sect.new(arm.start_addr, arm.get_sect_ptr(arm.start_addr,size), size))
|
|
758
|
+
main_added = true
|
|
759
|
+
end
|
|
760
|
+
next if e[:address]+e[:size] <= e[:address]
|
|
761
|
+
ptr = arm.get_sect_ptr(e[:address],e[:size])
|
|
762
|
+
add_section(Uc::Sect.new(e[:address], ptr, e[:size]))
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
def load_overlay(ov_id)
|
|
767
|
+
ov = $rom.get_overlay(ov_id)
|
|
768
|
+
add_section(Uc::Sect.new(ov.start_addr, ov.get_sect_ptr(ov.start_addr, ov.size), ov.size))
|
|
769
|
+
end
|
|
770
|
+
alias_method :load_ov, :load_overlay
|
|
771
|
+
|
|
772
|
+
def call_func(addr, *args)
|
|
773
|
+
raise "Calling functions with more than 4 args isn't supported yet" if args.length > 4
|
|
774
|
+
args.each_with_index do |arg,i|
|
|
775
|
+
send(:"write_r#{i}", arg)
|
|
776
|
+
end
|
|
777
|
+
run(from: addr, to: read_lr, timeout_ms: 5000)
|
|
778
|
+
read_r0
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
end
|
data/lib/ncpp/version.rb
CHANGED
data/lib/ncpp.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require_relative 'nitro/nitro.rb'
|
|
2
2
|
require_relative 'unarm/unarm.rb'
|
|
3
|
+
require_relative 'unicorn/unicorn.rb'
|
|
4
|
+
require_relative 'keystone/keystone.rb'
|
|
3
5
|
require_relative 'ncpp/interpreter.rb'
|
|
4
6
|
|
|
5
7
|
require 'json'
|
|
@@ -15,6 +17,10 @@ module NCPP
|
|
|
15
17
|
|
|
16
18
|
alias $rom $clean_rom # In most cases the clean rom will be desired
|
|
17
19
|
|
|
20
|
+
$emu = nil
|
|
21
|
+
$arm_assembler = nil
|
|
22
|
+
$thumb_assembler = nil
|
|
23
|
+
|
|
18
24
|
$config = nil
|
|
19
25
|
|
|
20
26
|
NCP_CONFIG_FILE_PATH = 'ncpatcher.json'
|
|
@@ -141,6 +147,11 @@ module NCPP
|
|
|
141
147
|
|
|
142
148
|
Unarm.load_symbols9(cfg['symbols9'].gsub(/\$\{env:([^}]+)\}/) { ENV[$1] }) unless cfg['symbols9'].empty?
|
|
143
149
|
Unarm.load_symbols7(cfg['symbols7'].gsub(/\$\{env:([^}]+)\}/) { ENV[$1] }) unless cfg['symbols7'].empty?
|
|
150
|
+
|
|
151
|
+
$emu = Uc::Emu.new
|
|
152
|
+
$emu.load_arm9
|
|
153
|
+
$arm_assembler = Ks::Assembler.new
|
|
154
|
+
$thumb_assembler = Ks::Assembler.new(mode: Ks::KS_MODE_THUMB)
|
|
144
155
|
end
|
|
145
156
|
|
|
146
157
|
def self.uninstall(cfg_path = CONFIG_FILE_PATH)
|
|
@@ -426,20 +437,6 @@ module NCPP
|
|
|
426
437
|
end
|
|
427
438
|
end
|
|
428
439
|
|
|
429
|
-
# interpreter = CFileInterpreter.new(
|
|
430
|
-
# files, $config['gen_path'], $config['command_prefix'], extra_commands, extra_variables,
|
|
431
|
-
# safe: safe_mode, puritan: puritan_mode
|
|
432
|
-
# )
|
|
433
|
-
# interpreter.run(verbose: !quiet)
|
|
434
|
-
# lines_parsed += interpreter.lines_parsed
|
|
435
|
-
|
|
436
|
-
# unless interpreter.incomplete_files.empty?
|
|
437
|
-
# interpreter.incomplete_files.each do |file|
|
|
438
|
-
# timestamp_cache.delete(file)
|
|
439
|
-
# success = false
|
|
440
|
-
# end
|
|
441
|
-
# end
|
|
442
|
-
|
|
443
440
|
end
|
|
444
441
|
|
|
445
442
|
timestamp_cache['NCPP_VERSION'] = VERSION
|
|
@@ -447,9 +444,6 @@ module NCPP
|
|
|
447
444
|
FileUtils.mkdir_p(File.dirname(timestamp_cache_path))
|
|
448
445
|
File.write(timestamp_cache_path, JSON.generate(timestamp_cache))
|
|
449
446
|
|
|
450
|
-
# FileUtils.mkdir_p(File.dirname(cmd_cache_path))
|
|
451
|
-
# File.write(cmd_cache_path, JSON.generate(command_cache))
|
|
452
|
-
|
|
453
447
|
unless quiet
|
|
454
448
|
if lines_parsed > 0
|
|
455
449
|
msg = "\nParsed #{lines_parsed} line#{'s' if lines_parsed != 1} across " \
|
data/lib/nitro/nitro.dylib
CHANGED
|
Binary file
|
data/lib/nitro/nitro.rb
CHANGED
|
@@ -13,6 +13,7 @@ module NitroBind
|
|
|
13
13
|
typedef :pointer, :codebin_handle
|
|
14
14
|
typedef :pointer, :ovte_handle
|
|
15
15
|
typedef :pointer, :module_params_handle
|
|
16
|
+
typedef :pointer, :autoload_entry_handle
|
|
16
17
|
|
|
17
18
|
attach_function :nitroRom_alloc, [], :rom_handle
|
|
18
19
|
attach_function :nitroRom_release, [:rom_handle], :void
|
|
@@ -48,12 +49,15 @@ module NitroBind
|
|
|
48
49
|
attach_function :codeBin_readCString, [:codebin_handle, :uint32], :string
|
|
49
50
|
attach_function :codeBin_getSize, [:codebin_handle], :uint32
|
|
50
51
|
attach_function :codeBin_getStartAddress, [:codebin_handle], :uint32
|
|
52
|
+
attach_function :codeBin_getSectPtr, [:codebin_handle, :uint32, :size_t], :pointer
|
|
51
53
|
|
|
52
54
|
attach_function :armBin_alloc, [], :codebin_handle
|
|
53
55
|
attach_function :armBin_release, [:codebin_handle], :void
|
|
54
56
|
attach_function :armBin_load, [:codebin_handle, :string, :uint32, :uint32, :uint32, :bool], :bool
|
|
55
57
|
attach_function :armBin_getEntryPointAddress, [:codebin_handle], :uint32
|
|
56
58
|
attach_function :armBin_getModuleParams, [:codebin_handle], :module_params_handle
|
|
59
|
+
attach_function :armBin_getAutoloadEntry, [:codebin_handle, :size_t], :autoload_entry_handle
|
|
60
|
+
attach_function :armBin_getAutoloadEntryCount, [:codebin_handle], :size_t
|
|
57
61
|
attach_function :armBin_sanityCheckAddress, [:codebin_handle, :uint32], :bool
|
|
58
62
|
|
|
59
63
|
attach_function :overlayBin_alloc, [], :codebin_handle
|
|
@@ -176,7 +180,7 @@ module Nitro
|
|
|
176
180
|
raise ArgumentError, 'step must be 1, 2, 4, or 8 (bytes)' unless [1,2,4,8].include? step
|
|
177
181
|
raise ArgumentError, 'range must be a Range' unless range.is_a? Range
|
|
178
182
|
|
|
179
|
-
clamped = Range.new(
|
|
183
|
+
clamped = Range.new(range.begin || start_addr, [range.end || end_addr, end_addr].min)
|
|
180
184
|
|
|
181
185
|
clamped.step(step).map { |addr| [send(:"read#{step * 8}", addr), addr] }
|
|
182
186
|
end
|
|
@@ -211,17 +215,25 @@ module Nitro
|
|
|
211
215
|
end
|
|
212
216
|
end
|
|
213
217
|
|
|
214
|
-
def read_cstring(
|
|
215
|
-
codeBin_readCString(@ptr,
|
|
218
|
+
def read_cstring(addr)
|
|
219
|
+
codeBin_readCString(@ptr, addr)
|
|
216
220
|
end
|
|
217
221
|
alias_method :read_cstr, :read_cstring
|
|
218
222
|
|
|
223
|
+
def get_section_ptr(addr, sect_size)
|
|
224
|
+
ptr = FFI::MemoryPointer.new(:pointer, 1)
|
|
225
|
+
ptr.write_pointer(codeBin_getSectPtr(@ptr, addr, sect_size))
|
|
226
|
+
raise "Could not read #{sect_size} bytes from address #{addr.to_hex}" if ptr.read_pointer == FFI::Pointer::NULL
|
|
227
|
+
ptr.read_pointer
|
|
228
|
+
end
|
|
229
|
+
alias_method :get_sect_ptr, :get_section_ptr
|
|
230
|
+
|
|
219
231
|
end
|
|
220
232
|
|
|
221
233
|
class ArmBin < CodeBin
|
|
222
234
|
include NitroBind
|
|
223
235
|
|
|
224
|
-
attr_reader :module_params
|
|
236
|
+
attr_reader :module_params, :autoload_entries
|
|
225
237
|
|
|
226
238
|
class ModuleParams < FFI::Struct
|
|
227
239
|
layout :autoload_list_start, :uint32,
|
|
@@ -235,10 +247,17 @@ module Nitro
|
|
|
235
247
|
:nitro_code_le, :uint32
|
|
236
248
|
end
|
|
237
249
|
|
|
250
|
+
class AutoLoadEntry < FFI::Struct
|
|
251
|
+
layout :address, :uint32,
|
|
252
|
+
:size, :uint32,
|
|
253
|
+
:bss_size, :uint32,
|
|
254
|
+
:data_offset, :uint32
|
|
255
|
+
end
|
|
256
|
+
|
|
238
257
|
def initialize(args = {})
|
|
239
258
|
if args.has_key? :file_path
|
|
240
259
|
@ptr = FFI::AutoPointer.new(armBin_alloc, method(:armBin_release))
|
|
241
|
-
if
|
|
260
|
+
if !File.exist?(args[:file_path])
|
|
242
261
|
puts "Error: #{args[:file_path]} does not exist"
|
|
243
262
|
raise 'ArmBin initialization failed'
|
|
244
263
|
end
|
|
@@ -253,6 +272,9 @@ module Nitro
|
|
|
253
272
|
end
|
|
254
273
|
|
|
255
274
|
@module_params = ModuleParams.new(armBin_getModuleParams(@ptr))
|
|
275
|
+
@autoload_entries = []
|
|
276
|
+
autoload_entry_count = armBin_getAutoloadEntryCount(@ptr)
|
|
277
|
+
autoload_entry_count.times {|id| autoload_entries << AutoLoadEntry.new(armBin_getAutoloadEntry(@ptr,id)) }
|
|
256
278
|
end
|
|
257
279
|
|
|
258
280
|
def entry_point_address
|
data/lib/unarm/unarm.dylib
CHANGED
|
Binary file
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm_const.rb]
|
|
2
|
+
|
|
3
|
+
module UnicornEngine
|
|
4
|
+
|
|
5
|
+
# ARM CPU
|
|
6
|
+
|
|
7
|
+
UC_CPU_ARM_926 = 0
|
|
8
|
+
UC_CPU_ARM_946 = 1
|
|
9
|
+
UC_CPU_ARM_1026 = 2
|
|
10
|
+
UC_CPU_ARM_1136_R2 = 3
|
|
11
|
+
UC_CPU_ARM_1136 = 4
|
|
12
|
+
UC_CPU_ARM_1176 = 5
|
|
13
|
+
UC_CPU_ARM_11MPCORE = 6
|
|
14
|
+
UC_CPU_ARM_CORTEX_M0 = 7
|
|
15
|
+
UC_CPU_ARM_CORTEX_M3 = 8
|
|
16
|
+
UC_CPU_ARM_CORTEX_M4 = 9
|
|
17
|
+
UC_CPU_ARM_CORTEX_M7 = 10
|
|
18
|
+
UC_CPU_ARM_CORTEX_M33 = 11
|
|
19
|
+
UC_CPU_ARM_CORTEX_R5 = 12
|
|
20
|
+
UC_CPU_ARM_CORTEX_R5F = 13
|
|
21
|
+
UC_CPU_ARM_CORTEX_A7 = 14
|
|
22
|
+
UC_CPU_ARM_CORTEX_A8 = 15
|
|
23
|
+
UC_CPU_ARM_CORTEX_A9 = 16
|
|
24
|
+
UC_CPU_ARM_CORTEX_A15 = 17
|
|
25
|
+
UC_CPU_ARM_TI925T = 18
|
|
26
|
+
UC_CPU_ARM_SA1100 = 19
|
|
27
|
+
UC_CPU_ARM_SA1110 = 20
|
|
28
|
+
UC_CPU_ARM_PXA250 = 21
|
|
29
|
+
UC_CPU_ARM_PXA255 = 22
|
|
30
|
+
UC_CPU_ARM_PXA260 = 23
|
|
31
|
+
UC_CPU_ARM_PXA261 = 24
|
|
32
|
+
UC_CPU_ARM_PXA262 = 25
|
|
33
|
+
UC_CPU_ARM_PXA270 = 26
|
|
34
|
+
UC_CPU_ARM_PXA270A0 = 27
|
|
35
|
+
UC_CPU_ARM_PXA270A1 = 28
|
|
36
|
+
UC_CPU_ARM_PXA270B0 = 29
|
|
37
|
+
UC_CPU_ARM_PXA270B1 = 30
|
|
38
|
+
UC_CPU_ARM_PXA270C0 = 31
|
|
39
|
+
UC_CPU_ARM_PXA270C5 = 32
|
|
40
|
+
UC_CPU_ARM_MAX = 33
|
|
41
|
+
UC_CPU_ARM_ENDING = 34
|
|
42
|
+
|
|
43
|
+
# ARM registers
|
|
44
|
+
|
|
45
|
+
UC_ARM_REG_INVALID = 0
|
|
46
|
+
UC_ARM_REG_APSR = 1
|
|
47
|
+
UC_ARM_REG_APSR_NZCV = 2
|
|
48
|
+
UC_ARM_REG_CPSR = 3
|
|
49
|
+
UC_ARM_REG_FPEXC = 4
|
|
50
|
+
UC_ARM_REG_FPINST = 5
|
|
51
|
+
UC_ARM_REG_FPSCR = 6
|
|
52
|
+
UC_ARM_REG_FPSCR_NZCV = 7
|
|
53
|
+
UC_ARM_REG_FPSID = 8
|
|
54
|
+
UC_ARM_REG_ITSTATE = 9
|
|
55
|
+
UC_ARM_REG_LR = 10
|
|
56
|
+
UC_ARM_REG_PC = 11
|
|
57
|
+
UC_ARM_REG_SP = 12
|
|
58
|
+
UC_ARM_REG_SPSR = 13
|
|
59
|
+
UC_ARM_REG_D0 = 14
|
|
60
|
+
UC_ARM_REG_D1 = 15
|
|
61
|
+
UC_ARM_REG_D2 = 16
|
|
62
|
+
UC_ARM_REG_D3 = 17
|
|
63
|
+
UC_ARM_REG_D4 = 18
|
|
64
|
+
UC_ARM_REG_D5 = 19
|
|
65
|
+
UC_ARM_REG_D6 = 20
|
|
66
|
+
UC_ARM_REG_D7 = 21
|
|
67
|
+
UC_ARM_REG_D8 = 22
|
|
68
|
+
UC_ARM_REG_D9 = 23
|
|
69
|
+
UC_ARM_REG_D10 = 24
|
|
70
|
+
UC_ARM_REG_D11 = 25
|
|
71
|
+
UC_ARM_REG_D12 = 26
|
|
72
|
+
UC_ARM_REG_D13 = 27
|
|
73
|
+
UC_ARM_REG_D14 = 28
|
|
74
|
+
UC_ARM_REG_D15 = 29
|
|
75
|
+
UC_ARM_REG_D16 = 30
|
|
76
|
+
UC_ARM_REG_D17 = 31
|
|
77
|
+
UC_ARM_REG_D18 = 32
|
|
78
|
+
UC_ARM_REG_D19 = 33
|
|
79
|
+
UC_ARM_REG_D20 = 34
|
|
80
|
+
UC_ARM_REG_D21 = 35
|
|
81
|
+
UC_ARM_REG_D22 = 36
|
|
82
|
+
UC_ARM_REG_D23 = 37
|
|
83
|
+
UC_ARM_REG_D24 = 38
|
|
84
|
+
UC_ARM_REG_D25 = 39
|
|
85
|
+
UC_ARM_REG_D26 = 40
|
|
86
|
+
UC_ARM_REG_D27 = 41
|
|
87
|
+
UC_ARM_REG_D28 = 42
|
|
88
|
+
UC_ARM_REG_D29 = 43
|
|
89
|
+
UC_ARM_REG_D30 = 44
|
|
90
|
+
UC_ARM_REG_D31 = 45
|
|
91
|
+
UC_ARM_REG_FPINST2 = 46
|
|
92
|
+
UC_ARM_REG_MVFR0 = 47
|
|
93
|
+
UC_ARM_REG_MVFR1 = 48
|
|
94
|
+
UC_ARM_REG_MVFR2 = 49
|
|
95
|
+
UC_ARM_REG_Q0 = 50
|
|
96
|
+
UC_ARM_REG_Q1 = 51
|
|
97
|
+
UC_ARM_REG_Q2 = 52
|
|
98
|
+
UC_ARM_REG_Q3 = 53
|
|
99
|
+
UC_ARM_REG_Q4 = 54
|
|
100
|
+
UC_ARM_REG_Q5 = 55
|
|
101
|
+
UC_ARM_REG_Q6 = 56
|
|
102
|
+
UC_ARM_REG_Q7 = 57
|
|
103
|
+
UC_ARM_REG_Q8 = 58
|
|
104
|
+
UC_ARM_REG_Q9 = 59
|
|
105
|
+
UC_ARM_REG_Q10 = 60
|
|
106
|
+
UC_ARM_REG_Q11 = 61
|
|
107
|
+
UC_ARM_REG_Q12 = 62
|
|
108
|
+
UC_ARM_REG_Q13 = 63
|
|
109
|
+
UC_ARM_REG_Q14 = 64
|
|
110
|
+
UC_ARM_REG_Q15 = 65
|
|
111
|
+
UC_ARM_REG_R0 = 66
|
|
112
|
+
UC_ARM_REG_R1 = 67
|
|
113
|
+
UC_ARM_REG_R2 = 68
|
|
114
|
+
UC_ARM_REG_R3 = 69
|
|
115
|
+
UC_ARM_REG_R4 = 70
|
|
116
|
+
UC_ARM_REG_R5 = 71
|
|
117
|
+
UC_ARM_REG_R6 = 72
|
|
118
|
+
UC_ARM_REG_R7 = 73
|
|
119
|
+
UC_ARM_REG_R8 = 74
|
|
120
|
+
UC_ARM_REG_R9 = 75
|
|
121
|
+
UC_ARM_REG_R10 = 76
|
|
122
|
+
UC_ARM_REG_R11 = 77
|
|
123
|
+
UC_ARM_REG_R12 = 78
|
|
124
|
+
UC_ARM_REG_S0 = 79
|
|
125
|
+
UC_ARM_REG_S1 = 80
|
|
126
|
+
UC_ARM_REG_S2 = 81
|
|
127
|
+
UC_ARM_REG_S3 = 82
|
|
128
|
+
UC_ARM_REG_S4 = 83
|
|
129
|
+
UC_ARM_REG_S5 = 84
|
|
130
|
+
UC_ARM_REG_S6 = 85
|
|
131
|
+
UC_ARM_REG_S7 = 86
|
|
132
|
+
UC_ARM_REG_S8 = 87
|
|
133
|
+
UC_ARM_REG_S9 = 88
|
|
134
|
+
UC_ARM_REG_S10 = 89
|
|
135
|
+
UC_ARM_REG_S11 = 90
|
|
136
|
+
UC_ARM_REG_S12 = 91
|
|
137
|
+
UC_ARM_REG_S13 = 92
|
|
138
|
+
UC_ARM_REG_S14 = 93
|
|
139
|
+
UC_ARM_REG_S15 = 94
|
|
140
|
+
UC_ARM_REG_S16 = 95
|
|
141
|
+
UC_ARM_REG_S17 = 96
|
|
142
|
+
UC_ARM_REG_S18 = 97
|
|
143
|
+
UC_ARM_REG_S19 = 98
|
|
144
|
+
UC_ARM_REG_S20 = 99
|
|
145
|
+
UC_ARM_REG_S21 = 100
|
|
146
|
+
UC_ARM_REG_S22 = 101
|
|
147
|
+
UC_ARM_REG_S23 = 102
|
|
148
|
+
UC_ARM_REG_S24 = 103
|
|
149
|
+
UC_ARM_REG_S25 = 104
|
|
150
|
+
UC_ARM_REG_S26 = 105
|
|
151
|
+
UC_ARM_REG_S27 = 106
|
|
152
|
+
UC_ARM_REG_S28 = 107
|
|
153
|
+
UC_ARM_REG_S29 = 108
|
|
154
|
+
UC_ARM_REG_S30 = 109
|
|
155
|
+
UC_ARM_REG_S31 = 110
|
|
156
|
+
UC_ARM_REG_C1_C0_2 = 111
|
|
157
|
+
UC_ARM_REG_C13_C0_2 = 112
|
|
158
|
+
UC_ARM_REG_C13_C0_3 = 113
|
|
159
|
+
UC_ARM_REG_IPSR = 114
|
|
160
|
+
UC_ARM_REG_MSP = 115
|
|
161
|
+
UC_ARM_REG_PSP = 116
|
|
162
|
+
UC_ARM_REG_CONTROL = 117
|
|
163
|
+
UC_ARM_REG_IAPSR = 118
|
|
164
|
+
UC_ARM_REG_EAPSR = 119
|
|
165
|
+
UC_ARM_REG_XPSR = 120
|
|
166
|
+
UC_ARM_REG_EPSR = 121
|
|
167
|
+
UC_ARM_REG_IEPSR = 122
|
|
168
|
+
UC_ARM_REG_PRIMASK = 123
|
|
169
|
+
UC_ARM_REG_BASEPRI = 124
|
|
170
|
+
UC_ARM_REG_BASEPRI_MAX = 125
|
|
171
|
+
UC_ARM_REG_FAULTMASK = 126
|
|
172
|
+
UC_ARM_REG_APSR_NZCVQ = 127
|
|
173
|
+
UC_ARM_REG_APSR_G = 128
|
|
174
|
+
UC_ARM_REG_APSR_NZCVQG = 129
|
|
175
|
+
UC_ARM_REG_IAPSR_NZCVQ = 130
|
|
176
|
+
UC_ARM_REG_IAPSR_G = 131
|
|
177
|
+
UC_ARM_REG_IAPSR_NZCVQG = 132
|
|
178
|
+
UC_ARM_REG_EAPSR_NZCVQ = 133
|
|
179
|
+
UC_ARM_REG_EAPSR_G = 134
|
|
180
|
+
UC_ARM_REG_EAPSR_NZCVQG = 135
|
|
181
|
+
UC_ARM_REG_XPSR_NZCVQ = 136
|
|
182
|
+
UC_ARM_REG_XPSR_G = 137
|
|
183
|
+
UC_ARM_REG_XPSR_NZCVQG = 138
|
|
184
|
+
UC_ARM_REG_CP_REG = 139
|
|
185
|
+
UC_ARM_REG_ESR = 140
|
|
186
|
+
UC_ARM_REG_ENDING = 141
|
|
187
|
+
|
|
188
|
+
# alias registers
|
|
189
|
+
UC_ARM_REG_R13 = 12
|
|
190
|
+
UC_ARM_REG_R14 = 10
|
|
191
|
+
UC_ARM_REG_R15 = 11
|
|
192
|
+
UC_ARM_REG_SB = 75
|
|
193
|
+
UC_ARM_REG_SL = 76
|
|
194
|
+
UC_ARM_REG_FP = 77
|
|
195
|
+
UC_ARM_REG_IP = 78
|
|
196
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
require 'ffi'
|
|
2
|
+
|
|
3
|
+
require_relative 'arm_const.rb'
|
|
4
|
+
require_relative 'unicorn_const.rb'
|
|
5
|
+
|
|
6
|
+
include UnicornEngine
|
|
7
|
+
|
|
8
|
+
module UnicornBind
|
|
9
|
+
extend FFI::Library
|
|
10
|
+
ffi_lib [
|
|
11
|
+
File.expand_path("unicorn", __dir__),
|
|
12
|
+
File.expand_path("unicorn.dylib", __dir__),
|
|
13
|
+
File.expand_path("unicorn.so", __dir__),
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
typedef :pointer, :uc_engine # ptr to uc_engine instance
|
|
17
|
+
typedef :pointer, :uc_engine_handle # ptr to a uc_engine ptr
|
|
18
|
+
typedef :pointer, :reg_val_ptr
|
|
19
|
+
typedef :pointer, :reg_val_ptr_arr
|
|
20
|
+
typedef :pointer, :reg_id_arr
|
|
21
|
+
typedef :uint64, :addr
|
|
22
|
+
typedef :uint, :uc_arch
|
|
23
|
+
typedef :uint, :uc_mode
|
|
24
|
+
typedef :uint, :uc_err
|
|
25
|
+
typedef :uint, :uc_query_type
|
|
26
|
+
typedef :uint, :uc_control_type
|
|
27
|
+
typedef :int, :reg_id
|
|
28
|
+
|
|
29
|
+
attach_function :uc_version, [:pointer,:pointer], :uint
|
|
30
|
+
attach_function :uc_arch_supported, [:uc_arch], :bool
|
|
31
|
+
attach_function :uc_open, [:uc_arch, :uc_mode, :uc_engine_handle], :uc_err
|
|
32
|
+
attach_function :uc_close, [:uc_engine], :uc_err
|
|
33
|
+
attach_function :uc_query, [:uc_engine, :uc_query_type, :pointer], :uc_err
|
|
34
|
+
attach_function :uc_ctl, [:uc_engine, :uc_control_type, :varargs], :uc_err
|
|
35
|
+
attach_function :uc_errno, [:uc_engine], :uc_err
|
|
36
|
+
attach_function :uc_strerror, [:uc_err], :string
|
|
37
|
+
attach_function :uc_reg_write, [:uc_engine, :reg_id, :reg_val_ptr], :uc_err
|
|
38
|
+
attach_function :uc_reg_read, [:uc_engine, :reg_id, :reg_val_ptr], :uc_err
|
|
39
|
+
attach_function :uc_reg_write_batch, [:uc_engine, :reg_id_arr, :reg_val_ptr_arr, :int], :uc_err
|
|
40
|
+
attach_function :uc_reg_read_batch, [:uc_engine, :reg_id_arr, :reg_val_ptr_arr, :int], :uc_err
|
|
41
|
+
attach_function :uc_mem_write, [:uc_engine, :addr, :pointer, :uint64], :uc_err
|
|
42
|
+
attach_function :uc_mem_read, [:uc_engine, :addr, :pointer, :uint64], :uc_err
|
|
43
|
+
attach_function :uc_emu_start, [:uc_engine, :addr, :addr, :uint64, :size_t], :uc_err
|
|
44
|
+
attach_function :uc_emu_stop, [:uc_engine], :uc_err
|
|
45
|
+
attach_function :uc_mem_map, [:uc_engine, :addr, :uint64, :uint32], :uc_err
|
|
46
|
+
attach_function :uc_mem_map_ptr, [:uc_engine, :addr, :uint64, :uint32, :pointer], :uc_err
|
|
47
|
+
attach_function :uc_mem_unmap, [:uc_engine, :addr, :uint64], :uc_err
|
|
48
|
+
attach_function :uc_mem_protect, [:uc_engine, :addr, :uint64, :uint32], :uc_err
|
|
49
|
+
|
|
50
|
+
REG_ID = {
|
|
51
|
+
r0: UC_ARM_REG_R0,
|
|
52
|
+
r1: UC_ARM_REG_R1,
|
|
53
|
+
r2: UC_ARM_REG_R2,
|
|
54
|
+
r3: UC_ARM_REG_R3,
|
|
55
|
+
r4: UC_ARM_REG_R4,
|
|
56
|
+
r5: UC_ARM_REG_R5,
|
|
57
|
+
r6: UC_ARM_REG_R6,
|
|
58
|
+
r7: UC_ARM_REG_R7,
|
|
59
|
+
r8: UC_ARM_REG_R8,
|
|
60
|
+
r9: UC_ARM_REG_R9,
|
|
61
|
+
r10: UC_ARM_REG_R10,
|
|
62
|
+
r11: UC_ARM_REG_R11,
|
|
63
|
+
r12: UC_ARM_REG_R12,
|
|
64
|
+
sp: UC_ARM_REG_SP,
|
|
65
|
+
lr: UC_ARM_REG_LR,
|
|
66
|
+
pc: UC_ARM_REG_PC,
|
|
67
|
+
cpsr: UC_ARM_REG_CPSR,
|
|
68
|
+
spsr: UC_ARM_REG_SPSR
|
|
69
|
+
}.freeze
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
module Unicorn
|
|
73
|
+
extend UnicornBind
|
|
74
|
+
|
|
75
|
+
class Region
|
|
76
|
+
attr_reader :addr, :size, :prot, :end_addr
|
|
77
|
+
def initialize(addr, size, prot = UC_PROT_ALL)
|
|
78
|
+
@addr = addr
|
|
79
|
+
@size = size
|
|
80
|
+
@prot = prot
|
|
81
|
+
@end_addr = addr + size
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
NDS_REGIONS = [
|
|
86
|
+
Region.new(0x1ff8000, 32*1024), # ITCM -> 32KB
|
|
87
|
+
Region.new(0x2000000, 4*1024*1024), # Main memory -> 4MB
|
|
88
|
+
Region.new(0x4000000, 64*1024*1024), # I/O and VRAM -> 64MB
|
|
89
|
+
Region.new(0xffff000, 32*1024) # BIOS -> 32KB
|
|
90
|
+
].freeze
|
|
91
|
+
|
|
92
|
+
class Section
|
|
93
|
+
attr_reader :addr, :ptr, :size, :end_addr
|
|
94
|
+
def initialize(addr, ffi_ptr, size)
|
|
95
|
+
@addr = addr
|
|
96
|
+
@ptr = ffi_ptr
|
|
97
|
+
@size = size
|
|
98
|
+
@end_addr = addr + size
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
Sect = Section
|
|
102
|
+
|
|
103
|
+
class Emulator
|
|
104
|
+
include UnicornBind
|
|
105
|
+
|
|
106
|
+
def initialize(arch: UC_ARCH_ARM, mode: UC_MODE_ARM946, regions: NDS_REGIONS, sections: [], registers: {})
|
|
107
|
+
|
|
108
|
+
FFI::MemoryPointer.new(:pointer, 1) do |ptr|
|
|
109
|
+
safe_call(:uc_open, arch, mode, ptr)
|
|
110
|
+
@engine = FFI::AutoPointer.new(ptr.read_pointer, method(:uc_close))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
regions.each { add_region(it) } unless regions.empty?
|
|
114
|
+
sections.each { add_sect(it) } unless sections.empty?
|
|
115
|
+
registers.each {|r,v| write_register(r,v) } unless registers.empty?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def run(from: nil, to: -1, timeout_ms: 0, max_ins: 0)
|
|
119
|
+
raise "The 'from' parameter must be specified" if from.nil?
|
|
120
|
+
if to == -1 && timeout_ms == 0 && max_ins == 0
|
|
121
|
+
raise "The 'to' parameter must be specified if 'timeout_ms' or 'max_ins' are not"
|
|
122
|
+
end
|
|
123
|
+
safe_call(:uc_emu_start, @engine, from, to, timeout_ms, max_ins)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def add_region(region)
|
|
127
|
+
safe_call(:uc_mem_map, @engine, region.addr, region.size, region.prot)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def add_section(sect)
|
|
131
|
+
safe_call(:uc_mem_write, @engine, sect.addr, sect.ptr, sect.size)
|
|
132
|
+
end
|
|
133
|
+
alias_method :add_sect, :add_section
|
|
134
|
+
|
|
135
|
+
def write_mem(addr, byte_str)
|
|
136
|
+
FFI::MemoryPointer.new(:uint8, byte_str.bytesize) do |ptr|
|
|
137
|
+
ptr.write_array_of_uint8(byte_str.bytes)
|
|
138
|
+
safe_call(:uc_mem_write, @engine, addr, ptr, byte_str.bytesize)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def read_mem(addr, size)
|
|
143
|
+
byte_str = nil
|
|
144
|
+
FFI::MemoryPointer.new(:uint8, size) do |ptr|
|
|
145
|
+
safe_call(:uc_mem_read, @engine, addr, ptr, size)
|
|
146
|
+
byte_str = ptr.read_array_of_uint8(size).pack('C*')
|
|
147
|
+
end
|
|
148
|
+
byte_str
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def write_register(reg, val)
|
|
152
|
+
FFI::MemoryPointer.new(:int32, 1) do |pv|
|
|
153
|
+
pv.write_int(val)
|
|
154
|
+
safe_call(:uc_reg_write, @engine, REG_ID[reg], pv)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
alias_method :write_reg, :write_register
|
|
158
|
+
|
|
159
|
+
def write_registers(regs_h)
|
|
160
|
+
regs_h.each {|r,v| write_register(r,v) }
|
|
161
|
+
end
|
|
162
|
+
alias_method :write_regs, :write_registers
|
|
163
|
+
|
|
164
|
+
REG_ID.each do |name, id|
|
|
165
|
+
define_method("write_#{name.to_s}".to_sym) do |val|
|
|
166
|
+
write_register(name, val)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def read_register(reg)
|
|
171
|
+
val = nil
|
|
172
|
+
FFI::MemoryPointer.new(:int32, 1) do |pv|
|
|
173
|
+
safe_call(:uc_reg_read, @engine, REG_ID[reg], pv)
|
|
174
|
+
val = pv.read_int32
|
|
175
|
+
end
|
|
176
|
+
val
|
|
177
|
+
end
|
|
178
|
+
alias_method :read_reg, :read_register
|
|
179
|
+
|
|
180
|
+
def read_registers(reg_names = REG_ID.keys)
|
|
181
|
+
regs_h = {}
|
|
182
|
+
reg_names.each {|r| regs_h[r] = read_register(r) }
|
|
183
|
+
regs_h
|
|
184
|
+
end
|
|
185
|
+
alias_method :read_regs, :read_registers
|
|
186
|
+
|
|
187
|
+
REG_ID.each do |name, id|
|
|
188
|
+
define_method("read_#{name.to_s}".to_sym) do
|
|
189
|
+
read_register(name)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
def safe_call(meth_sym, *args)
|
|
195
|
+
err = send(meth_sym, *args)
|
|
196
|
+
raise "Error from #{meth_sym.to_s}: #{uc_strerror(err)}" if err != UC_ERR_OK
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
Emu = Emulator
|
|
201
|
+
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
Uc = Unicorn
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [unicorn_const.rb]
|
|
2
|
+
|
|
3
|
+
module UnicornEngine
|
|
4
|
+
UC_API_MAJOR = 2
|
|
5
|
+
UC_API_MINOR = 1
|
|
6
|
+
UC_API_PATCH = 4
|
|
7
|
+
UC_API_EXTRA = 255
|
|
8
|
+
UC_VERSION_MAJOR = 2
|
|
9
|
+
UC_VERSION_MINOR = 1
|
|
10
|
+
UC_VERSION_PATCH = 4
|
|
11
|
+
UC_VERSION_EXTRA = 255
|
|
12
|
+
UC_SECOND_SCALE = 1000000
|
|
13
|
+
UC_MILISECOND_SCALE = 1000
|
|
14
|
+
UC_ARCH_ARM = 1
|
|
15
|
+
UC_ARCH_ARM64 = 2
|
|
16
|
+
UC_ARCH_MIPS = 3
|
|
17
|
+
UC_ARCH_X86 = 4
|
|
18
|
+
UC_ARCH_PPC = 5
|
|
19
|
+
UC_ARCH_SPARC = 6
|
|
20
|
+
UC_ARCH_M68K = 7
|
|
21
|
+
UC_ARCH_RISCV = 8
|
|
22
|
+
UC_ARCH_S390X = 9
|
|
23
|
+
UC_ARCH_TRICORE = 10
|
|
24
|
+
UC_ARCH_MAX = 11
|
|
25
|
+
|
|
26
|
+
UC_MODE_LITTLE_ENDIAN = 0
|
|
27
|
+
UC_MODE_BIG_ENDIAN = 1073741824
|
|
28
|
+
|
|
29
|
+
UC_MODE_ARM = 0
|
|
30
|
+
UC_MODE_THUMB = 16
|
|
31
|
+
UC_MODE_MCLASS = 32
|
|
32
|
+
UC_MODE_V8 = 64
|
|
33
|
+
UC_MODE_ARMBE8 = 1024
|
|
34
|
+
UC_MODE_ARM926 = 128
|
|
35
|
+
UC_MODE_ARM946 = 256
|
|
36
|
+
UC_MODE_ARM1176 = 512
|
|
37
|
+
UC_MODE_MICRO = 16
|
|
38
|
+
UC_MODE_MIPS3 = 32
|
|
39
|
+
UC_MODE_MIPS32R6 = 64
|
|
40
|
+
UC_MODE_MIPS32 = 4
|
|
41
|
+
UC_MODE_MIPS64 = 8
|
|
42
|
+
UC_MODE_16 = 2
|
|
43
|
+
UC_MODE_32 = 4
|
|
44
|
+
UC_MODE_64 = 8
|
|
45
|
+
UC_MODE_PPC32 = 4
|
|
46
|
+
UC_MODE_PPC64 = 8
|
|
47
|
+
UC_MODE_QPX = 16
|
|
48
|
+
UC_MODE_SPARC32 = 4
|
|
49
|
+
UC_MODE_SPARC64 = 8
|
|
50
|
+
UC_MODE_V9 = 16
|
|
51
|
+
UC_MODE_RISCV32 = 4
|
|
52
|
+
UC_MODE_RISCV64 = 8
|
|
53
|
+
|
|
54
|
+
UC_ERR_OK = 0
|
|
55
|
+
UC_ERR_NOMEM = 1
|
|
56
|
+
UC_ERR_ARCH = 2
|
|
57
|
+
UC_ERR_HANDLE = 3
|
|
58
|
+
UC_ERR_MODE = 4
|
|
59
|
+
UC_ERR_VERSION = 5
|
|
60
|
+
UC_ERR_READ_UNMAPPED = 6
|
|
61
|
+
UC_ERR_WRITE_UNMAPPED = 7
|
|
62
|
+
UC_ERR_FETCH_UNMAPPED = 8
|
|
63
|
+
UC_ERR_HOOK = 9
|
|
64
|
+
UC_ERR_INSN_INVALID = 10
|
|
65
|
+
UC_ERR_MAP = 11
|
|
66
|
+
UC_ERR_WRITE_PROT = 12
|
|
67
|
+
UC_ERR_READ_PROT = 13
|
|
68
|
+
UC_ERR_FETCH_PROT = 14
|
|
69
|
+
UC_ERR_ARG = 15
|
|
70
|
+
UC_ERR_READ_UNALIGNED = 16
|
|
71
|
+
UC_ERR_WRITE_UNALIGNED = 17
|
|
72
|
+
UC_ERR_FETCH_UNALIGNED = 18
|
|
73
|
+
UC_ERR_HOOK_EXIST = 19
|
|
74
|
+
UC_ERR_RESOURCE = 20
|
|
75
|
+
UC_ERR_EXCEPTION = 21
|
|
76
|
+
UC_ERR_OVERFLOW = 22
|
|
77
|
+
|
|
78
|
+
UC_PROT_NONE = 0
|
|
79
|
+
UC_PROT_READ = 1
|
|
80
|
+
UC_PROT_WRITE = 2
|
|
81
|
+
UC_PROT_EXEC = 4
|
|
82
|
+
UC_PROT_ALL = 7
|
|
83
|
+
UC_MEM_READ = 16
|
|
84
|
+
UC_MEM_WRITE = 17
|
|
85
|
+
UC_MEM_FETCH = 18
|
|
86
|
+
UC_MEM_READ_UNMAPPED = 19
|
|
87
|
+
UC_MEM_WRITE_UNMAPPED = 20
|
|
88
|
+
UC_MEM_FETCH_UNMAPPED = 21
|
|
89
|
+
UC_MEM_WRITE_PROT = 22
|
|
90
|
+
UC_MEM_READ_PROT = 23
|
|
91
|
+
UC_MEM_FETCH_PROT = 24
|
|
92
|
+
UC_MEM_READ_AFTER = 25
|
|
93
|
+
|
|
94
|
+
UC_TCG_OP_SUB = 0
|
|
95
|
+
UC_TCG_OP_FLAG_CMP = 1
|
|
96
|
+
UC_TCG_OP_FLAG_DIRECT = 2
|
|
97
|
+
UC_HOOK_INTR = 1
|
|
98
|
+
UC_HOOK_INSN = 2
|
|
99
|
+
UC_HOOK_CODE = 4
|
|
100
|
+
UC_HOOK_BLOCK = 8
|
|
101
|
+
UC_HOOK_MEM_READ_UNMAPPED = 16
|
|
102
|
+
UC_HOOK_MEM_WRITE_UNMAPPED = 32
|
|
103
|
+
UC_HOOK_MEM_FETCH_UNMAPPED = 64
|
|
104
|
+
UC_HOOK_MEM_READ_PROT = 128
|
|
105
|
+
UC_HOOK_MEM_WRITE_PROT = 256
|
|
106
|
+
UC_HOOK_MEM_FETCH_PROT = 512
|
|
107
|
+
UC_HOOK_MEM_READ = 1024
|
|
108
|
+
UC_HOOK_MEM_WRITE = 2048
|
|
109
|
+
UC_HOOK_MEM_FETCH = 4096
|
|
110
|
+
UC_HOOK_MEM_READ_AFTER = 8192
|
|
111
|
+
UC_HOOK_INSN_INVALID = 16384
|
|
112
|
+
UC_HOOK_EDGE_GENERATED = 32768
|
|
113
|
+
UC_HOOK_TCG_OPCODE = 65536
|
|
114
|
+
UC_HOOK_TLB_FILL = 131072
|
|
115
|
+
UC_HOOK_MEM_UNMAPPED = 112
|
|
116
|
+
UC_HOOK_MEM_PROT = 896
|
|
117
|
+
UC_HOOK_MEM_READ_INVALID = 144
|
|
118
|
+
UC_HOOK_MEM_WRITE_INVALID = 288
|
|
119
|
+
UC_HOOK_MEM_FETCH_INVALID = 576
|
|
120
|
+
UC_HOOK_MEM_INVALID = 1008
|
|
121
|
+
UC_HOOK_MEM_VALID = 7168
|
|
122
|
+
UC_QUERY_MODE = 1
|
|
123
|
+
UC_QUERY_PAGE_SIZE = 2
|
|
124
|
+
UC_QUERY_ARCH = 3
|
|
125
|
+
UC_QUERY_TIMEOUT = 4
|
|
126
|
+
|
|
127
|
+
UC_CTL_IO_NONE = 0
|
|
128
|
+
UC_CTL_IO_WRITE = 1
|
|
129
|
+
UC_CTL_IO_READ = 2
|
|
130
|
+
UC_CTL_IO_READ_WRITE = 3
|
|
131
|
+
|
|
132
|
+
UC_TLB_CPU = 0
|
|
133
|
+
UC_TLB_VIRTUAL = 1
|
|
134
|
+
|
|
135
|
+
UC_CTL_UC_MODE = 0
|
|
136
|
+
UC_CTL_UC_PAGE_SIZE = 1
|
|
137
|
+
UC_CTL_UC_ARCH = 2
|
|
138
|
+
UC_CTL_UC_TIMEOUT = 3
|
|
139
|
+
UC_CTL_UC_USE_EXITS = 4
|
|
140
|
+
UC_CTL_UC_EXITS_CNT = 5
|
|
141
|
+
UC_CTL_UC_EXITS = 6
|
|
142
|
+
UC_CTL_CPU_MODEL = 7
|
|
143
|
+
UC_CTL_TB_REQUEST_CACHE = 8
|
|
144
|
+
UC_CTL_TB_REMOVE_CACHE = 9
|
|
145
|
+
UC_CTL_TB_FLUSH = 10
|
|
146
|
+
UC_CTL_TLB_FLUSH = 11
|
|
147
|
+
UC_CTL_TLB_TYPE = 12
|
|
148
|
+
UC_CTL_TCG_BUFFER_SIZE = 13
|
|
149
|
+
UC_CTL_CONTEXT_MODE = 14
|
|
150
|
+
UC_CTL_CONTEXT_CPU = 1
|
|
151
|
+
UC_CTL_CONTEXT_MEMORY = 2
|
|
152
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: NCPrePatcher
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: arm64-darwin-23
|
|
6
6
|
authors:
|
|
7
7
|
- Will Smith
|
|
@@ -55,6 +55,11 @@ files:
|
|
|
55
55
|
- example/README.md
|
|
56
56
|
- example/disasm.rb
|
|
57
57
|
- exe/ncpp
|
|
58
|
+
- lib/keystone/arm_const.rb
|
|
59
|
+
- lib/keystone/keystone.dylib
|
|
60
|
+
- lib/keystone/keystone.rb
|
|
61
|
+
- lib/keystone/keystone_const.rb
|
|
62
|
+
- lib/keystone/version.rb
|
|
58
63
|
- lib/ncpp.rb
|
|
59
64
|
- lib/ncpp/commands.rb
|
|
60
65
|
- lib/ncpp/interpreter.rb
|
|
@@ -66,6 +71,11 @@ files:
|
|
|
66
71
|
- lib/nitro/nitro.rb
|
|
67
72
|
- lib/unarm/unarm.dylib
|
|
68
73
|
- lib/unarm/unarm.rb
|
|
74
|
+
- lib/unicorn/arm_const.rb
|
|
75
|
+
- lib/unicorn/unicorn.dylib
|
|
76
|
+
- lib/unicorn/unicorn.rb
|
|
77
|
+
- lib/unicorn/unicorn_const.rb
|
|
78
|
+
- lib/unicorn/version.rb
|
|
69
79
|
homepage: https://github.com/pete420griff/NCPrePatcher
|
|
70
80
|
licenses:
|
|
71
81
|
- GPL-3.0-only
|
|
@@ -78,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
78
88
|
requirements:
|
|
79
89
|
- - ">="
|
|
80
90
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '3.
|
|
91
|
+
version: '3.4'
|
|
82
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
93
|
requirements:
|
|
84
94
|
- - ">="
|