asmrepl 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d89ea7a3b6af16e72444221e66fa9c2af2ceaebaae8c4e48d7a30d4b419283f5
4
- data.tar.gz: 7b9e86750882fe36a9fdf5ee311e7cdb483c19faf3ffa8a46bdb85808a93e455
3
+ metadata.gz: 7045e3fe0facfdc15e21bb3dfebcaf5232eb68c144ac07e6bf61588979ca3c7f
4
+ data.tar.gz: 158f3aea1088ae25397dccfc6bf593449df3482f031c025c6dbf33ce372f6a53
5
5
  SHA512:
6
- metadata.gz: c583255650ca956401117259c068faa6cae8f8df435b88d447186a883a8c32b45a6e6e8d16aae0fc082f4b6b979156ee88aeea6c27bf4296f73fe0c15b7b85f0
7
- data.tar.gz: 349bcb373b93a9dec96421be445005dba162325acea07eb3e20850fd7078550d67576059ea81c33be9d99fe9f6147e8e3bde1d2945989372671e1d5418b3b141
6
+ metadata.gz: d039b567f9cb938f56f86c1ea02a9c16a3c266748fb16d37b5c710c66618010dba32b13755d778c9dded6a56bb521fb61198281297543aad9f3f6c39028510b4
7
+ data.tar.gz: 7f37562a9568489d61d9eb3144310d3c372fd5fe7ab07b3b0786c268bc8a2b20077a52736723d0f684930924614083cc4df2a817e6f91f8f6b7afae438aeb0fc
data/README.md CHANGED
@@ -4,27 +4,34 @@ This is a REPL for assembly language.
4
4
 
5
5
  ## Usage
6
6
 
7
- I haven't made a gem yet, so use it like this:
7
+ Install the gem:
8
8
 
9
9
  ```
10
- $ bundle install
11
- $ sudo ruby -I lib:test bin/asmrepl
10
+ $ gem install asmrepl
12
11
  ```
13
12
 
13
+ Then start the repl like this:
14
+
15
+ ```
16
+ $ asmrepl
17
+ ```
18
+
19
+ If you're on macOS, you'll need to start the repl with `sudo`.
20
+
14
21
  When the REPL starts, it will display all register values and flags:
15
22
 
16
23
  ```
17
24
  ================== CPU STATE ===================
18
- rax 000000000000000000 r8 0x0000600001782be0
19
- rbx 000000000000000000 r9 0x00007fbf9b0068c0
20
- rcx 0x0000000109dae951 r10 000000000000000000
21
- rdx 0x000000000000000c r11 0x000000010999c000
22
- rdi 0x00007ff7b6b2bbf0 r12 000000000000000000
23
- rsi 0x00000001096315fd r13 0x00007ff7b6b2bdc0
24
- rbp 0x00007ff7b6b2bc40 r14 000000000000000000
25
- rsp 0x00007ff7b6b2bc38 r15 000000000000000000
26
-
27
- rip 0x000000010999c001
25
+ rax 000000000000000000 r8 0x00007f89d0f04640
26
+ rbx 000000000000000000 r9 0x0000000000000004
27
+ rcx 0x00007f89d0f04a50 r10 000000000000000000
28
+ rdx 0x..fc611d3f0aa2900d4 r11 0x00000001033a4000
29
+ rdi 0x00007ff7bd126148 r12 000000000000000000
30
+ rsi 000000000000000000 r13 0x00007ff7bd125dc0
31
+ rbp 0x00007ff7bd125c40 r14 000000000000000000
32
+ rsp 0x00007ff7bd125c38 r15 000000000000000000
33
+
34
+ rip 0x00000001033a4001
28
35
  rflags 0x0000000000000246
29
36
  cs 0x000000000000002b
30
37
  fs 000000000000000000
@@ -32,46 +39,58 @@ gs 000000000000000000
32
39
 
33
40
  FLAGS: ["PF", "ZF", "IF"]
34
41
 
35
- >>
42
+ (rip 0x00000001033a4001)>
36
43
  ```
37
44
 
38
45
  Then you can issue commands and inspect register values. Let's write to the
39
46
  `rax` register and inspect its value:
40
47
 
41
48
  ```
42
- >> mov rax, 5
43
- >> rax
49
+ (rip 0x00000001033a4001)> mov rax, 5
50
+ =============== REGISTER CHANGES ===============
51
+ rax 000000000000000000 => 0x0000000000000005
52
+
53
+ (rip 0x00000001033a4009)> rax
44
54
  0x0000000000000005
45
- >>
55
+ (rip 0x00000001033a4009)>
46
56
  ```
47
57
 
48
58
  Now let's write to the `rbx` register and add the two values:
