Class: Relyze::DiffResults::DiffBaseResult

Inherits:
Object
  • Object
show all
Defined in:
C:/Program Files/Relyze/lib/relyze/core/diff_results.rb

Overview

Base class for all diff results. Diff results are provided as two parallel tree structures with each tree corresponding to one side of the differential analysis. The trees are linked by the #matched method for items that are seen to be either equal or modified.

Examples:

Diff two files and print some basic info

# analyze the two files we want to perform a diff against
modelA = @relyze.analyze_file( "c:\\samples\\file.before.dll" )
modelB = @relyze.analyze_file( "c:\\samples\\file.after.dll" )
# diff modelA against modelB, the results will be for the A model. To get the
# results for the B model, we can use dr.matched()
dr = modelA.diff( modelB )
dr.model.synchronize_read do
    # iterate over ever DiffFunctionResult
    dr.functions do | dr_func |
        # skip functions that were found to be equal
        next if dr_func.is_equal?
        print_message( "Function '%s' was %s (difference %.2f%%)" % [dr_func.name, dr_func.type, ( dr_func.difference * 100 ) ] )
        # iterate over every DiffCodeBlockResult in the current diff function result
        dr_func.blocks do | dr_block |
            # skip blocks that were found to be equal
            next if dr_block.is_equal?
            print_message( "    Block '%s' was %s (difference %.2f%%)" % [dr_block.name, dr_block.type, ( dr_block.difference * 100 ) ] )
            # iterate over every DiffInstructionResult in the current diff code block result
            dr_block.instructions do | dr_inst |
                # skip instructions that were found to be equal
                next if dr_inst.is_equal?
                print_message( "        Instruction '%s' was %s (difference %.2f%%)" % [dr_inst.name, dr_inst.type, ( dr_inst.difference * 100 ) ] )
            end
        end
    end
end

Diff two files and access information from the model about the results.

# analyze the two files we want to perform a diff against
modelA = @relyze.analyze_file( "c:\\samples\\file.before.dll" )
modelB = @relyze.analyze_file( "c:\\samples\\file.after.dll" )
# diff modelA against modelB, the results will be for the A model. To get the
# results for the B model, we can use dr.matched()
dr = modelA.diff( modelB )
dr.model.synchronize_read do
    # iterate over ever DiffFunctionResult
    dr.functions do | dr_func |
        # skip functions that were not modified (so either equal, removed or added)
        next if not dr_func.is_modified?
        print_message( "Function '%s' was %s (difference %.2f%%)" % [dr_func.name, dr_func.type, ( dr_func.difference * 100 ) ] )
        # pull out the FunctionData type and iterate over every reference in to its root block
        dr_func.function.block( dr_func.rva ).references( :in ) do | ref |
            # skip non control flow references
            next if not ref.control_flow?
            # get every function which contains the referencing block
            dr.model.functions( ref.owner_rva ) do | parent_func |
                print_message( "    Found control flow reference from function '%s' to this function." % [ parent_func.block( parent_func.rva ).name ] )
            end
        end
    end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, type, difference, rva, matched_rva) ⇒ DiffBaseResult

Returns a new instance of DiffBaseResult



101
102
103
104
105
106
107
108
109
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 101

def initialize( parent, type, difference, rva, matched_rva )
    @parent         = parent
    @type           = type # 
    @difference     = difference
    @rva            = rva
    @matched_rva    = matched_rva
    @children       = nil
    @cached_matched = nil
end

Instance Attribute Details

#differenceFloat (readonly)

Get the difference as a value between 0 and 1, where 0 is no difference (therefore type will be :equal) and 1 is 100% different to that of this results matched results.

Returns:

  • (Float)


88
89
90
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 88

def difference
  @difference
end

#matched_rvaInteger (readonly)

If this results has been matched to a corresponding result (therefore type will be either :equal or :modified), get the matched RVA of the corresponding results.

Returns:



99
100
101
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 99

def matched_rva
  @matched_rva
end

#parentRelyze::DiffResults::DiffBaseResult (readonly)

Get the parent diff results for this results. For example the parent of a DiffInstructionResult will be its corresponding DiffCodeBlockResult, whose parent will be its corresponding DiffFunctionResult, whose parent will be its corresponding DiffModelResult. A DiffModelResult will not have a parent.



77
78
79
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 77

def parent
  @parent
end

#rvaInteger (readonly)

Get the RVA of this results

Returns:



93
94
95
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 93

def rva
  @rva
end

#typeSymbol (readonly)

Get the type of results this is and may be either :equal, :modified, :removed or :added

Returns:

  • (Symbol)


82
83
84
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 82

def type
  @type
end

Instance Method Details

#_generate_child(rva) ⇒ Object (protected)



218
219
220
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 218

def _generate_child( rva )
    return nil
end

#get_child(rva) ⇒ Relyze::DiffResults::DiffBaseResult?

Helper method to get a child result of this item at a specific RVA. This method will be aliased by super classes to provide the expected functionality.

Parameters:

  • rva (Integer)

    The RVA of the child

Returns:



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 165

def get_child( rva )
    if( rva.nil? or @children.nil? or not @children.has_key?( rva ) )
        return nil
    end
    result = @children[rva]
    if( not result.nil? )
        if( not result.kind_of?( ::WeakRef ) )
            return result
        elsif( result.weakref_alive? )
            result = result.__getobj__ rescue nil
        else
            result = nil
        end
    end
    if( result.nil? )
        result = self._generate_child( rva )        
        if( not result.nil? )
            @children[rva] = ::WeakRef.new( result )
        end
    end
    return result
end

#get_children {|child| ... } ⇒ Array<Relyze::DiffResults::DiffBaseResult>?

Helper method to get all the child results of this item. This method will be aliased by super classes to provide the expected functionality.

Yields:

  • (child)

    yields the child to the block.

Yield Parameters:

Returns:



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 143

def get_children
    result = nil
    if( not @children.nil? )
        @children.each_key do | rva |
            if( block_given? )
                yield self.get_child( rva )
            else
                if( result.nil? )
                    result = ::Array.new
                end
                result << self.get_child( rva )
            end
        end
    end
    return result
end

#is_added?true, false

Test if this diff result is for an added item.

Returns:

  • (true, false)


212
213
214
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 212

def is_added?
    return (@type == :added)
end

#is_equal?true, false

Test if this diff result is for an equal item.

Returns:

  • (true, false)


191
192
193
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 191

def is_equal?
    return (@type == :equal)
end

#is_modified?true, false

Test if this diff result is for an modified item.

Returns:

  • (true, false)


198
199
200
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 198

def is_modified?
    return (@type == :modified)
end

#is_removed?true, false

Test if this diff result is for an removed item.

Returns:

  • (true, false)


205
206
207
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 205

def is_removed?
    return (@type == :removed)
end

#matchedRelyze::DiffResults::DiffBaseResult?

Get the corresponding DiffBaseResult for this item as matched by the diffing algorithm.

Returns:



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'C:/Program Files/Relyze/lib/relyze/core/diff_results.rb', line 114

def matched
    if( self.is_removed? or self.is_added? )
        return nil
    end
    result = @cached_matched
    if( not result.nil? )
        if( not result.kind_of?( ::WeakRef ) )
            return result
        elsif( result.weakref_alive? )
            result = result.__getobj__ rescue nil
        else
            result = nil
        end
    end
    if( result.nil? and not @parent.nil? )
        result = @parent.matched.get_child( @matched_rva )
        if( not result.nil? )
            @cached_matched = ::WeakRef.new( result )
        end
    end
    return result
end
Documentation Tool" target="_parent">yard 0.9.20 (ruby-2.6.5).