indis-core 0.1.0 → 0.1.1
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.
- data/lib/indis-core/binary_format.rb +1 -1
- data/lib/indis-core/binaryops_string.rb +150 -0
- data/lib/indis-core/segment.rb +1 -1
- data/lib/indis-core/target.rb +2 -2
- data/lib/indis-core/version.rb +1 -1
- data/lib/indis-core/vmmap.rb +2 -2
- data/spec/indis-core/binaryops_string_spec.rb +55 -0
- metadata +4 -1
@@ -0,0 +1,150 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# Indis framework #
|
3
|
+
# Copyright (C) 2012 Vladimir "Farcaller" Pouzanov <farcaller@gmail.com> #
|
4
|
+
# #
|
5
|
+
# This program is free software: you can redistribute it and/or modify #
|
6
|
+
# it under the terms of the GNU General Public License as published by #
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or #
|
8
|
+
# (at your option) any later version. #
|
9
|
+
# #
|
10
|
+
# This program is distributed in the hope that it will be useful, #
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
13
|
+
# GNU General Public License for more details. #
|
14
|
+
# #
|
15
|
+
# You should have received a copy of the GNU General Public License #
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
17
|
+
##############################################################################
|
18
|
+
|
19
|
+
# BinaryopsString manages bitwise operations on a String. This is useful when
|
20
|
+
# you expect bitstrings with meaningful leading zeroes.
|
21
|
+
class BinaryopsString < String
|
22
|
+
# BinaryopsString can be initialized either from a String or a Fixnum
|
23
|
+
# @param [String, Fixnum] s source value
|
24
|
+
def initialize(s)
|
25
|
+
if s.class == Fixnum
|
26
|
+
super s.to_s(2)
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Outputs an unsigned int value of self
|
33
|
+
def to_i
|
34
|
+
super 2
|
35
|
+
end
|
36
|
+
|
37
|
+
# Outputs a signed int value of self
|
38
|
+
def to_signed_i
|
39
|
+
return to_i if self[0] == '0'
|
40
|
+
complement = ('1'*(self.length)).to_i(2) - to_i + 1
|
41
|
+
-complement
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return a new BinaryopsString with a given slice (rightmost bit is 0)
|
45
|
+
# @param [Fixnum] from first bit (inclusive)
|
46
|
+
# @param [Fixnum] to last bit (inclusive)
|
47
|
+
def bits(from, to)
|
48
|
+
BinaryopsString.new(self.to_s[~from..~to])
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return a new BinaryopsString with a given slice (leftmost bit is 0)
|
52
|
+
# @param [Fixnum] from first bit (inclusive)
|
53
|
+
# @param [Fixnum] to last bit (inclusive)
|
54
|
+
def rbits(from, to)
|
55
|
+
BinaryopsString.new(self.to_s[from..to])
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return a Fixnum with given bit value (rightmost bit is 0)
|
59
|
+
# @param [Fixnum] i the bit in question
|
60
|
+
def bit(i)
|
61
|
+
self[~i].to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return a Fixnum with given bit value (leftmost bit is 0)
|
65
|
+
# @param [Fixnum] i the bit in question
|
66
|
+
def rbit(i)
|
67
|
+
self[i].to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
# Performs an OR operation
|
71
|
+
# @return a new BinaryopsString with result
|
72
|
+
# @raise [ArgumentError] when BinaryopsString lengths don't match
|
73
|
+
def |(other)
|
74
|
+
raise ArgumentError unless self.length == other.length
|
75
|
+
BinaryopsString.new(self.to_i | other.to_i).zero_extend(self.length)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Concatenates the receiver with another BinaryopsString
|
79
|
+
# @return a new BinaryopsString with result
|
80
|
+
def concat(other)
|
81
|
+
BinaryopsString.new(self.to_s + other.to_s)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Zero-extends the receiver to given length (left padding)
|
85
|
+
# @return a new BinaryopsString with result
|
86
|
+
def zero_extend(len)
|
87
|
+
return self unless len-self.length > 0
|
88
|
+
zbs = '0'*(len-self.length)
|
89
|
+
BinaryopsString.new(zbs + self.to_s)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Sign-extends the receiver to given length (left padding)
|
93
|
+
# @return a new BinaryopsString with result
|
94
|
+
def sign_extend(len)
|
95
|
+
return self unless len-self.length > 0
|
96
|
+
zbs = self[0]*(len-self.length)
|
97
|
+
BinaryopsString.new(zbs + self.to_s)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Performs a LSL operation
|
101
|
+
# @return a new BinaryopsString with result
|
102
|
+
def <<(amount)
|
103
|
+
return self if amount == 0
|
104
|
+
z = BinaryopsString.zeroes(amount)
|
105
|
+
concat(z).bits(self.length-1, 0)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Performs a LSR operation
|
109
|
+
# @return a new BinaryopsString with result
|
110
|
+
def >>(amount)
|
111
|
+
return self if amount == 0
|
112
|
+
z = BinaryopsString.zeroes(amount)
|
113
|
+
z.concat(self).rbits(0, self.length-1)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Performs a ROR operation (cyclic LSR)
|
117
|
+
# @return a new BinaryopsString with result
|
118
|
+
def ror(amount)
|
119
|
+
return self if amount == 0
|
120
|
+
s = self.to_s
|
121
|
+
moveover = s[-amount..-1]
|
122
|
+
movable = s[0...-amount]
|
123
|
+
BinaryopsString.new(moveover + movable)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns a new BinaryopsString filled in with zeroes of given length
|
127
|
+
def self.zeroes(n)
|
128
|
+
BinaryopsString.new('0'*n)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class String
|
133
|
+
# Helper method to convert String to BinaryopsString
|
134
|
+
def to_bo
|
135
|
+
BinaryopsString.new(self)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class Fixnum
|
140
|
+
# Helper method to convert Fixnum to BinaryopsString
|
141
|
+
def to_bo
|
142
|
+
BinaryopsString.new(self.to_s(2))
|
143
|
+
end
|
144
|
+
|
145
|
+
# Helper method to convert Fixnum to BinaryopsString with given length
|
146
|
+
# (zero-padded)
|
147
|
+
def to_boz(len)
|
148
|
+
BinaryopsString.new(self.to_s(2)).zero_extend(len)
|
149
|
+
end
|
150
|
+
end
|
data/lib/indis-core/segment.rb
CHANGED
@@ -25,7 +25,7 @@ module Indis
|
|
25
25
|
# @note this class is heavily based on Mach-O
|
26
26
|
class Segment
|
27
27
|
# Contains a list of current segment sections
|
28
|
-
# @return [Array]
|
28
|
+
# @return [Array<Indis::Section>]
|
29
29
|
attr_reader :sections
|
30
30
|
|
31
31
|
attr_reader :target # @return [Indis::Target] owning target
|
data/lib/indis-core/target.rb
CHANGED
@@ -30,9 +30,9 @@ module Indis
|
|
30
30
|
|
31
31
|
attr_reader :vmmap # @return [Indis::VMMap] virtual memory map
|
32
32
|
|
33
|
-
attr_accessor :segments # @return [Array] list of all processed {Indis::Segment segments}
|
33
|
+
attr_accessor :segments # @return [Array<Indis::Segment>] list of all processed {Indis::Segment segments}
|
34
34
|
|
35
|
-
attr_accessor :symbols # @return [Array] list of all processed {Indis::Symbol symbols}
|
35
|
+
attr_accessor :symbols # @return [Array<Indis::Symbol>] list of all processed {Indis::Symbol symbols}
|
36
36
|
|
37
37
|
# @param [String] filename target binary file name
|
38
38
|
# @raise [AttributeError] if the file does not exist
|
data/lib/indis-core/version.rb
CHANGED
data/lib/indis-core/vmmap.rb
CHANGED
@@ -54,7 +54,7 @@ module Indis
|
|
54
54
|
s.bytes[ofs-s.vmaddr].ord
|
55
55
|
end
|
56
56
|
|
57
|
-
# @return [Array] a list of bytes at given virtual address span
|
57
|
+
# @return [Array<Fixnum>] a list of bytes at given virtual address span
|
58
58
|
def bytes_at(ofs, size)
|
59
59
|
seg = segment_at(ofs)
|
60
60
|
return nil unless seg
|
@@ -110,7 +110,7 @@ module Indis
|
|
110
110
|
# nil's. For each unmapped byte it is returned as a Fixnum
|
111
111
|
#
|
112
112
|
# @param [Range] range range
|
113
|
-
# @return [Array] mapped entities
|
113
|
+
# @return [Array<Indis::Entity,nil,Fixnum>] mapped entities
|
114
114
|
# @raise [ArgumentError] if there is no segment at given range or the range spans several segments
|
115
115
|
def [](range)
|
116
116
|
return entity_at(range) if range.is_a?(Fixnum)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'indis-core/binaryops_string'
|
2
|
+
|
3
|
+
describe BinaryopsString do
|
4
|
+
it "should initialize from String" do
|
5
|
+
BinaryopsString.new('0110').should == '0110'
|
6
|
+
BinaryopsString.new('0110').to_i.should == 0b0110
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should initialize from Fixnum" do
|
10
|
+
BinaryopsString.new(0b0110).should == '110'
|
11
|
+
BinaryopsString.new(0b0110).to_i.should == 0b110
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should initialize from given zeroes count" do
|
15
|
+
BinaryopsString.zeroes(5).should == '00000'
|
16
|
+
BinaryopsString.zeroes(5).to_i.should == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should perform concatenation" do
|
20
|
+
BinaryopsString.new('0110').concat(BinaryopsString.new('0001')).to_s.should == '01100001'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should perform zero extension" do
|
24
|
+
BinaryopsString.new('0110').zero_extend(8).should == '00000110'
|
25
|
+
BinaryopsString.new('0110').zero_extend(4).should == '0110'
|
26
|
+
BinaryopsString.new('0110').zero_extend(0).should == '0110'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should perform sign extension" do
|
30
|
+
BinaryopsString.new('1010').sign_extend(8).should == '11111010'
|
31
|
+
BinaryopsString.new('0010').sign_extend(8).should == '00000010'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should output correct sign on to_signed_i" do
|
35
|
+
BinaryopsString.new('11111010').to_signed_i.should == -6
|
36
|
+
BinaryopsString.new('00001010').to_signed_i.should == 10
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should output correct sign on to_i" do
|
40
|
+
BinaryopsString.new('11111010').to_i.should == 250
|
41
|
+
BinaryopsString.new('00001010').to_i.should == 10
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should perform lsl / lsr" do
|
45
|
+
(BinaryopsString.new('0110') << 1).should == '1100'
|
46
|
+
(BinaryopsString.new('0110') >> 1).should == '0011'
|
47
|
+
(BinaryopsString.new('0110') << 2).should == '1000'
|
48
|
+
(BinaryopsString.new('0110') >> 2).should == '0001'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should perform ror" do
|
52
|
+
(BinaryopsString.new('0110').ror(1)).should == '0011'
|
53
|
+
(BinaryopsString.new('0110').ror(2)).should == '1001'
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: indis-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- indis-core.gemspec
|
46
46
|
- lib/indis-core.rb
|
47
47
|
- lib/indis-core/binary_format.rb
|
48
|
+
- lib/indis-core/binaryops_string.rb
|
48
49
|
- lib/indis-core/data_entity.rb
|
49
50
|
- lib/indis-core/entity.rb
|
50
51
|
- lib/indis-core/section.rb
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- lib/indis-core/vmmap.rb
|
56
57
|
- spec/fixtures/single-object.o
|
57
58
|
- spec/indis-core/binary_format_spec.rb
|
59
|
+
- spec/indis-core/binaryops_string_spec.rb
|
58
60
|
- spec/indis-core/data_entity_spec.rb
|
59
61
|
- spec/indis-core/section_spec.rb
|
60
62
|
- spec/indis-core/segment_spec.rb
|
@@ -90,6 +92,7 @@ summary: Core indis components
|
|
90
92
|
test_files:
|
91
93
|
- spec/fixtures/single-object.o
|
92
94
|
- spec/indis-core/binary_format_spec.rb
|
95
|
+
- spec/indis-core/binaryops_string_spec.rb
|
93
96
|
- spec/indis-core/data_entity_spec.rb
|
94
97
|
- spec/indis-core/section_spec.rb
|
95
98
|
- spec/indis-core/segment_spec.rb
|