asmrepl 1.0.3 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fea751dab8edd03b3cecfb3ea60417c34a9464f19c6e2bc2c2b67b4dcc209cd
4
- data.tar.gz: db10a7a8e9a385bcafa3d517dc851774f52a657184334c493627e7cd09d7f870
3
+ metadata.gz: 7045e3fe0facfdc15e21bb3dfebcaf5232eb68c144ac07e6bf61588979ca3c7f
4
+ data.tar.gz: 158f3aea1088ae25397dccfc6bf593449df3482f031c025c6dbf33ce372f6a53
5
5
  SHA512:
6
- metadata.gz: cf9202d1ec0d1700f404f6b8e3c353b56b1985b9a36b4e7520857ac228815439d424c63936b840b56c4a0d073a5814ac699e4afa146ffa73e360b39ec526f05f
7
- data.tar.gz: 7c999f1a3b51ea5156e4224296b2df27ca509ae5a4becec8f9d2c57ef1a6af4338993137efe98e98f75ffed1fff791a25c530e5bdd75d36b18f025a8e8aa4a50
6
+ metadata.gz: d039b567f9cb938f56f86c1ea02a9c16a3c266748fb16d37b5c710c66618010dba32b13755d778c9dded6a56bb521fb61198281297543aad9f3f6c39028510b4
7
+ data.tar.gz: 7f37562a9568489d61d9eb3144310d3c372fd5fe7ab07b3b0786c268bc8a2b20077a52736723d0f684930924614083cc4df2a817e6f91f8f6b7afae438aeb0fc
data/README.md CHANGED
@@ -2,11 +2,6 @@
2
2
 
3
3
  This is a REPL for assembly language.
4
4
 
5
- ## Linux requirements
6
- ```
7
- $ sudo apt-get install libcapstone-dev
8
- ```
9
-
10
5
  ## Usage
11
6
 
12
7
  Install the gem:
@@ -27,16 +22,16 @@ When the REPL starts, it will display all register values and flags:
27
22
 
28
23
  ```
29
24
  ================== CPU STATE ===================
30
- rax 000000000000000000 r8 0x0000600001782be0
31
- rbx 000000000000000000 r9 0x00007fbf9b0068c0
32
- rcx 0x0000000109dae951 r10 000000000000000000
33
- rdx 0x000000000000000c r11 0x000000010999c000
34
- rdi 0x00007ff7b6b2bbf0 r12 000000000000000000
35
- rsi 0x00000001096315fd r13 0x00007ff7b6b2bdc0
36
- rbp 0x00007ff7b6b2bc40 r14 000000000000000000
37
- rsp 0x00007ff7b6b2bc38 r15 000000000000000000
38
-
39
- 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
40
35
  rflags 0x0000000000000246
41
36
  cs 0x000000000000002b
42
37
  fs 000000000000000000
@@ -44,46 +39,58 @@ gs 000000000000000000
44
39
 
45
40
  FLAGS: ["PF", "ZF", "IF"]
46
41
 
47
- >>
42
+ (rip 0x00000001033a4001)>
48
43
  ```
49
44
 
50
45
  Then you can issue commands and inspect register values. Let's write to the
51
46
  `rax` register and inspect its value:
52
47
 
53
48
  ```
54
- >> mov rax, 5
55
- >> rax
49
+ (rip 0x00000001033a4001)> mov rax, 5
50
+ =============== REGISTER CHANGES ===============
51
+ rax 000000000000000000 => 0x0000000000000005
52
+
53
+ (rip 0x00000001033a4009)> rax
56
54
  0x0000000000000005
57
- >>
55
+ (rip 0x00000001033a4009)>
58
56
  ```
59
57
 
60
58
  Now let's write to the `rbx` register and add the two values:
61
59
 
