arasm 0.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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/arasm +196 -0
  3. data/bin/darasm +138 -0
  4. metadata +47 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b17106382b375fa9e517b975c6c6b4f6a33185e6
4
+ data.tar.gz: bd55cacceab89c1fc0384e79e42e6bf645416e53
5
+ SHA512:
6
+ metadata.gz: 42b64aada2bc744dcba5323c916a29040cddba40a3247422a2de06772c95f3811e7a976a565a180352cc90a0bedaefa99684af3ba7e4188b09cc9251c2cf3916
7
+ data.tar.gz: 402113251c61e5cdadc5693b6b553382b60f7e9d0a4a0b1565d30dde2aced1ed0c8c986eb6e84a7ca7bcfd76890bbe9dbf07ebaac559c969b2f227a11c2243c7
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $cmdlist = []
4
+ $blocks = {}
5
+ $out = ""
6
+ $help = "USAGE: arasm <-f file> [ -o outfile ]"
7
+ $options = {}
8
+
9
+ ARGV.each_with_index do |i,ind|
10
+ case i
11
+ when "-f"
12
+ $options["file"] = ARGV[ind+1]
13
+ when "-o"
14
+ $options["outfile"] = ARGV[ind+1]
15
+ end
16
+ end
17
+
18
+ unless $options["file"]
19
+ abort $help
20
+ end
21
+
22
+ content = File.read($options["file"]).split("\n") rescue abort($help)
23
+ content.map!{|i|i.match(/;/) ? i.strip.split(";")[0].strip : i}
24
+ #content.select!{|i|!i.empty?}
25
+
26
+ def abort_with_style(l,i,e)
27
+ i.to_s.match(/^[0-9]+$/)&&i+=1
28
+ abort("[#{i}]FATAL @ `#{l}`: #{e}")
29
+ end
30
+
31
+ valid_commands = %w( mv[dwb] [dw]lt [dw]gt [dw]eq [dw]ne [lsa]of rop [as]st si[dwb] ls[dwb] fmv fcp ).map{|i|eval("/^"+i+"/i")}
32
+
33
+ def assert_args(com,ln,*types)
34
+ com.is_a?(Array)||com=com.split
35
+ com.length-1==types.length||abort_with_style(com.join(" "),ln,"WRONG NUMBER OF ARGUMENTS, EXPECTED #{types.length}, GOT #{com.length-1}.")
36
+ type_rxps = {
37
+ /\.[^\s;]+/ => :block,
38
+ /\$[A-Z0-9]+/i => :num,
39
+ /[0-9]+/i => :num,
40
+ /.*/ => :some_weird_alphanumeric_foo
41
+ }
42
+ types.each{|i|type_rxps.values.include?(i)||raise("Unknown literal type #{i.inspect}")}
43
+ com[1..-1].each_with_index do |i,ind|
44
+ identifier = type_rxps[type_rxps.keys.select{|k|i.match(k)}[0]]
45
+ identifier==types[ind]||abort_with_style(com.join(" "),ln,"ARGUMENT #{ind+1} HAS WRONG TYPE, EXPECTED #{types[ind]}, GOT #{identifier} INSTEAD.")
46
+ end
47
+ end
48
+
49
+ def parse_command(c,ln)
50
+ barr_t = ""
51
+ command = c.split
52
+
53
+ case command[0]
54
+
55
+ when /^mv[dwb]$/
56
+ assert_args(c,ln,:num,:num)
57
+ barr_t << %w(d w b).index(command[0][2]).to_s
58
+ addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
59
+ val= (command[2][0]==?$ ? sprintf("%08x",command[2][1..-1].to_i(16)) : sprintf("%08x",command[2].to_i))
60
+ #puts "MV with addr=#{addr.inspect} val=#{val.inspect}"
61
+ barr_t << addr << val
62
+
63
+ when /^[dw]lt$/
64
+ assert_args(c,ln,:num,:num,:block)
65
+ barr_t << ( 3 + 4*%w(d w).index(command[0][0]) ).to_s(16)
66
+ addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
67
+ val = (command[2][0]==?$ ? sprintf("%08x",command[2][1..-1].to_i(16)) : sprintf("%08x",command[2].to_i))
68
+ block = command[3][1..-1]
69
+ $blocks[block] = "if"
70
+ barr_t << addr << val
71
+
72
+ when /^[dw]gt$/
73
+ assert_args(c,ln,:num,:num,:block)
74
+ barr_t << ( 4 + 4*%w(d w).index(command[0][0]) ).to_s(16)
75
+ addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
76
+ val = (command[2][0]==?$ ? sprintf("%08x",command[2][1..-1].to_i(16)) : sprintf("%08x",command[2].to_i))
77
+ block = command[3][1..-1]
78
+ $blocks[block] = "if"
79
+ barr_t << addr << val
80
+
81
+ when /^[dw]eq$/
82
+ assert_args(c,ln,:num,:num,:block)
83
+ barr_t << ( 5 + 4*%w(d w).index(command[0][0]) ).to_s(16)
84
+ addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
85
+ val = (command[2][0]==?$ ? sprintf("%08x",command[2][1..-1].to_i(16)) : sprintf("%08x",command[2].to_i))
86
+ block = command[3][1..-1]
87
+ $blocks[block] = "if"
88
+ barr_t << addr << val
89
+
90
+ when /^[dw]ne$/
91
+ assert_args(c,ln,:num,:num,:block)
92
+ barr_t << ( 6 + 4*%w(d w).index(command[0][0]) ).to_s(16)
93
+ x_addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
94
+ val = (command[2][0]==?$ ? sprintf("%08x",command[2][1..-1].to_i(16)) : sprintf("%08x",command[2].to_i))
95
+ block = command[3][1..-1]
96
+ $blocks[block] = "if"
97
+ #p {x_addr: x, val: val,}
98
+ barr_t << addr << val
99
+
100
+ when "lof"
101
+ assert_args(c,ln,:num)
102
+ addr = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
103
+ barr_t << "b" << addr << "00000000"
104
+
105
+ when "rop"
106
+ assert_args(c,ln,:num,:block)
107
+ $rop&&abort_with_style(c,ln,"NESTING ROP BLOCKS IS PROHIBITED.")
108
+ $rop = ln
109
+ t = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
110
+ block = command[2][1..-1]
111
+ $blocks[block] = "rop"
112
+ barr_t << "c0000000" << t
113
+
114
+ when /^~/
115
+ bname = command[0][1..-1]
116
+ bname==?#||$blocks[bname]||abort_with_style(c,ln,"TRYING TO CLOSE BLOCK `#{bname}` WHICH WASN'T OPENED BEFORE.")
117
+ if bname == ?#
118
+ barr_t << "d2" << ("0"*14)
119
+ elsif $blocks[bname] == "if"
120
+ barr_t << "d0" << ("0"*14)
121
+ else
122
+ barr_t << "d1" << ("0"*14)
123
+ $rop = nil
124
+ end
125
+ $blocks.delete(bname)
126
+
127
+ when "sof"
128
+ assert_args(c,ln,:num)
129
+ val = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
130
+ barr_t << "d3000000" << val
131
+
132
+ when "ast"
133
+ assert_args(c,ln,:num)
134
+ val = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
135
+ barr_t << "d4000000" << val
136
+
137
+ when "sst"
138
+ assert_args(c,ln,:num)
139
+ val = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
140
+ barr_t << "d5000000" << val
141
+
142
+ when /si[dwb]/
143
+ assert_args(c,ln,:num)
144
+ barr_t << "d" << (6+%w(d w b).index).to_s(16) << ("0"*6)
145
+ addr = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
146
+ barr_t << val
147
+
148
+ when /ls[dwb]/
149
+ assert_args(c,ln,:num)
150
+ barr_t << "d" << (9+%w(d w b).index).to_s(16) << ("0"*6)
151
+ addr = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
152
+ barr_t << val
153
+
154
+ when "aof"
155
+ assert_args(c,ln,:num)
156
+ barr_t << "dc" << ("0"*6)
157
+ val = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
158
+ barr_t << val
159
+
160
+ when "fmv"
161
+ abort_with_style(c,ln,"FMV IS NOT IMPLEMENTED YET.")
162
+ assert_args(c,ln,:num,:num,:num)
163
+ barr_t << "e"
164
+ addr_s = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
165
+ vals = (command[2][0]==?$ ? sprintf("%016x",command[2][1..-1].to_i(16)) : sprintf("%016x",command[2].to_i))
166
+ num_b = (command[3][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
167
+ barr_t << addr_s << num_b << vals
168
+
169
+ when "fcp"
170
+ assert_args(c,ln,:num,:num)
171
+ addr_s = (command[1][0]==?$ ? sprintf("%07x",command[1][1..-1].to_i(16)) : sprintf("%07x",command[1].to_i))
172
+ length = (command[1][0]==?$ ? sprintf("%08x",command[1][1..-1].to_i(16)) : sprintf("%08x",command[1].to_i))
173
+ barr_t << addr_s << length
174
+
175
+ end
176
+
177
+ return barr_t
178
+
179
+ end
180
+
181
+ content.each_with_index do |i,ind|
182
+ $out << parse_command(i,ind)
183
+ end
184
+
185
+ unless $blocks.empty?
186
+ abort("FATAL @ EOF: THE FOLLOWING BLOCKS WEREN'T CLOSED. #{$blocks.keys.join(" ")}")
187
+ end
188
+
189
+ $out = $out.split("")
190
+ ($out.length/2).times do
191
+ $out << $out.shift(2).join.to_i(16).chr
192
+ end
193
+
194
+ $options["outfile"] ||= $options["file"].split(?.)[0..-2].join(?.)+".cht"
195
+
196
+ File.write($options["outfile"],$out.join)
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "digest"
4
+
5
+ $cmdlist = []
6
+ $blocks = []
7
+ $out = []
8
+ $help = "USAGE: darasm <-f file> [ -o outfile ]"
9
+ $options = {}
10
+ $loopcount = 0
11
+
12
+ ARGV.each_with_index do |i,ind|
13
+ case i
14
+ when "-f"
15
+ $options["file"] = ARGV[ind+1]
16
+ when "-o"
17
+ $options["outfile"] = ARGV[ind+1]
18
+ end
19
+ end
20
+
21
+ unless $options["file"]
22
+ abort $help
23
+ end
24
+
25
+ $options["outfile"] ||= $options["file"].split(?.)[0..-2].join(?.)+".arasm"
26
+
27
+ content = File.read($options["file"]) rescue abort($help)
28
+ content.inspect.match(/\\x[A-F0-9]{2}/)&&content = content.bytes.map{|i|sprintf("%02x",i)}.join
29
+ content.gsub!(/[^0-9A-F]/i,"")
30
+ content = content.downcase
31
+
32
+ content.length%16==0 || abort("FATAL: INSTRUCTION LENGTH DOES NOT SEEM TO BE 16.")
33
+
34
+ (content.length/16).times{|i|$cmdlist<<content[i*16,16]} # divide it into proper instructions
35
+
36
+ lptr = 0
37
+
38
+ while lptr < cmdlist.length
39
+ com = $cmdlist[lptr]
40
+ case com
41
+ when /^0/
42
+ $out << "mvd $#{com[1,7]} $#{com[8,8]}"
43
+ when /^1/
44
+ $out << "mvw $#{com[1,7]} $#{com[8,8]}"
45
+ when /^2/
46
+ $out << "mvb $#{com[1,7]} #{com[8,8].to_i(16)}"
47
+ when /^3/
48
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
49
+ $out << "dlt $#{com[1,7]} $#{com[8,8]} .#{bname}"
50
+ $blocks << bname
51
+ $loopcount += 1
52
+ when /^4/
53
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
54
+ $out << "dgt $#{com[1,7]} $#{com[8,8]} .#{bname}"
55
+ $blocks << bname
56
+ $loopcount += 1
57
+ when /^5/
58
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
59
+ $out << "deq $#{com[1,7]} $#{com[8,8]} .#{bname}"
60
+ $blocks << bname
61
+ $loopcount += 1
62
+ when /^6/
63
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
64
+ $out << "dne $#{com[1,7]} $#{com[8,8]} .#{bname}"
65
+ $blocks << bname
66
+ $loopcount += 1
67
+ when /^7/
68
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
69
+ $out << "wlt $#{com[1,7]} $#{com[8,8]} .#{bname}"
70
+ $blocks << bname
71
+ $loopcount += 1
72
+ when /^8/
73
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
74
+ $out << "wgt $#{com[1,7]} $#{com[8,8]} .#{bname}"
75
+ $blocks << bname
76
+ $loopcount += 1
77
+ when /^9/
78
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
79
+ $out << "weq $#{com[1,7]} $#{com[8,8]} .#{bname}"
80
+ $blocks << bname
81
+ $loopcount += 1
82
+ when /^a/
83
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
84
+ $out << "wne $#{com[1,7]} #{com[8,8].to_i(16)} .#{bname}"
85
+ $blocks << bname
86
+ $loopcount += 1
87
+ when /^b/
88
+ $out << "lof $#{com[1,7]}"
89
+ when /^c/
90
+ $rop && abort("FATAL: TRYING TO PLACE A ROP BLOCK ON LINE #{i+1} INTO ROP ON LINE #{$rop[0]+1}, WTF.")
91
+ bname = Digest::MD5.hexdigest($loopcount.to_s)[10,8]
92
+ $rop = [i,bname]
93
+ $out << "rop #{com[8,8]} .#{bname}"
94
+ $loopcount += 1
95
+ when /^d0/
96
+ $out << "~#{$blocks.pop}"
97
+ when /^d1/
98
+ $out << "~#{$rop[1]}"
99
+ $rop = nil
100
+ when /^d2/
101
+ $out << "~#"
102
+ $rop = nil
103
+ $blocks = []
104
+ when /^d3/
105
+ $out << "sof $#{com[8,8]}"
106
+ when /^d4/
107
+ $out << "ast $#{com[8,8]}"
108
+ when /^d5/
109
+ $out << "sst $#{com[8,8]}"
110
+ when /^d6/
111
+ $out << "sid $#{com[8,8]}"
112
+ when /^d7/
113
+ $out << "siw $#{com[8,8]}"
114
+ when /^d8/
115
+ $out << "sib #{com[8,8].to_i(16)}"
116
+ when /^d9/
117
+ $out << "lsd $#{com[8,8]}"
118
+ when /^da/
119
+ $out << "lsw $#{com[8,8]}"
120
+ when /^db/
121
+ $out << "lsb $#{com[8,8].to_i(16)}"
122
+ when /^dc/
123
+ $out << "aof $#{com[8,8]}"
124
+ when /^e/
125
+ abort "FATAL: INSTRUCTION 'E' IS NOT IMPLEMENTED YET"
126
+ $out << "fmv $#{com[1,7]} $#{com[8,8]}"
127
+ when /^f/
128
+ $out << "fcp $#{com[1,7]} $#{com[8,8]}"
129
+ else
130
+ abort("FATAL: UNKNOWN INSTRUCTION #{com[0,2].upcase} ON LINE #{lptr+1}.")
131
+ end
132
+
133
+ lptr+=1
134
+ end
135
+
136
+ $out = $out.join("\n")
137
+ #puts $out
138
+ File.write($options["outfile"],$out)
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arasm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - sesshomariu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Action Replay Assembly Language
14
+ email: ''
15
+ executables:
16
+ - arasm
17
+ - darasm
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/arasm
22
+ - bin/darasm
23
+ homepage: ''
24
+ licenses:
25
+ - MS-PL
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.6.11
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Action Replay Assembly Language
47
+ test_files: []