Perl-hack for å hacke terminalene i Fallout 3
Det er ikke bare vanskelig å hacke terminalene i spillet Fallout 3 – det er også tidkrevende. Selv om du leser en kjempebra tutorial – for eksempel denne FALLOUT 3: Hacking FAQ v1.2 av Dave Bosley – så kan det ta lang tid å hacke passordet til en terminal.
Men frykt ikke. Siden det er ferie har jeg programmert to Perl-scripts som du kan bruke til å korte ned tiden det tar å hacke en terminal betraktelig.
For å bruke scriptene må du for det ha Perl installert. Har du PC må du kanskje laste det ned, mens er du så heldig å ha Mac så er det allerede forhåndsinstallert. Deretter må du kopiere koden inn i hver sin tekstfil. Kall f.eks filene for bestcandidate.pl og shortenlist.pl.
Det første skriptet brukes til å finne det beste ordet å teste først. Dette gjøres ved å finne ut hvilket ord som har mest til felles med de andre. For å bruke skriptet må du skrive ned alle ordene som kommer på terminalskjermen i spillet. Så må du kopiere dem inn på riktig plass i scriptet. Deretter må du kjøre scriptet fra kommandolinjen din, ved å skrive inn perl bestcandidate.pl.
Her er det første scriptet:
#!/usr/bin/perl use strict; use warnings; # here's the list of candidate words my @list = qw( PARTNERSHIPS REPRIMANDING CIVILIZATION APPRECIATION CONVERSATION CIRCUMSTANCE PURIFICATION SECLUSIONIST CONSTRUCTION DISAPPEARING TRANSMISSION APPREHENSIVE ENCOUNTERING ); # end of the list of words it should be checked against # populate two dimensional array with the list, # so we can compare each letter with the other # letters on the same row more easily my $list_length = @list; my @words; for (my $i = 0; $i < $list_length; $i++) { my @letters = split(//, $list[$i]); my $letters_length = @letters; for (my $j = 0; $j < $letters_length; $j++) { $words[$i][$j] = $letters[$j]; } } # this gives a two-dimensional array like this: # @words = ( ["B", "A", "K", "E", "R"], # ["S", "A", "L", "E", "R"], # ["B", "A", "L", "E", "R"], # ["C", "A", "R", "E", "R"], # ["R", "U", "F", "F", "R"], # ); # now, on to find the word with most letters in # common with the other on the same row # add up the score for each letter in each word my $word_length = @words; my @letter_score; for my $i (0 .. $#words) { for my $j (0 .. $#{$words[$i]}) { for (my $k = 0; $k < $word_length; $k++) { if ($words[$i][$j] eq $words[$k][$j]) { $letter_score[$i][$j] += 1; } } $letter_score[$i][$j] -= 1; } } # sum each score up my @scores; for my $i (0 .. $#letter_score ) { for my $j (0 .. $#{$letter_score[$i]}) { $scores[$i] += $letter_score[$i][$j]; } } # find the highest score my $max = $scores[0]; foreach my $i (@scores[1 .. $#scores]) { if ($i > $max) { $max = $i; } } # and print it all outfor my $i (0 .. $#letter_score ) { print "$list[$i]: $scores[$i]"; if ($scores[$i] == $max) { print " <- best"; } print "\n"; }
Tester du det første scriptet uten å endre på innholdet, vil du få ut samme ord som i tutorialen til Bosley, nemlig APPRECIATION. I tutorialen kan du se at dette ordet har fire (4) av tolv mulige matches med det virkelige passordet (vist som 4/12 i spillet). Dette er viktig, fordi dette er ting vi må bruke for å korte ned listen av passordkandidater i det andre scriptet.
Det andre scriptet bruker du til å korte ned listen av mulige passordkandidater. Skriv inn ordet du testet på riktig plass, og pass på å få inn matchtallet på riktig plass. Kjør så scriptet fra kommandolinen, slik: perl shortenlist.pl
#!/usr/bin/perl use strict; use warnings; my $checkword = "APPRECIATION"; # the word to be checked my $match = 4; # equal to the match you got from testing your checkword my @checkletters = split(//, $checkword); # the list of words: my @wordlist = qw( PARTNERSHIPS REPRIMANDING CIVILIZATION APPRECIATION CONVERSATION CIRCUMSTANCE PURIFICATION SECLUSIONIST CONSTRUCTION DISAPPEARING TRANSMISSION APPREHENSIVE ENCOUNTERING ); # end of the list of words it should be checked against print "$checkword has $match letters in common with:\n"; # split the word into single characters into an array with regexp // foreach my $word (@wordlist) { next if $word eq $checkword; my @letters = split(//, $word); my $length = @letters; # determine how many letters to check my $eq_letters = 0; for (my $i = 0; $i < $length; $i++) { if ($letters[$i] eq $checkletters[$i]) { $eq_letters++; } } if ($eq_letters == $match) { print "$word\n"; } }
Må også rette en stor takk til folkene på Stackoverflow.com som har gitt mye uvurderlig hjelp til prosjektet.

skriv en kommentar