62
60
  ```
63
- >> mov rbx, 3
64
- >> add rax, rbx
65
- >> 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
66
73
  0x0000000000000008
67
- >> rbx
74
+ (rip 0x00000001033a4015)> rbx
68
75
  0x0000000000000003
69
- >>
76
+ (rip 0x00000001033a4015)>
70
77
  ```
71
78
 
72
79
  Finally, lets check all values in the CPU:
73
80
 
74
81
  ```
75
- >> cpu
82
+ (rip 0x00000001033a4015)> cpu
76
83
  ================== CPU STATE ===================
77
- rax 0x0000000000000008 r8 0x0000600001d848a0
78
- rbx 0x0000000000000003 r9 0x00007fced316f850
79
- rcx 0x00000001017da951 r10 000000000000000000
80
- rdx 0x000000000000000c r11 0x00000001013cc000
81
- rdi 0x00007ff7bf0fdbf0 r12 000000000000000000
82
- rsi 0x000000010105f5fd r13 0x00007ff7bf0fddc0
83
- rbp 0x00007ff7bf0fdc40 r14 000000000000000000
84
- rsp 0x00007ff7bf0fdc38 r15 000000000000000000
85
-
86
- 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
87
94
  rflags 0x0000000000000202
88
95
  cs 0x000000000000002b
89
96
  fs 000000000000000000
@@ -91,5 +98,5 @@ gs 000000000000000000
91
98
 
92
99
  FLAGS: ["IF"]
93
100
 
94
- >>
101
+ (rip 0x00000001033a4015)>
95
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
@@ -27,13 +27,40 @@ module ASMREPL
27
27
  end
28
28
 
29
29
  def display_state state
30
- puts " CPU STATE ".center(48, "=")
30
+ puts bold(" CPU STATE ".center(48, "="))
31
31
  puts state
32
32
  puts
33
33
  puts "FLAGS: #{state.flags.inspect}"
34
34
  puts
35
35
  end
36
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
+
37
64
  def start
38
65
  pid = fork {
39
66
  CFuncs.traceme
@@ -42,13 +69,18 @@ module ASMREPL
42
69
 
43
70
  tracer = CFuncs::Tracer.new pid
44
71
  should_cpu = true
72
+ last_state = nil
73
+
45
74
  while tracer.wait
46
75
  state = tracer.state
47
76
 
48
77
  # Show CPU state once on boot
49
- if should_cpu
78
+ if last_state.nil?
50
79
  display_state state
51
- should_cpu = false
80
+ last_state = state
81
+ else
82
+ display_state_change last_state, state
83
+ last_state = state
52
84
  end
53
85
 
54
86
  # Move the JIT buffer to the current instruction pointer
@@ -58,7 +90,8 @@ module ASMREPL
58
90
  begin
59
91
  loop do
60
92
  cmd = nil
61
- text = Reline.readmultiline(">> ", use_history) do |multiline_input|
93
+ prompt = sprintf("(rip %#018x)> ", state.rip)
94
+ text = Reline.readmultiline(prompt, use_history) do |multiline_input|
62
95
  if multiline_input =~ /\A\s*(\w+)\s*\Z/
63
96
  register = $1
64
97
  cmd = [:read, register]
@@ -71,8 +104,21 @@ module ASMREPL
71
104
  case cmd
72
105
  in :run
73
106
  break if text.chomp.empty?
74
- binary = @assembler.assemble @parser.parse text.chomp
75
- binary.bytes.each { |byte| @buffer.putc byte }
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
76
122
  break
77
123
  in [:read, "cpu"]
78
124
  display_state state
@@ -88,6 +134,7 @@ module ASMREPL
88
134
  end
89
135
  end
90
136
  rescue Interrupt
137
+ puts ""
91
138
  exit 0
92
139
  end
93
140
  tracer.continue
@@ -1,3 +1,3 @@
1
1
  module ASMREPL
2
- VERSION = '1.0.3'
2
+ VERSION = '1.1.0'
3
3
  end
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.3
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-12-01 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