49
59
 
50
60
  ```
51
- >> mov rbx, 3
52
- >> add rax, rbx
53
- >> rax
61
+ (rip 0x00000001033a4009)> mov rbx, 3
62
+ =============== REGISTER CHANGES ===============
63
+ rbx 000000000000000000 => 0x0000000000000003
64
+
65
+ (rip 0x00000001033a4011)> add rax, rbx
66
+ =============== REGISTER CHANGES ===============
67
+ rax 0x0000000000000005 => 0x0000000000000008
68
+ rflags 0x0000000000000246 => 0x0000000000000202
69
+
70
+ FLAGS: ["IF"]
71
+
72
+ (rip 0x00000001033a4015)> rax
54
73
  0x0000000000000008
55
- >> rbx
74
+ (rip 0x00000001033a4015)> rbx
56
75
  0x0000000000000003
57
- >>
76
+ (rip 0x00000001033a4015)>
58
77
  ```
59
78
 
60
79
  Finally, lets check all values in the CPU:
61
80
 
62
81
  ```
63
- >> cpu
82
+ (rip 0x00000001033a4015)> cpu
64
83
  ================== CPU STATE ===================
65
- rax 0x0000000000000008 r8 0x0000600001d848a0
66
- rbx 0x0000000000000003 r9 0x00007fced316f850
67
- rcx 0x00000001017da951 r10 000000000000000000
68
- rdx 0x000000000000000c r11 0x00000001013cc000
69
- rdi 0x00007ff7bf0fdbf0 r12 000000000000000000
70
- rsi 0x000000010105f5fd r13 0x00007ff7bf0fddc0
71
- rbp 0x00007ff7bf0fdc40 r14 000000000000000000
72
- rsp 0x00007ff7bf0fdc38 r15 000000000000000000
73
-
74
- rip 0x00000001013cc029
84
+ rax 0x0000000000000008 r8 0x00007f89d0f04640
85
+ rbx 0x0000000000000003 r9 0x0000000000000004
86
+ rcx 0x00007f89d0f04a50 r10 000000000000000000
87
+ rdx 0x..fc611d3f0aa2900d4 r11 0x00000001033a4000
88
+ rdi 0x00007ff7bd126148 r12 000000000000000000
89
+ rsi 000000000000000000 r13 0x00007ff7bd125dc0
90
+ rbp 0x00007ff7bd125c40 r14 000000000000000000
91
+ rsp 0x00007ff7bd125c38 r15 000000000000000000
92
+
93
+ rip 0x00000001033a4015
75
94
  rflags 0x0000000000000202
76
95
  cs 0x000000000000002b
77
96
  fs 000000000000000000
@@ -79,5 +98,5 @@ gs 000000000000000000
79
98
 
80
99
  FLAGS: ["IF"]
81
100
 
82
- >>
101
+ (rip 0x00000001033a4015)>
83
102
  ```
data/asmrepl.gemspec CHANGED
@@ -20,5 +20,5 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency 'minitest', '~> 5.14'
21
21
  s.add_development_dependency 'crabstone', '~> 4.0'
22
22
  s.add_development_dependency 'rake', '~> 13.0'
23
- s.add_dependency 'fisk', '~> 2'
23
+ s.add_dependency 'fisk', '~> 2.3.1'
24
24
  end
data/lib/asmrepl/repl.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "fiddle"
2
2
  require "fisk/helpers"
3
- require "crabstone"
4
3
  require "reline"
5
4
 
6
5
  if RUBY_PLATFORM =~ /darwin/
@@ -9,17 +8,6 @@ else
9
8
  require "asmrepl/linux"
10
9
  end
11
10
 
12
- class Crabstone::Binding::Instruction
13
- class << self
14
- alias :old_release :release
15
- end
16
-
17
- # Squelch error in crabstone
18
- def self.release obj
19
- nil
20
- end
21
- end
22
-
23
11
  module ASMREPL
24
12
  class REPL
25
13
  include Fiddle
@@ -39,13 +27,40 @@ module ASMREPL
39
27
  end
40
28
 
41
29
  def display_state state
42
- puts " CPU STATE ".center(48, "=")
30
+ puts bold(" CPU STATE ".center(48, "="))
43
31
  puts state
44
32
  puts
45
33
  puts "FLAGS: #{state.flags.inspect}"
46
34
  puts
47
35
  end
48
36
 
