fisk 1.0.0
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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +118 -0
- data/Rakefile +29 -0
- data/bin/build-machine.rb +11 -0
- data/bin/machine.rb.erb +100 -0
- data/examples/print-string.rb +26 -0
- data/lib/fisk.rb +240 -0
- data/lib/fisk/helpers.rb +73 -0
- data/lib/fisk/machine.rb +35 -0
- data/lib/fisk/machine/encoding.rb +78 -0
- data/lib/fisk/machine/generated.rb +124746 -0
- data/test/helper.rb +8 -0
- data/test/test_fisk.rb +153 -0
- data/test/test_run_fisk.rb +128 -0
- metadata +60 -0
data/test/helper.rb
ADDED
data/test/test_fisk.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class FiskTest < Fisk::Test
|
4
|
+
attr_reader :fisk
|
5
|
+
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@fisk = Fisk.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_sub
|
12
|
+
fisk.sub fisk.rsp, fisk.imm8(16)
|
13
|
+
i = disasm(fisk.to_binary).first
|
14
|
+
assert_equal "sub", i.mnemonic.to_s
|
15
|
+
assert_equal "rsp, 0x10", i.op_str.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_lol
|
19
|
+
binary = fisk.asm do
|
20
|
+
push rbp
|
21
|
+
mov rsp, rbp
|
22
|
+
int lit(3)
|
23
|
+
pop rbp
|
24
|
+
ret
|
25
|
+
end
|
26
|
+
assert_equal "UH\x89\xEC\xCC]\xC3".b, binary.string
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_add_eax
|
30
|
+
fisk.add fisk.eax, fisk.imm32(0x4351ff23)
|
31
|
+
i = disasm(fisk.to_binary).first
|
32
|
+
assert_equal "add", i.mnemonic.to_s
|
33
|
+
assert_equal "eax, 0x4351ff23", i.op_str.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_add_ecx_esi
|
37
|
+
fisk.add fisk.ecx, fisk.esi
|
38
|
+
i = disasm(fisk.to_binary).first
|
39
|
+
assert_equal "add", i.mnemonic.to_s
|
40
|
+
assert_equal "ecx, esi", i.op_str.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_add_rcx_rsi
|
44
|
+
fisk.add fisk.rcx, fisk.rsi
|
45
|
+
i = disasm(fisk.to_binary).first
|
46
|
+
assert_equal "add", i.mnemonic.to_s
|
47
|
+
assert_equal "rcx, rsi".b, i.op_str.to_s.b
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_add_rax
|
51
|
+
fisk.add fisk.rax, fisk.imm32(0x4351ff23)
|
52
|
+
i = disasm(fisk.to_binary).first
|
53
|
+
assert_equal "add", i.mnemonic.to_s
|
54
|
+
assert_equal "rax, 0x4351ff23", i.op_str.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_add_rax_rcx
|
58
|
+
fisk.add fisk.rax, fisk.rcx
|
59
|
+
i = disasm(fisk.to_binary).first
|
60
|
+
assert_equal "add", i.mnemonic.to_s
|
61
|
+
assert_equal "rax, rcx", i.op_str.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_add_rcx_r9
|
65
|
+
fisk.add fisk.rcx, fisk.r9
|
66
|
+
i = disasm(fisk.to_binary).first
|
67
|
+
assert_equal "add", i.mnemonic.to_s
|
68
|
+
assert_equal "rcx, r9", i.op_str.to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_adc_rcx_r9
|
72
|
+
fisk.adc fisk.rcx, fisk.r9
|
73
|
+
i = disasm(fisk.to_binary).first
|
74
|
+
assert_equal "adc", i.mnemonic.to_s
|
75
|
+
assert_equal "rcx, r9", i.op_str.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_int3
|
79
|
+
fisk.int fisk.lit(3)
|
80
|
+
i = disasm(fisk.to_binary).first
|
81
|
+
assert_equal "int3", i.mnemonic.to_s
|
82
|
+
assert_equal "", i.op_str.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_int5
|
86
|
+
fisk.int fisk.imm8(5)
|
87
|
+
i = disasm(fisk.to_binary).first
|
88
|
+
assert_equal "int", i.mnemonic.to_s
|
89
|
+
assert_equal "5", i.op_str.to_s
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_push_rbp
|
93
|
+
fisk.push fisk.rbp
|
94
|
+
i = disasm(fisk.to_binary).first
|
95
|
+
assert_equal "push", i.mnemonic.to_s
|
96
|
+
assert_equal "rbp", i.op_str.to_s
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_mov_rsp_rbp
|
100
|
+
fisk.mov fisk.rsp, fisk.rbp
|
101
|
+
i = disasm(fisk.to_binary).first
|
102
|
+
assert_equal "mov", i.mnemonic.to_s
|
103
|
+
assert_equal "rsp, rbp", i.op_str.to_s
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_popq
|
107
|
+
fisk.pop fisk.rbp
|
108
|
+
i = disasm(fisk.to_binary).first
|
109
|
+
assert_equal "pop", i.mnemonic.to_s
|
110
|
+
assert_equal "rbp", i.op_str.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_ret
|
114
|
+
fisk.ret
|
115
|
+
i = disasm(fisk.to_binary).first
|
116
|
+
assert_equal "ret", i.mnemonic.to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_jmp
|
120
|
+
fisk.jmp fisk.rel32(0)
|
121
|
+
binary = fisk.to_binary
|
122
|
+
i = disasm(binary).first
|
123
|
+
assert_equal "jmp", i.mnemonic.to_s
|
124
|
+
assert_equal binary.bytesize.to_s, i.op_str.to_s
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_jmp_rel8
|
128
|
+
fisk.jmp fisk.rel8(-2)
|
129
|
+
binary = fisk.to_binary
|
130
|
+
assert_equal "\xEB\xFE".b, binary
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_jbe_rel8
|
134
|
+
fisk.jbe fisk.rel8(2)
|
135
|
+
binary = fisk.to_binary
|
136
|
+
i = disasm(binary).first
|
137
|
+
assert_equal "jbe", i.mnemonic.to_s
|
138
|
+
assert_equal "4", i.op_str.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_jbe_rel32
|
142
|
+
fisk.jbe fisk.rel32(2)
|
143
|
+
binary = fisk.to_binary
|
144
|
+
i = disasm(binary).first
|
145
|
+
assert_equal "jbe", i.mnemonic.to_s
|
146
|
+
assert_equal "8", i.op_str.to_s
|
147
|
+
end
|
148
|
+
|
149
|
+
def disasm binary
|
150
|
+
cs = Crabstone::Disassembler.new(Crabstone::ARCH_X86, Crabstone::MODE_64)
|
151
|
+
cs.disasm binary, 0
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "fisk/helpers"
|
3
|
+
|
4
|
+
class RunFiskTest < Fisk::Test
|
5
|
+
def disasm binary
|
6
|
+
cs = Crabstone::Disassembler.new(Crabstone::ARCH_X86, Crabstone::MODE_64)
|
7
|
+
cs.disasm(binary, 0x0000).each {|i|
|
8
|
+
printf("0x%x:\t%s\t\t%s\n",i.address, i.mnemonic, i.op_str)
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_sum
|
13
|
+
fisk = Fisk.new
|
14
|
+
jitbuf = Fisk::Helpers.jitbuffer 4096
|
15
|
+
|
16
|
+
fisk.asm jitbuf do
|
17
|
+
push rbp
|
18
|
+
mov rbp, rsp
|
19
|
+
mov rdx, imm32(1)
|
20
|
+
xor rax, rax
|
21
|
+
make_label :loop
|
22
|
+
add rax, rdx
|
23
|
+
inc rdx
|
24
|
+
cmp rdx, imm32(10)
|
25
|
+
jbe label(:loop)
|
26
|
+
pop rbp
|
27
|
+
ret
|
28
|
+
end
|
29
|
+
|
30
|
+
func = jitbuf.to_function [], Fiddle::TYPE_INT
|
31
|
+
assert_equal 11.times.inject(:+), func.call
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_jmp
|
35
|
+
fisk = Fisk.new
|
36
|
+
jitbuf = Fisk::Helpers.jitbuffer 4096
|
37
|
+
|
38
|
+
fisk.asm jitbuf do
|
39
|
+
push rbp
|
40
|
+
mov rbp, rsp
|
41
|
+
jmp label(:foo)
|
42
|
+
make_label(:bar)
|
43
|
+
mov rax, imm32(100)
|
44
|
+
pop rbp
|
45
|
+
ret
|
46
|
+
make_label(:foo)
|
47
|
+
jmp label(:bar)
|
48
|
+
mov rax, imm32(42)
|
49
|
+
pop rbp
|
50
|
+
ret
|
51
|
+
end
|
52
|
+
|
53
|
+
func = jitbuf.to_function [], Fiddle::TYPE_INT
|
54
|
+
assert_equal 100, func.call
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_run_fisk
|
58
|
+
fisk = Fisk.new
|
59
|
+
mem = Fisk::Helpers.mmap_jit 4096
|
60
|
+
|
61
|
+
binary = fisk.asm do
|
62
|
+
push rbp
|
63
|
+
mov rbp, rsp
|
64
|
+
mov rax, imm32(100)
|
65
|
+
pop rbp
|
66
|
+
ret
|
67
|
+
end
|
68
|
+
|
69
|
+
Fisk::Helpers.memcpy mem, binary.string, binary.string.bytesize
|
70
|
+
func = Fiddle::Function.new mem.to_i, [], Fiddle::TYPE_INT
|
71
|
+
assert_equal 100, func.call
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_jit_memory_has_size
|
75
|
+
mem = Fisk::Helpers.mmap_jit 100
|
76
|
+
assert_equal 100, mem.size
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_get_address
|
80
|
+
fisk = Fisk.new
|
81
|
+
jitbuf = Fisk::Helpers.jitbuffer 4096
|
82
|
+
|
83
|
+
fisk.asm jitbuf do
|
84
|
+
push rbp
|
85
|
+
mov rbp, rsp
|
86
|
+
mov rax, rdi
|
87
|
+
pop rbp
|
88
|
+
ret
|
89
|
+
end
|
90
|
+
|
91
|
+
func = jitbuf.to_function [Fiddle::TYPE_VOIDP], Fiddle::TYPE_LONG
|
92
|
+
x = Object.new
|
93
|
+
wrapped = Fiddle.dlwrap x
|
94
|
+
assert_equal wrapped.to_i, func.call(wrapped)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_fisk_jit
|
98
|
+
fisk = Fisk.new
|
99
|
+
jitbuf = Fisk::Helpers.jitbuffer 4096
|
100
|
+
|
101
|
+
fisk.asm jitbuf do
|
102
|
+
push rbp
|
103
|
+
mov rbp, rsp
|
104
|
+
mov rax, imm32(100)
|
105
|
+
pop rbp
|
106
|
+
ret
|
107
|
+
end
|
108
|
+
|
109
|
+
func = jitbuf.to_function [], Fiddle::TYPE_INT
|
110
|
+
assert_equal 100, func.call
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_fisk_get_param
|
114
|
+
fisk = Fisk.new
|
115
|
+
jitbuf = Fisk::Helpers.jitbuffer 4096
|
116
|
+
|
117
|
+
fisk.asm jitbuf do
|
118
|
+
push rbp
|
119
|
+
mov rbp, rsp
|
120
|
+
mov rax, imm32(100)
|
121
|
+
pop rbp
|
122
|
+
ret
|
123
|
+
end
|
124
|
+
|
125
|
+
func = jitbuf.to_function [], Fiddle::TYPE_INT
|
126
|
+
assert_equal 100, func.call
|
127
|
+
end
|
128
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fisk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Patterson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-06-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Tired of writing Ruby in Ruby? Now you can write assembly in Ruby!
|
14
|
+
email: tenderlove@ruby-lang.org
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Gemfile
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- Rakefile
|
23
|
+
- bin/build-machine.rb
|
24
|
+
- bin/machine.rb.erb
|
25
|
+
- examples/print-string.rb
|
26
|
+
- lib/fisk.rb
|
27
|
+
- lib/fisk/helpers.rb
|
28
|
+
- lib/fisk/machine.rb
|
29
|
+
- lib/fisk/machine/encoding.rb
|
30
|
+
- lib/fisk/machine/generated.rb
|
31
|
+
- test/helper.rb
|
32
|
+
- test/test_fisk.rb
|
33
|
+
- test/test_run_fisk.rb
|
34
|
+
homepage: https://github.com/tenderlove/fisk
|
35
|
+
licenses:
|
36
|
+
- Apache-2.0
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubygems_version: 3.3.0.dev
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: Write assembly in Ruby!
|
57
|
+
test_files:
|
58
|
+
- test/helper.rb
|
59
|
+
- test/test_fisk.rb
|
60
|
+
- test/test_run_fisk.rb
|