Kebmans blogg

Perl-hack for å hacke terminalene i Fallout 3

Posted in Perl, Scripting, Spill by kebman on 16/07/2011

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 out :D
for my $i (0 .. $#letter_score ) {
    print "$list[$i]: $scores[$i]";
    if ($scores[$i] == $max) {
        print " <- best";
    }     
    print "\n";
}

Creative Commons License

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";
    }
}

Creative Commons License

Må også rette en stor takk til folkene på Stackoverflow.com som har gitt mye uvurderlig hjelp til prosjektet.

Legg igjen en kommentar

Fyll inn i feltene under, eller klikk på et ikon for å logge inn:

WordPress.com-logo

Du kommenterer med bruk av din WordPress.com konto. Logg ut / Endre )

Twitter picture

Du kommenterer med bruk av din Twitter konto. Logg ut / Endre )

Facebookbilde

Du kommenterer med bruk av din Facebook konto. Logg ut / Endre )

Google+ photo

Du kommenterer med bruk av din Google+ konto. Logg ut / Endre )

Kobler til %s

%d bloggers like this: