indis-core 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|