Changeset 112

Show
Ignore:
Timestamp:
12/14/06 03:48:53 (2 years ago)
Author:
kindlund
Message:

Identified slowdown culprit: XML::XPath using $` (which is bad). Developed patch file.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/bug/42/etc/honeyclient.xml

    r96 r112  
    7272            </timeout> 
    7373            <Browser> 
    74                    <!-- HoneyClient::Agent::Driver::IE Options --> 
    75                <!-- TODO: Update this. --> 
    76                <ignore_links_timed_out description="If this parameter is 1, then the browser will never attempt to revisit any links that caused the browser to initially time out." default="0"> 
     74                <!-- HoneyClient::Agent::Driver::IE Options --> 
     75                <!-- TODO: Update this. --> 
     76                <ignore_links_timed_out description="If this parameter is 1, then the browser will never attempt to revisit any links that caused the browser to initially time out." default="0"> 
    7777                    1 
    7878                </ignore_links_timed_out> 
    79                <!-- TODO: Update this. --> 
    80                <process_name description="The name of the Internet Explorer application process, as it appears in the Task Manager." default="iexplore.exe"> 
     79                <!-- TODO: Update this. --> 
     80                <process_name description="The name of the Internet Explorer application process, as it appears in the Task Manager." default="iexplore.exe"> 
    8181                    iexplore.exe 
    8282                </process_name> 
    83                <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
     83                <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
    8484                    -1 
    8585                </max_relative_links_to_visit> 
    86                <IE> 
    87                        <!-- HoneyClient::Agent::Driver::IE Options --> 
    88                    <!-- TODO: Update this. --> 
    89                    <ignore_links_timed_out description="If this parameter is 1, then the browser will never attempt to revisit any links that caused the browser to initially time out." default="0"> 
     86                <IE> 
     87                    <!-- HoneyClient::Agent::Driver::IE Options --> 
     88                    <!-- TODO: Update this. --> 
     89                    <ignore_links_timed_out description="If this parameter is 1, then the browser will never attempt to revisit any links that caused the browser to initially time out." default="0"> 
    9090                        1 
    9191                    </ignore_links_timed_out> 
    92                    <!-- TODO: Update this. --> 
    93                    <process_name description="The name of the Internet Explorer application process, as it appears in the Task Manager." default="iexplore.exe"> 
     92                    <!-- TODO: Update this. --> 
     93                    <process_name description="The name of the Internet Explorer application process, as it appears in the Task Manager." default="iexplore.exe"> 
    9494                        iexplore.exe 
    9595                    </process_name> 
    96                    <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
     96                    <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
    9797                        -1 
    9898                    </max_relative_links_to_visit> 
    99                    </IE> 
     99                </IE> 
    100100                <FF> 
    101                    <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
     101                    <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
    102102                        5 
    103103                    </max_relative_links_to_visit> 
    104                    <!-- http://gatekeeper-w.mitre.org:80 --> 
    105                    <http_proxy description="Set to your HTTP Proxy if you have one, otherwise set to 'none'"> 
     104                    <!-- http://gatekeeper-w.mitre.org:80 --> 
     105                    <http_proxy description="Set to your HTTP Proxy if you have one, otherwise set to 'none'"> 
    106106                        none 
    107107                    </http_proxy> 
    108                    <ff_exec description="path to the firefox executable (default install path is C:\Program Files\Mozilla Firefox\firefox.exe)"> 
     108                    <ff_exec description="path to the firefox executable (default install path is C:\Program Files\Mozilla Firefox\firefox.exe)"> 
    109109                        C:\Program Files\Mozilla Firefox\firefox.exe 
    110110                    </ff_exec> 
    111                </FF> 
     111                </FF> 
    112112            </Browser> 
    113113            <EmailClient> 
  • honeyclient/branches/bug/42/etc/honeyclient_log.conf

    r108 r112  
    6161log4perl.rootLogger=DEBUG, Screen 
    6262# Suppress Parser Debugging Messages 
    63 # Note: If you want to change the logging level for the parser, then 
    64 # you must also edit the Parser.pm file directly, as this setting 
    65 # is only enforced within the Parser.pm file. 
    6663log4perl.logger.HoneyClient.Agent.Integrity.Registry.Parser=INFO, Screen 
    6764log4perl.appender.Screen=Log::Log4perl::Appender::Screen 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry.pm

    r111 r112  
    407407        } 
    408408 
    409         $parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file => $fname); 
     409        $parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file   => $fname, 
     410                                                                        index_groups => 1); 
    410411 
    411412        # Preemptively unlink the file, to prevent any other process from mucking with it. 
     
    559560 
    560561    # Perform diff operation. 
    561     my $status = system("diff --speed-large-files \"" . $src_filename . "\" \"" . $tgt_filename . "\" | 
    562                          grep -e '^[0-9].*' > " . $fname_tmp); 
    563     if ($status == 2) { 
     562    # Because we're chaining together multiple system operations, we have to check the file output 
     563    # directly, to see if any failures occurred. 
     564    system("((diff --speed-large-files \"" . $src_filename . "\" \"" . $tgt_filename . "\" && " . 
     565             "echo \"0NOCHANGES\") | " .  
     566            "grep -e '^[0-9].*' || echo \"FAILURE\") > " . $fname_tmp . " 2>/dev/null"); 
     567 
     568    my $fh = new IO::File($fname_tmp, "r"); 
     569    if (!defined($fh)) { 
     570        $LOG->fatal("Error: Unable to read file '" . $fname_tmp . "'!"); 
     571        Carp::croak("Error: Unable to read file '" . $fname_tmp . "'!"); 
     572    } 
     573 
     574    # Read in the first line. 
     575    $/ = "\n"; 
     576    $_ = <$fh>; 
     577 
     578    if (defined($_)) { 
     579        if ($_ eq "0NOCHANGES\n") { 
     580            $LOG->info("No changes detected in specified data."); 
     581            _cleanup($fname_tmp); 
     582            return ($src_offsets, $tgt_offsets); 
     583        } 
     584        if ($_ eq "FAILURE\n") { 
     585            # Check if diff operation failed. 
     586            _cleanup($fname_tmp); 
    564587            $LOG->fatal("Error: Unable to diff '" . $src_filename . "' against '" . $tgt_filename ."'."); 
    565588            Carp::croak("Error: Unable to diff '" . $src_filename . "' against '" . $tgt_filename ."'."); 
    566     } 
    567  
    568     if ($status == 1) { 
    569         return ($src_offsets, $tgt_offsets); 
    570     } 
    571  
    572     # Delete the unconverted temporary file. 
    573 #    if (!unlink($fname_tmp)) { 
    574 #        $LOG->fatal("Error: Unable to unlink temporary file '" . $fname_tmp ."'."); 
    575 #        Carp::croak("Error: Unable to unlink temporary file '" . $fname_tmp ."'."); 
    576 #    } 
     589        } 
     590    } 
     591 
     592    do { 
     593        if (/([0-9]+)(?:|,[0-9]+)[a-z]([0-9]+)/) { 
     594            push (@{$src_offsets}, $1); 
     595            push (@{$tgt_offsets}, $2); 
     596        } 
     597    } while (<$fh>); 
     598 
     599    _cleanup($fname_tmp); 
     600    return ($src_offsets, $tgt_offsets); 
     601
     602 
     603# Helper function, to delete a specified temporary file. 
     604
     605# Inputs: tmpfile 
     606# Outputs: None 
     607sub _cleanup { 
     608    my $tmpfile = shift; 
     609    undef $/; 
     610    if (!unlink($tmpfile)) { 
     611        $LOG->fatal("Error: Unable to unlink temporary file '" . $tmpfile ."'."); 
     612        Carp::croak("Error: Unable to unlink temporary file '" . $tmpfile ."'."); 
     613    } 
     614
     615 
     616# TODO: Comment this. 
     617sub _compare { 
     618 
     619    # Extract arguments. 
     620    my ($self, %args) = @_; 
     621 
     622    my $before_parser = $args{'before_parser'}; 
     623    my $after_parser  = $args{'after_parser'}; 
     624 
     625    # Array reference, containing hashtables, where each 
     626    # hashtable represents a change between the before and 
     627    # after parsers. 
     628    my $changes = [];  
     629 
     630    # Array references, reflecting collection of offsets 
     631    # found, where differences occur between before and 
     632    # after the specified files. 
     633    my ($before_offsets, $after_offsets) = $self->_diff($before_parser, $after_parser); 
     634 
     635    # Get first offsets. 
     636    my $before_offset = shift(@{$before_offsets}); 
     637    my $after_offset = shift(@{$after_offsets}); 
     638 
     639    # Return early, if no changes were found. 
     640    if (!defined($before_offset) && !defined($after_offset)) { 
     641        return $changes; 
     642    } 
     643 
     644    # Seek to nearest common group. 
     645    $before_parser->seekToNearestGroup(absolute_offset => $before_offset); 
     646#    $after_parser->seekToNearestGroup(absolute_offset => $after_offset); 
     647 
     648    # Start with the first registry group from both files. 
     649    my $before_group = $self->_nextGroup($before_parser); 
     650    my $after_group  = $self->_nextGroup($after_parser); 
     651 
     652    # A hashtable reference, containing the latest change found. 
     653    my $change = { }; 
     654 
     655    # While we are able to read the next key from either file... 
     656    while (defined($before_group) || defined($after_group)) { 
     657 
     658        # Reset the change hashref. 
     659        $change = { }; 
     660 
     661        # If the next group name extracted from both files is identical...  
     662        if (defined($before_group) && defined($after_group) && 
     663            ($self->_cmpGroup($before_group, $after_group) == 0)) { 
     664 
     665            # Extract the next key/value pair corresponding to this group from 
     666            # both files. 
     667            my ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
     668            my ($after_entry_name, $after_entry_value)   = $self->_nextVal($after_parser); 
     669 
     670            # While this key name exists in either file... 
     671            while (defined($before_entry_name) || defined($after_entry_name)) { 
     672 
     673                # If the key name matches in both files... 
     674                if (defined($before_entry_name) && defined($after_entry_name) && 
     675                    $self->_cmpEntryName($before_entry_name, $after_entry_name) == 0) { 
     676 
     677                    # If the corresponding values in both files are 
     678                    # DIFFERENT... 
     679                    if ($before_entry_value ne $after_entry_value) { 
     680 
     681                        # Scenario: 
     682                        # Same directory name, same entry key name, 
     683                        # but different entry values. 
     684 
     685                        # Save the change. 
     686                        $change->{'key'} = $before_group; 
     687                        $change->{'status'} = "changed"; 
     688                        $change->{'entries'}->{$before_entry_name} = { 
     689                            old_value => $before_entry_value, 
     690                            new_value => $after_entry_value, 
     691                        }; 
     692                    } 
     693 
     694                    # Get the next corresponding key/value pair from this group. 
     695                    ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
     696                    ($after_entry_name, $after_entry_value)   = $self->_nextVal($after_parser); 
     697 
     698                # Else, the key names are different in both files... 
     699                } else { 
     700 
     701                    # Scenario: 
     702                    # Same directory name, different entry key names. 
     703 
     704                    # Save the change. 
     705                    $change->{'key'} = $before_group; 
     706                    $change->{'status'} = "changed"; 
     707 
     708                    # If the after key name doesn't exist, or if the before key  
     709                    # name exists and the before name is alphabetically earlier 
     710                    # than the after key name... 
     711                    if (!defined($after_entry_name) || defined($before_entry_name) && 
     712                        $self->_cmpEntryName($before_entry_name, $after_entry_name) < 0) { 
     713 
     714                        # Then we know that the before key name got deleted 
     715                        # in the after file. 
     716                        # Check to see if some of this change data already exists... 
     717                        if (exists($change->{'entries'}->{$before_entry_name})) { 
     718 
     719                            # Sanity check: Looks like an earlier iteration populated 
     720                            # this change entry with a 'new_value'.  Let's make sure 
     721                            # the our 'old_value' and 'new_value' are truly different. 
     722                            if (defined($change->{'entries'}->{$before_entry_name}->{'new_value'}) && 
     723                                ($change->{'entries'}->{$before_entry_name}->{'new_value'} ne 
     724                                 $before_entry_value)) { 
     725 
     726                                # Okay, looks like they're different, so only update the old_value. 
     727                                $change->{'entries'}->{$before_entry_name}->{'old_value'} = $before_entry_value; 
     728                            } else { 
     729                                # Looks like they're the same value, so delete the entry completely. 
     730                                delete($change->{'entries'}->{$before_entry_name}); 
     731                            } 
     732                        } else { 
     733                            # If not, then update both old_value and new_value. 
     734                            $change->{'entries'}->{$before_entry_name} = { 
     735                                old_value => $before_entry_value, 
     736                                new_value => undef, 
     737                            }; 
     738                        } 
     739 
     740                        # And get the next corresponding key/value pair from the before group. 
     741                        ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
     742 
     743                    # Else, the after key name exists but the corresponding before key name  
     744                    # did not exist -- which means that this is a new key/value pair. 
     745                    } else { 
     746 
     747                        # Check to see if some of this change data already exists... 
     748                        if (exists($change->{'entries'}->{$after_entry_name})) { 
     749                            # Sanity check: Looks like an earlier iteration populated 
     750                            # this change entry with an 'old_value'.  Let's make sure 
     751                            # the our 'old_value' and 'new_value' are truly different. 
     752                            if (defined($change->{'entries'}->{$after_entry_name}->{'old_value'}) && 
     753                                ($change->{'entries'}->{$after_entry_name}->{'old_value'} ne 
     754                                 $after_entry_value)) { 
     755 
     756                                # Okay, looks like they're different, so only update the new_value. 
     757                                $change->{'entries'}->{$after_entry_name}->{'new_value'} = $after_entry_value; 
     758                            } else { 
     759                                # Looks like they're the same value, so delete the entry completely. 
     760                                delete($change->{'entries'}->{$after_entry_name}); 
     761                            } 
     762                        } else { 
     763                            # If not, then update both old_value and new_value. 
     764                            $change->{'entries'}->{$after_entry_name} = { 
     765                                old_value => undef, 
     766                                new_value => $after_entry_value, 
     767                            }; 
     768                        } 
     769 
     770                        # And get the next corresponding key/value pair from the after group. 
     771                        ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
     772                    } 
     773                } 
     774            } 
     775 
     776            # Once we're out of the previous loop, then we are finished enumerating 
     777            # all key/value pairs corresponding to the identical group in either files. 
     778 
     779            # And get the next group to compare from both files. 
     780            $before_group = $self->_nextGroup($before_parser); 
     781            $after_group  = $self->_nextGroup($after_parser); 
     782 
     783        # Else, if the after group doesn't exist, or if the before group exists and the 
     784        # before group name is alphabetically earlier than the after group name... 
     785        } elsif (!defined($after_group) || defined($before_group) && 
     786                 $self->_cmpGroup($before_group, $after_group) < 0) { 
     787 
     788            # Get the length of the before group. 
     789            my $before_group_length = length($before_group); 
     790 
     791            # Scenario: 
     792            # Directory was deleted. 
     793 
     794            # Save the change. 
     795            $change->{'key'} = $before_group; 
     796            $change->{'status'} = "deleted"; 
     797            $change->{'entries'} = { }; 
     798 
     799            # Get the first key/value pair from this before group. 
     800            my ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
     801 
     802            # While there are key/values within this before group. 
     803            while (defined($before_entry_name)) { 
     804                $change->{'entries'}->{$before_entry_name} = { 
     805                    old_value => $before_entry_value, 
     806                    new_value => undef, 
     807                }; 
     808 
     809                # And get the next corresponding key/value pair from the before group. 
     810                ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
     811            } 
     812 
     813            # Get the next group from the before file. 
     814            $before_group = $self->_nextGroup($before_parser); 
     815 
     816        # Else, the after group exists but the corresponding before group 
     817        # did not exist -- which means that this is a new group. 
     818        } else { 
     819            # Scenario: 
     820            # Directory was added. 
     821 
     822            # Save the change. 
     823            $change->{'key'} = $after_group; 
     824            $change->{'status'} = "added"; 
     825            $change->{'entries'} = { }; 
     826 
     827            # Get the first key/value pair from this after group. 
     828            my ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
     829 
     830            # While there are key/values within this after group. 
     831            while (defined($after_entry_name)) { 
     832 
     833                $change->{'entries'}->{$after_entry_name} = { 
     834                    old_value => undef, 
     835                    new_value => $after_entry_value, 
     836                }; 
     837 
     838                # Get the next key/value pair from the after group. 
     839                ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
     840            } 
     841 
     842            # Get the next group from the after file. 
     843            $after_group = $self->_nextGroup($after_parser); 
     844        } 
     845 
     846        # Transform the 'entries' sub-key from a nested hash structure, 
     847        # into an array of separate hashtables. 
     848        if (exists($change->{'entries'})) { 
     849            my $entries = [ ]; 
     850            while (my ($key, $value) = each(%{$change->{'entries'}})) { 
     851                push (@{$entries}, { 
     852                        name      => $key, 
     853                        old_value => $value->{'old_value'}, 
     854                        new_value => $value->{'new_value'}, 
     855                }); 
     856            } 
     857            $change->{'entries'} = $entries; 
     858        } 
     859 
     860        # Push the change onto our array of changes. 
     861        if (scalar(keys(%{$change}))) { 
     862            push(@{$changes}, $change); 
     863        } 
     864    } 
     865 
     866    # TODO: delete this, eventually. 
     867    $Data::Dumper::Terse = 1; 
     868    $Data::Dumper::Indent = 1; 
     869    #print "Complete list: " . Dumper($changes) . "\n"; 
     870    return $changes; 
    577871} 
    578872 
     
    7331027        $LOG->info("Before file '" . $args{'before_file'} . "' manually specified; " . 
    7341028                   "using this file as basis, instead of any previous registry snapshot."); 
    735         $before_parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file => $args{'before_file'}); 
     1029        $before_parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file   => $args{'before_file'}, 
     1030                                                                               index_groups => 1); 
    7361031        $self->{_filenames}->{$before_parser} = $args{'before_file'}; 
    7371032    } 
     
    7421037        $LOG->info("After file '" . $args{'after_file'} . "' manually specified; " . 
    7431038                   "using this file for comparison, instead of snapshotting the registry."); 
    744         $after_parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file => $args{'after_file'}); 
     1039        $after_parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file   => $args{'after_file'}, 
     1040                                                                              index_groups => 1); 
    7451041        $self->{_filenames}->{$after_parser} = $args{'after_file'}; 
    7461042    } 
     
    7791075    return $changes; 
    7801076}         
    781  
    782 # TODO: Comment this. 
    783 sub _compare { 
    784  
    785     # Extract arguments. 
    786     my ($self, %args) = @_; 
    787  
    788     my $before_parser = $args{'before_parser'}; 
    789     my $after_parser  = $args{'after_parser'}; 
    790  
    791     # Array reference, containing hashtables, where each 
    792     # hashtable represents a change between the before and 
    793     # after parsers. 
    794     my $changes = [];  
    795  
    796     # Array references, reflecting collection of offsets 
    797     # found, where differences occur between before and 
    798     # after the specified files. 
    799     #my ($before_offsets, $after_offsets) = $self->_diff($before_parser, $after_parser); 
    800  
    801     # Start with the first registry group from both files. 
    802     my $before_group = $self->_nextGroup($before_parser); 
    803     my $after_group  = $self->_nextGroup($after_parser); 
    804  
    805     # A hashtable reference, containing the latest change found. 
    806     my $change = { }; 
    807  
    808     # While we are able to read the next key from either file... 
    809     while (defined($before_group) || defined($after_group)) { 
    810  
    811         # Reset the change hashref. 
    812         $change = { }; 
    813  
    814         # If the next group name extracted from both files is identical...  
    815         if (defined($before_group) && defined($after_group) && 
    816             ($self->_cmpGroup($before_group, $after_group) == 0)) { 
    817  
    818             # Extract the next key/value pair corresponding to this group from 
    819             # both files. 
    820             my ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
    821             my ($after_entry_name, $after_entry_value)   = $self->_nextVal($after_parser); 
    822  
    823             # While this key name exists in either file... 
    824             while (defined($before_entry_name) || defined($after_entry_name)) { 
    825  
    826                 # If the key name matches in both files... 
    827                 if (defined($before_entry_name) && defined($after_entry_name) && 
    828                     $self->_cmpEntryName($before_entry_name, $after_entry_name) == 0) { 
    829  
    830                     # If the corresponding values in both files are 
    831                     # DIFFERENT... 
    832                     if ($before_entry_value ne $after_entry_value) { 
    833  
    834                         # Scenario: 
    835                         # Same directory name, same entry key name, 
    836                         # but different entry values. 
    837  
    838                         # Save the change. 
    839                         $change->{'key'} = $before_group; 
    840                         $change->{'status'} = "changed"; 
    841                         $change->{'entries'}->{$before_entry_name} = { 
    842                             old_value => $before_entry_value, 
    843                             new_value => $after_entry_value, 
    844                         }; 
    845                     } 
    846  
    847                     # Get the next corresponding key/value pair from this group. 
    848                     ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
    849                     ($after_entry_name, $after_entry_value)   = $self->_nextVal($after_parser); 
    850  
    851                 # Else, the key names are different in both files... 
    852                 } else { 
    853  
    854                     # Scenario: 
    855                     # Same directory name, different entry key names. 
    856  
    857                     # Save the change. 
    858                     $change->{'key'} = $before_group; 
    859                     $change->{'status'} = "changed"; 
    860  
    861                     # If the after key name doesn't exist, or if the before key  
    862                     # name exists and the before name is alphabetically earlier 
    863                     # than the after key name... 
    864                     if (!defined($after_entry_name) || defined($before_entry_name) && 
    865                         $self->_cmpEntryName($before_entry_name, $after_entry_name) < 0) { 
    866  
    867                         # Then we know that the before key name got deleted 
    868                         # in the after file. 
    869                         # Check to see if some of this change data already exists... 
    870                         if (exists($change->{'entries'}->{$before_entry_name})) { 
    871  
    872                             # Sanity check: Looks like an earlier iteration populated 
    873                             # this change entry with a 'new_value'.  Let's make sure 
    874                             # the our 'old_value' and 'new_value' are truly different. 
    875                             if (defined($change->{'entries'}->{$before_entry_name}->{'new_value'}) && 
    876                                 ($change->{'entries'}->{$before_entry_name}->{'new_value'} ne 
    877                                  $before_entry_value)) { 
    878  
    879                                 # Okay, looks like they're different, so only update the old_value. 
    880                                 $change->{'entries'}->{$before_entry_name}->{'old_value'} = $before_entry_value; 
    881                             } else { 
    882                                 # Looks like they're the same value, so delete the entry completely. 
    883                                 delete($change->{'entries'}->{$before_entry_name}); 
    884                             } 
    885                         } else { 
    886                             # If not, then update both old_value and new_value. 
    887                             $change->{'entries'}->{$before_entry_name} = { 
    888                                 old_value => $before_entry_value, 
    889                                 new_value => undef, 
    890                             }; 
    891                         } 
    892  
    893                         # And get the next corresponding key/value pair from the before group. 
    894                         ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
    895  
    896                     # Else, the after key name exists but the corresponding before key name  
    897                     # did not exist -- which means that this is a new key/value pair. 
    898                     } else { 
    899  
    900                         # Check to see if some of this change data already exists... 
    901                         if (exists($change->{'entries'}->{$after_entry_name})) { 
    902                             # Sanity check: Looks like an earlier iteration populated 
    903                             # this change entry with an 'old_value'.  Let's make sure 
    904                             # the our 'old_value' and 'new_value' are truly different. 
    905                             if (defined($change->{'entries'}->{$after_entry_name}->{'old_value'}) && 
    906                                 ($change->{'entries'}->{$after_entry_name}->{'old_value'} ne 
    907                                  $after_entry_value)) { 
    908  
    909                                 # Okay, looks like they're different, so only update the new_value. 
    910                                 $change->{'entries'}->{$after_entry_name}->{'new_value'} = $after_entry_value; 
    911                             } else { 
    912                                 # Looks like they're the same value, so delete the entry completely. 
    913                                 delete($change->{'entries'}->{$after_entry_name}); 
    914                             } 
    915                         } else { 
    916                             # If not, then update both old_value and new_value. 
    917                             $change->{'entries'}->{$after_entry_name} = { 
    918                                 old_value => undef, 
    919                                 new_value => $after_entry_value, 
    920                             }; 
    921                         } 
    922  
    923                         # And get the next corresponding key/value pair from the after group. 
    924                         ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
    925                     } 
    926                 } 
    927             } 
    928  
    929             # Once we're out of the previous loop, then we are finished enumerating 
    930             # all key/value pairs corresponding to the identical group in either files. 
    931  
    932             # And get the next group to compare from both files. 
    933             $before_group = $self->_nextGroup($before_parser); 
    934             $after_group  = $self->_nextGroup($after_parser); 
    935  
    936         # Else, if the after group doesn't exist, or if the before group exists and the 
    937         # before group name is alphabetically earlier than the after group name... 
    938         } elsif (!defined($after_group) || defined($before_group) && 
    939                  $self->_cmpGroup($before_group, $after_group) < 0) { 
    940  
    941             # Get the length of the before group. 
    942             my $before_group_length = length($before_group); 
    943  
    944             # Scenario: 
    945             # Directory was deleted. 
    946  
    947             # Save the change. 
    948             $change->{'key'} = $before_group; 
    949             $change->{'status'} = "deleted"; 
    950             $change->{'entries'} = { }; 
    951  
    952             # Get the first key/value pair from this before group. 
    953             my ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
    954  
    955             # While there are key/values within this before group. 
    956             while (defined($before_entry_name)) { 
    957                 $change->{'entries'}->{$before_entry_name} = { 
    958                     old_value => $before_entry_value, 
    959                     new_value => undef, 
    960                 }; 
    961  
    962                 # And get the next corresponding key/value pair from the before group. 
    963                 ($before_entry_name, $before_entry_value) = $self->_nextVal($before_parser); 
    964             } 
    965  
    966             # Get the next group from the before file. 
    967             $before_group = $self->_nextGroup($before_parser); 
    968  
    969         # Else, the after group exists but the corresponding before group 
    970         # did not exist -- which means that this is a new group. 
    971         } else { 
    972             # Scenario: 
    973             # Directory was added. 
    974  
    975             # Save the change. 
    976             $change->{'key'} = $after_group; 
    977             $change->{'status'} = "added"; 
    978             $change->{'entries'} = { }; 
    979  
    980             # Get the first key/value pair from this after group. 
    981             my ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
    982  
    983             # While there are key/values within this after group. 
    984             while (defined($after_entry_name)) { 
    985  
    986                 $change->{'entries'}->{$after_entry_name} = { 
    987                     old_value => undef, 
    988                     new_value => $after_entry_value, 
    989                 }; 
    990  
    991                 # Get the next key/value pair from the after group. 
    992                 ($after_entry_name, $after_entry_value) = $self->_nextVal($after_parser); 
    993             } 
    994  
    995             # Get the next group from the after file. 
    996             $after_group = $self->_nextGroup($after_parser); 
    997         } 
    998  
    999         # Transform the 'entries' sub-key from a nested hash structure, 
    1000         # into an array of separate hashtables. 
    1001         if (exists($change->{'entries'})) { 
    1002             my $entries = [ ]; 
    1003             while (my ($key, $value) = each(%{$change->{'entries'}})) { 
    1004                 push (@{$entries}, { 
    1005                         name      => $key, 
    1006                         old_value => $value->{'old_value'}, 
    1007                         new_value => $value->{'new_value'}, 
    1008                 }); 
    1009             } 
    1010             $change->{'entries'} = $entries; 
    1011         } 
    1012  
    1013         # Push the change onto our array of changes. 
    1014         if (scalar(keys(%{$change}))) { 
    1015             push(@{$changes}, $change); 
    1016         } 
    1017     } 
    1018  
    1019     # TODO: delete this, eventually. 
    1020     print "Complete list: " . Dumper($changes) . "\n"; 
    1021     return $changes; 
    1022 } 
    10231077 
    102410781; 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry/Parser.pm

    r105 r112  
    102102use Carp (); 
    103103 
     104# Include Global Configuration Processing Library  
     105use HoneyClient::Util::Config qw(getVar); 
     106 
    104107# Include Logging Library 
    105108use Log::Log4perl qw(:easy); 
    106 # Temporarily Initialize Logging Subsystem 
    107 # XXX: We hard code the logging format here, since it appears that 
    108 #      calling 'use HoneyClient::Util::Config qw(getVar);' slows down 
    109 #      the parser by a factor of 10x (not sure why). 
    110 Log::Log4perl->init_once({ 
    111     "log4perl.rootLogger"                               => "INFO, Screen", 
    112     "log4perl.appender.Screen"                          => "Log::Log4perl::Appender::Screen", 
    113     "log4perl.appender.Screen.stderr"                   => 0, 
    114     "log4perl.appender.Screen.Threshold"                => "INFO", 
    115     "log4perl.appender.Screen.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
    116     "log4perl.appender.Screen.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
    117 }); 
    118  
    119109 
    120110# Use Dumper Library. 
     
    383373         'registry', 0, 
    384374sub 
    385 #line 257 "Parser.yp" 
     375#line 247 "Parser.yp" 
    386376{ 
    387377            $LOG->debug("Reached end of input stream."); 
     
    393383         'registry', 1, 
    394384sub 
    395 #line 262 "Parser.yp" 
     385#line 252 "Parser.yp" 
    396386{ 
    397387            $LOG->debug("Reached end of input stream."); 
     
    403393         'registry', 2, 
    404394sub 
    405 #line 267 "Parser.yp" 
     395#line 257 "Parser.yp" 
    406396{ 
    407397            $LOG->debug("Reached end of input stream."); 
     
    425415         'group', 2, 
    426416sub 
    427 #line 284 "Parser.yp" 
     417#line 274 "Parser.yp" 
    428418{ 
    429419            my $ret = { }; 
     
    444434         'group', 1, 
    445435sub 
    446 #line 298 "Parser.yp" 
     436#line 288 "Parser.yp" 
    447437{ 
    448438            my $ret = { }; 
     
    469459         'entry', 2, 
    470460sub 
    471 #line 322 "Parser.yp" 
     461#line 312 "Parser.yp" 
    472462{ 
    473463            my $entry = { 
     
    484474} 
    485475 
    486 #line 332 "Parser.yp" 
     476#line 322 "Parser.yp" 
    487477 
    488478 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry/Parser.yp

    r105 r112  
    8585use Carp (); 
    8686 
     87# Include Global Configuration Processing Library  
     88use HoneyClient::Util::Config qw(getVar); 
     89 
    8790# Include Logging Library 
    8891use Log::Log4perl qw(:easy); 
    89 # Temporarily Initialize Logging Subsystem 
    90 # XXX: We hard code the logging format here, since it appears that 
    91 #      calling 'use HoneyClient::Util::Config qw(getVar);' slows down 
    92 #      the parser by a factor of 10x (not sure why). 
    93 Log::Log4perl->init_once({ 
    94     "log4perl.rootLogger"                               => "INFO, Screen", 
    95     "log4perl.appender.Screen"                          => "Log::Log4perl::Appender::Screen", 
    96     "log4perl.appender.Screen.stderr"                   => 0, 
    97     "log4perl.appender.Screen.Threshold"                => "INFO", 
    98     "log4perl.appender.Screen.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
    99     "log4perl.appender.Screen.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
    100 }); 
    101  
    10292 
    10393# Use Dumper Library. 
  • honeyclient/branches/bug/42/t/honeyclient_agent_integrity_registry_parser.t

    r99 r112  
    6161use Fcntl qw(:seek); 
    6262 
     63# Make sure Search::Binary loads 
     64BEGIN { use_ok('Search::Binary') 
     65        or diag("Can't load Search::Binary package. Check to make sure the package library is correctly listed within the path."); } 
     66require_ok('Search::Binary'); 
     67can_ok('Search::Binary', 'binary_search'); 
     68use Search::Binary; 
     69 
     70# Make sure Term::ProgressBar loads 
     71BEGIN { use_ok('Term::ProgressBar') 
     72        or diag("Can't load Term::ProgressBar package. Check to make sure the package library is correctly listed within the path."); } 
     73require_ok('Term::ProgressBar'); 
     74use Term::ProgressBar; 
     75 
    6376# Make sure HoneyClient::Agent::Integrity::Registry::Parser loads 
    6477BEGIN { use_ok('HoneyClient::Agent::Integrity::Registry::Parser') 
     
    282295 
    283296 
     297# =begin testing 
     298{ 
     299my ($nextGroup, $expectedGroup); 
     300my $test_registry_file = $ENV{PWD} . "/" . getVar(name      => "registry_file", 
     301                                                  namespace => "HoneyClient::Agent::Integrity::Registry::Parser::Test"); 
     302 
     303# Create a generic Parser object, with test state data. 
     304my $parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file => $test_registry_file, index_groups => 1); 
     305 
     306$parser->seekToNearestGroup(absolute_offset => 84); 
     307 
     308# Verify Test Group #2 
     309$nextGroup = $parser->nextGroup(); 
     310$expectedGroup = { 
     311    key     => 'HKEY_CURRENT_USER\Testing Group 2', 
     312    entries => [ { 
     313        name  => '@', 
     314        value => '\\"Annoying=Value\\"', 
     315    }, { 
     316