37
+ def display_state_change last_state, state
38
+ puts bold(" REGISTER CHANGES ".center(48, "="))
39
+ show_flags = false
40
+
41
+ state.fields.each do |field|
42
+ next if field == "rip"
43
+
44
+ if last_state[field] != state[field]
45
+ print "#{field.ljust(6)} "
46
+ print sprintf("%#018x", last_state[field])
47
+ print " => "
48
+ puts bold(sprintf("%#018x", state[field]))
49
+ end
50
+ end
51
+
52
+ if last_state.flags != state.flags
53
+ puts
54
+ puts "FLAGS: #{state.flags.inspect}"
55
+ end
56
+
57
+ puts
58
+ end
59
+
60
+ def bold string
61
+ "\e[1m#{string}\e[0m"
62
+ end
63
+
49
64
  def start
50
65
  pid = fork {
51
66
  CFuncs.traceme
@@ -54,49 +69,73 @@ module ASMREPL
54
69
 
55
70
  tracer = CFuncs::Tracer.new pid
56
71
  should_cpu = true
72
+ last_state = nil
73
+
57
74
  while tracer.wait
58
75
  state = tracer.state
59
76
 
60
77
  # Show CPU state once on boot
61
- if should_cpu
78
+ if last_state.nil?
62
79
  display_state state
63
- should_cpu = false
80
+ last_state = state
81
+ else
82
+ display_state_change last_state, state
83
+ last_state = state
64
84
  end
65
85
 
66
86
  # Move the JIT buffer to the current instruction pointer
67
87
  pos = (state.rip - @buffer.memory.to_i)
68
88
  @buffer.seek pos
69
89
  use_history = true
70
- loop do
71
- cmd = nil
72
- text = Reline.readmultiline(">> ", use_history) do |multiline_input|
73
- if multiline_input =~ /\A\s*(\w+)\s*\Z/
74
- register = $1
75
- cmd = [:read, register]
76
- else
77
- cmd = :run
90
+ begin
91
+ loop do
92
+ cmd = nil
93
+ prompt = sprintf("(rip %#018x)> ", state.rip)
94
+ text = Reline.readmultiline(prompt, use_history) do |multiline_input|
95
+ if multiline_input =~ /\A\s*(\w+)\s*\Z/
96
+ register = $1
97
+ cmd = [:read, register]
98
+ else
99
+ cmd = :run
100
+ end
101
+ true
78
102
  end
79
- true
80
- end
81
103
 
82
- case cmd
83
- in :run
84
- break if text.chomp.empty?
85
- binary = @assembler.assemble @parser.parse text.chomp
86
- binary.bytes.each { |byte| @buffer.putc byte }
87
- break
88
- in [:read, "cpu"]
89
- display_state state
90
- in [:read, reg]
91
- val = state[reg]
92
- if val
93
- puts sprintf("%#018x", state[reg])
104
+ case cmd
105
+ in :run
106
+ break if text.chomp.empty?
107
+ begin
108
+ parser_result = @parser.parse text.chomp
109
+ rescue
110
+ puts "Invalid intruction"
111
+ next
112
+ end
113
+
114
+ begin
115
+ binary = @assembler.assemble parser_result
116
+ binary.bytes.each { |byte| @buffer.putc byte }
117
+ rescue Fisk::Errors::InvalidInstructionError => e
118
+ # Print an error message when the instruction is invalid
119
+ puts e.message
120
+ next
121
+ end
122
+ break
123
+ in [:read, "cpu"]
124
+ display_state state
125
+ in [:read, reg]
126
+ val = state[reg]
127
+ if val
128
+ puts sprintf("%#018x", state[reg])
129
+ else
130
+ puts "Unknown command: "
131
+ puts " " + text
132
+ end
94
133
  else
95
- puts "Unknown command: "
96
- puts " " + text
97
134
  end
98
- else
99
135
  end
136
+ rescue Interrupt
137
+ puts ""
138
+ exit 0
100
139
  end
101
140
  tracer.continue
102
141
  end
@@ -1,3 +1,3 @@
1
1
  module ASMREPL
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
data/lib/asmrepl.rb CHANGED
@@ -1,3 +1,11 @@
1
+ require "fiddle"
2
+
3
+ module Fiddle
4
+ unless Fiddle.const_defined?(:SIZEOF_INT64_T)
5
+ SIZEOF_INT64_T = Fiddle::SIZEOF_UINTPTR_T
6
+ end
7
+ end
8
+
1
9
  require "asmrepl/parser"
2
10
  require "asmrepl/assembler"
3
11
  require "asmrepl/repl"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asmrepl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-24 00:00:00.000000000 Z
11
+ date: 2021-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '2'
61
+ version: 2.3.1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2'
68
+ version: 2.3.1
69
69
  description: Tired of writing assembly and them assembling it? Now you can write assembly
70
70
  and evaluate it!
71
71
  email: tenderlove@ruby-lang.org