• Nie Znaleziono Wyników

Wykorzystanie skryptów programu EnCase Forensic w kryminalistycznych badaniach cyfrowych nośników danych

N/A
N/A
Protected

Academic year: 2021

Share "Wykorzystanie skryptów programu EnCase Forensic w kryminalistycznych badaniach cyfrowych nośników danych"

Copied!
22
0
0

Pełen tekst

(1)

mł.asp.PawełOlber

biegłyz zakresubadańinformatycz nychLaboratorium Kryminalistyczn egoKomendy Wojewódz k iej PolicjiwOlsztynie pawel.olber @ol.policja.gov.pl

W

ykorzystanie s

kryptów pr

ogramu

EnC

ase

F

orensic

w

k

ryminalistycznych

b

adaniach c

yfrowych

n

ośni ków

d

anych

Streszczenie

Celem niniejszej pracy jest przedstawienie użytkownikowi programu EnCase Forensic składni języka pro

-gramowania EnScript, umożliwiającego tworzenie własnych rozwiązań programistycznych, a także przed-stawienie możliwości jego wykorzystania w kryminalistycznych badaniach cyfrowych nośników danych.

W celu zrozumieniaomawianego zagadnienia opis elementów ww. języka programowania poparty został

praktycznymi, autorskimiprzykładami. Przykładyzamieszczone w niniejszej pracypozwalają na zrozumienie

kodu istniejących już skryptów, zawartych m.in. w tzw. dokumentacji EnCase API. Dokumentacja ta jest najlepszym źródłem pozwalającym na zdobycie szczegółowych informacji o klasach ww. języka progra-mowania, ich składowych i funkcjach. Poza ww. dokumentem, w sieci Internet znajduje się wiele aplikacji

tworzonych przez pasjonatów języka programowania EnScript, które ułatwiają pisaniewłasnych skryptów orazstanowiącenneźródłoinformacjiiinspiracji.Zaletąpoznania ww.językaprogramowania jestmożliwość

tworzenia własnych rozwiązań programistycznych, pozwalających na automatyzację realizowanych zadań

wykonywanych w ramach przeprowadzanych analizśledczych, co jest bardzo istotnym elementem w pracy informatykaśledczego.

Słowa kluczoweEnCase Forensic, EnCase API, EnScript

Wprowadzenie i cel pracy

Niniejsza publikacja zawiera omówienie języka pro

-gramowania EnScript zdefiniowanego w programie EnCase Forensic, który jest jednym z najbardziej ce-nionych naświecie programów z informatyki śledczej

(computer forensic). Przeprowadzone badania

doty-czące ww.językaprogramowania, opartesąw

szcze-gólności na pracy w programie EnCase Forensic, który ma wbudowane własne środowisko programistyczne oraz zawiera skrypty służące do automatyzacji

cza-sochłonnych analiz śledczych. Środowisko progra-mistyczne ww. programu jest bardzo proste i brakuje w nim wielu przydatnych funkcji służących do forma-towania kodu źródłowego. Dlatego też przykładowe

skrypty prezentujące składnię języka EnScript napi

-sane zostaną przy użyciu aplikacji Microsoft Visual

C++ Express skonfigurowanej w sposób umożliwia­ jący współdziałanie z programem EnCase. Program Microsoft Visual C++ Express pozwala na zachowanie czytelneji przejrzystej struktury tworzonych skryptów, co ułatwia ich analizę i zrozumienie oraz uniknięcie błędów programistycznych. Informacje dotyczące

PROBLEMY KRYMINALISTYKI 288(2) 2015

składni językaprogramowania EnScript zgromadzone

zostaną przede wszystkim w wyniku analizy kodów

źródłowych skryptów,zawartych w tzw. dokumentacji

API programu EnCase Forensic. Ponadto przeprowa-dzona zostanie analiza dostępnych w sieci Internet skryptów, które są tworzone przez pasjonatów ww.

języka programowania.

W pierwszejczęści artykułuprzedstawionezostaną

podstawowe informacje i pojęcia dotyczące języka

programowania EnScript. Następnie przedstawiony zostanie prosty program, który będzie punktem

wyj-ścia do tworzeniabardziej skomplikowanychaplikacji.

W dalszej kolejności wyjaśnione zostaną elementy

składni języka programowania EnScript, w

szczegól-ności podstawowe typy danych, zmienne złożone,

instrukcje sterujące, operacje na zmiennych, a także

zagadnienia dotyczące programowania obiektowego.

Na końcu przedstawionezostaną autorskie rozwiąza­

nia programistyczne, powstałe na potrzeby real

izowa-nych opinii kryminalistyczizowa-nych.

Celem starań podjętych przez autora jest omówie

-nie języka programowania EnScript zdefiniowanego w programie EnCase Forensic i przedstawienie jego

(2)

możliwości w kryminalistycznych badaniach cyfro-wych nośników danych. Informacje zawarte w publi-kacji powinny byćprzydatne dla osóbzajmującym się informatyką śledcząw tworzeniu autorskich narzędzi analitycznychsłużącychdo automatyzacjiczasochłon­ nych czynności wykonywanych w trakcie przeprowa-dzanych analiz. Przedmiotowa publikacja wydaje się o tyle istotna, że w resorcie brakuje specjalistycznych szkoleń dotyczącychomawianego zagadnienia.

EnScript - informacje podstawowe

EnScript jest obiektowym językiem programowania opartym naskładnidwóchjęzyków:C++ i Java. Język ten pozwala na automatyzację realizowanych zadań oraz uproszczenie wielu czasochłonnych czynności przeprowadzanych w trakcie wykonywanych analiz śledczych, takich jak np. wyszukiwanie i analizowanie konkretnych typów dokumentów, przetwarzanie oraz ekstrakcja danych zapisanych w różnego rodzaju pli-kach, tworzenie zbiorów zawierających funkcje skrótu itd. Korzystanie z tego języka programowania umoż­ liwia również przetwarzanie informacji wyselekcjono-wanych w wyniku przeprowadzonej analizy danych, które zostały dodane do zakładek (bookmarks) lub rekordów(records).

EnScript - składnia języka

Rozpoczęcie nauki tworzenia skryptów w języku EnScript wymaga zapoznaniaużytkownikaz podstawo-wymizagadnieniami orazterminologią dotyczącą pro-gramowania.W artykule omówione zostaną również: struktura programu, przebieg przetwarzania składo­ wych oraz funkcji programu. Poznanie ww. zagadnień jest bardzo istotne, ponieważ ułatwi użytkownikowi zrozumienie kodu źródłowegotworzonych przez niego aplikacji oraz pozwoli na skuteczną analizę istnieją­ cych już skryptów, m.in. domyślnie zdefiniowanych w programie EnCase orazdostępnychw sieci Internet.

Białeznaki

Białeznaki,tj. spacje,tabulatory oraz znaczniki no -wej linii, nie mająznaczenia w kodzie źródłowym isą ignorowane przez kompilator - program wykonujący kompilację, czyli tłumaczenie kodu źródłowego na językmaszynowy.

Komentarze

Dowolny fragment kodu źródłowego programu

może być objęty komentarzem. Komentarz jest całkowicie ignorowany przez kompilator, natomiast może byćprzydatny dla piszącego iczytającego kod. Komentarze stosowane są w celu opisu, wyjaśnienia pewnych fragmentów kodu programu, oddzielenia jednejczęści kodu od drugiej oraz oznaczania funkcji. Wjęzyku EnScript istniejądwadostępnesposoby ko-mentowania kodu: liniowe oraz blokowe.

Przykład: class MainClass {

void Main(CaseClass c) {

// Przykład komentarza li ni owego.

/*

Przykład komentarza blokowego,

którym można objąć wiel e linii .

*/

} }

Dyrektywainclude

Wjęzyku EnScript zapis inc/ude to tzw. dyrektywa - informacja o dołączeniu do kompilowanego pliku źródłowego zawartości wskazanego pliku o rozsze-rzeniu enscript,określanegojako biblioteka. Biblioteki zawierająfunkcje,z których można korzystaćw pliku źródłowym. Nazwę pliku podajesiębez rozszerzenia.

Przykład:

This script is a modification of "Sweep Enterprise" of EnCase V4.

Report alI bugs and queries to

techni cal s uppor t @gui dancesof t war e . com

////////////////////////////////////////////

*/

inclu de "GSI_Basi c"

include "GSI_SweepCaseLib"

include "GSI_Defa ultModules"

Dyrektywa typelib

Wjęzyku EnScript zapis typelib umożliwia dołącze­

nie do kompilowanego pliku źródłowego zawartości

wskazanego pliku, tzw. biblioteki pochodzącej z

ze-wnętrznejaplikacji, np. programów z pakietu Microsoft Office.

Przykład:

typelib Excel "Exce l.Sheet"

typelib Scripting "Scrip ting. Fi leSyst emObject"

#ifdef Excel class MainClass { void Main() { SystemClass::ClearConsole()j CreateExcel()j } void CreateExcel() { Excel::Application apPj

if (app.Create(» { app.SetVisible(t r ue)j

Excel::Workbooks books

=

app.Workbooks()j Excel::Workbook book

=

books.Add()j Excel::Sheets sheets

=

book.Worksheets()j Excel: :Wordsheet sheet = Excel: :Worksheet ~

::TypeCast ( s heet s .lt em( l » j Excel::Range cells

=

sheet.Cells()j AddTable(cells)j

AddPieChart(sheet)j }

(3)

Konsola

Konsola jest w rzeczywistości plikiem, którego za-wartość wyświetlanajest w oknie podglądu programu EnCase Forensic. Konsola dostępna jest po wciśnię­ ciuzakładki .Console"(dot. V6)lub zapomocąmenu: View -> Console (dot. V7) i umożliwia wyświetlanie wszelkiego rodzaju komunikatów oraz innych treści, np. informacji o przebiegudziałan iaprogramu. W celu wyświetlenia komunikatu w konsoli należy posłużyć siępoleceniem WriteUne().

Pierwszy program

Tradycyjne książki o programowaniu zaczynają naukęprogramowania od przedstawienia aplikacji wy-świetlającej w konsoli lub na ekranie monitora zdanie:

"Hello Wor/d".Tradycja ta zostanie zachowana także i w niniejszej publikacji. Pierwszy program będzie punktem wyjściado bardziejzłożonychaplikacji, które pozwolą zrozumieć składnię języka EnScript.

Przykład: class MainClass { void Main(CaseClass c) { Console.WriteLine("Hello Worl d") ; } } Wynik:

I

Hello World

Głównaklasa programu

Program napisany w języku EnScript jest zbiorem zmiennych, definicji i wywołań funkcji. Każdy skrypt utworzony w programie EnCase ma klasę o nazwie MainCIass, wewnątrzktórej znajduje sięfunkcja Main, przyjmującajako parametr zmienną typu CaseClass, która jest odpowiednikiem sprawy utworzonej przez użytkownika programu. Wewnątrz klasy głównej MainClass definiowane są pozostałe klasy i funkcje. Po uruchomieniu skryptu program EnCase lokalizuje obiekt typu MainClass i wywołuje jego konstruktor. Zagadnienia dotyczące konstruktorów przedstawione zostaną w dalszej części publikacji. Następnie

ww

.

obiektwywołuje funkcjęMain,która poprzedzona jest słowemkluczowym void. Oznacza to,żefunkcja ta nie zwraca żadnych danych. Na koniec program EnCase uruchamia destruktor klasy MainClass i ostatecznie usuwa obiekt klasy głównej. W tym miejscu program kończy działanie.

Pojęciezmiennej ipodstawowe typy danych Zmienna (variable) to miejsce w pamięci opera-cyjnej komputera przechowujące pojedynczą wartość określonego typu. Każda zmienna ma nazwę, dzięki której można siędo niejodwoływać. Przed pierwszym użyciem zmienną należy zadeklarować, a więc po-informować kompilator, że pod taką nazwą kryje się PROBLEMY KRYMINALISTYKI 288(2) 2015

zmienna danego typu. Składnia deklaracji zmiennej wygląda następująco:

I

typ nazwa_zmiennej

=

wartość_zmiennej;

Typokreślarodzaj informacji,jakiemożna

przecho-wywaćw zmiennej.Mogą to byćnp. liczby całkowite,

rzeczywiste, tekst (czyli łańcuchy znaków, strings). Nazwa zmiennejpowinna dobrze określaćjej znacze-nieispełniaćpewne kryteria.Otonajważniejszez nich: • nazwa zmiennej powinna być słowem lub

skró-tem,określającymjej przeznaczenie

• nazwamoże się składaćzmałychiwielkich liter, atakżecyfr i znakupodkreślenia. Należy pamię­ tać, że nazwa zmiennej nie może zaczynać się

od cyfry. W odróżnieniu od innychjęzyków pro-gramowania w nazwie zmiennej można używać

znaków narodowych, np. literćczyŹ.

JęzykEnScript obsługuje różnetypy danych natyw-nie,co oznacza,żekonwersjepomiędzyróżnymi typa-mi danych wykonywane sąautomatycznie orazużycie

danej określonego typu dopuszczalne jest w każdym

kontekście. Przykład: class MainClass {

void Main(CaseClass c) {

II

deklaracja zmiennej "i"

II

przypisanie wartości 1 do zmiennej int i

=

1;

II

wyświetlenie zawartości zmiennej "i"

Console.WriteLine("i

= "

+ i);

II

dodanie wartości 1 do uprzednio

II

zdefiniowanej zmiennej i

=

i + 1; Console.WriteLine("i

=

"

+ i); } } Wynik:

Podstawowe typy danych

Typy danych określają sposób użycia parruęci w programie. Określając typ danych, przekazuje się

kompilatorowi informację,jakutworzyć określony frag-ment pamięci, atakżew jaki sposób wykonać na nim operacje. Dane różnych typów różnią się szybkością

działania,rozmiarem zajmowanej pamięciioczywiście

funkcjonalnością, np. są dane, które wolno mnożyć

przez siebie, ale i takie, dla których operacja mnożenia

nie istnieje - choćbyteksty.

(4)

char

Zmienna typu char przechowuje jeden znak. Do zmiennejtego typu można przypisaćznaki UNICOOE

o kodach od O do 65535. Zmienne typu char mogą

być przypisane do zmiennych typu całkowitego int i odwrotnie, zmienne typu całkowitego mogą być

przypisane do zmiennych znakowych. W przypadk u

takiego zabieguEnScriptdokonujekonwersji znaków

zgodnie z kodowaniem ASCII. W kodzieASCII mała

litera "a" ma przypisanąwartość97.Gdy do zmiennej

typu char zostajeprzypisanyznak,to wrzeczywistości

jest on liczbą z zakresu od O do 255. Należy jednak

zdawać sobie sprawę z różn icy pomiędzy wartością

a znakiem,np.:5i ,,5" nie jest tym samym,ponieważ5

jestwartością,natomiast,,5"jest znakiemi mawartość

53, tak jak w przypadku litery"a", która mawartość97.

Przykład:

clas s Ma i nClas s {

voi d Mai n(CaseClass c) {

II

Przypisanie liczby 82 do zmiennej int

int i

=

82;

II

Wyświetlenie zawartości zmiennej 'i'

Cons ol e.Wr it eLin e ("i = " + i);

II

Przypisanie zmiennej 'i' do zmiennej

II

typu char

char a

=

i;

II

Wyświetlenie zawartości zmiennej 'a' Console. WriteL i ne("a

=

"

+ a);

II

Przypisanie znaku do zmiennej typu char

char b

=

'v';

II

Wyświetlenie zawartości zmiennej 'b' Console.WriteLine("b = " + b);

II

Przypisanie zmiennej 'b' do zmiennej 'j'

int j = b;

II

Wyświetlenie zawartości zmiennej 'j' Console. WriteLine("j

=

"

+ j) ; } } Wynik: i 82 a

=

R b

=

v j = 118 String

Zmienna typu String przechowuje ciągi znaków

(tekst), na których można wykonywać wiele operacji.

Ciągiznaków mogą byćzesobą łączone zapomocą

operatora,,+".

Przykład:

class MainCl ass {

void Main(Case Cla s s c) {

II

Usunięcie zawartości konsoli Sys t emC l ass: :Cl ea rConso le ( ) ;

II

Przypisanie wartoścido zmiennej 51 St r i ng 51 = "Hel lo";

II

Przypisanie wartoścido zmiennej s2 St r i ng s2

=

"

World";

II

Zmienna 51 uzyskuje wartość "Hello World"

51 = 51 + 52;

II

Zmienna 51 uzyskuje wartość "Hello World." 51

=

51 + ".";

II

Przejście do nowego wiersza

sI =sI + '\n';

II

Wyświetlenie wyników konsoli

Console.Write(sl);

}

}

Wynik:

I

Hello Wor Id.

Ciągi znaków mogą zawierać znaki specjalne.

W celu wykorzystaniaznaków specjalnych w tekście

należy posłużyćsięznakiemukośnika(backslash).Do

grupy znaków specjalnych zaliczamy: tabulator, uko

-śnik, pojedynczy cudzysłów, znak końcalinii.

Przykład:

class MainClass {

void Main(CaseClass c) {

SystemClass::ClearConsole();

String 51

=

"Tabul at or \t, ukośnik \\, ~

pojedynczy cudzys łów \", ~

znak końca linii. \n";

Console.Write(5 1) ;

} }

Wynik:

Tabulator , ukośnik \, pojedynczy cudzysłów

", znak końca lini i

Istnieje również możliwość umieszczeniawtekście

dodatkowych znaków specjalnychz tablicyUNICOOE,

np. znaku towarowego ®. Znak ten należy zapisać

z ukośnikiemw postaci szesnastkowe]'.

Tablica UNICODE dostępna jest m.in. pod adresem:

(5)

Przykład:

class MainClass {

void Main(CaseClass c) { SystemClass::ClearConsole()j

String si

=

"To jest znak towarowy: \xeeAE"j Console.Write(sl)j

String s2

=

"Litera alfabetu rosyjskiego: ~

\xe414"j Console.Write(s2)j

} }

Wynik:

To jest znak towarowy: ~ Litera alfabetu rosyjskiego:

A

Ponieważ wszystkie znaki w cudzysłowie są

zna-czące, w tym również białeznaki, niemożna wstawić

nowego wiersza wśrodku łańcucha.

Przykład:

class MainClass {

void Main(CaseClass c) { SystemClass::ClearConsole()j

II

Nieprawidłowy sposób

si

=

"To jest bardzo długi tekst,

którego nie można zapisywać w ten sposób. Próba uruchomienia skryptu zakończy się błędem" j

} }

Abypołączyćbardzodługie ciągiznaków, wystarczy

umieścić je w cudzysłowie, jeden pod drugim. Ciągi

znaków zostaną połączone w czasie kompilacji

pro-gramu. W przypadku bardzo długich ciągów znaków

nie należy używać operatora łączenia ,,+", ponieważ

spowoduje to niepotrzebne wydłużenie czasu

kompi-lacji programu.

Przykład:

class MainClass {

void Main(CaseClass c) { SystemClass::ClearConsole()j

II

Prawidłowe połączenie bardzo długich znaków

si

=

"To jest bardz o długi tekst, "

"kt ór y został zapisany prawidłowo. \n"

"Ur uchomi enie skryptu zakończy się sukcesem."j Console.WriteLine(sl)j

}

}

PROBLEMY KRYMINALISTYKI 288(2) 2015

Wynik:

To jest bardzo długi tekst, który został zapisany prawidłowo.

Uruchomienie skryptu zakończy się sukcesem.

Ciągi znaków mogą być traktowane jako

tabli-ca znaków i adresowane indywidualnie. Uwaga:

Indeksowanie tablicy odbywasięzawsze odO.Ostatni element ma indeks równy rozmiarowi tablicy - 1.

Przykład: class MainClass { void Main(CaseClass c) { SystemClass::ClearConsole()j String s

=

"12345678ge"j Console.Writeline("Pi erwotny ci ąg: " + s)j

II

Wyświetlenie liczby 1

Console.WriteLine("Pi erwszy znak ciągu: " + ~ s(e]

=

'X'j

II

Pusta linia

Console.WriteLine(" ") j

II

Wstawienie znaku

·

na pierwszą pozycję s(e]

=

·x·

j

II

s

=

X2345678ge

Console.WriteLine("Nowy ciąg: " + sj ;

Console.WriteLine("Pi erwot ny ci ą g: " + s)j

} }

Wynik:

Pierwotny ciąg: 12345678ge Pierwszy znak ciągu: 1 Nowy ciąg: X2345678ge Pierwszy znak ciągu: X

Numeryczne typy danych

W języku EnScript dostępnych jest siedem typów

numerycznych. Typy numeryczne mają stały rozmiar,

niezależnie od procesora i platformy. Część typów

numerycznych ma podobne nazwy, różnią się one

jedynie pierwszą literąu. Wjęzyku EnScript jest to tak

zwany modyfikator, przy użyciu którego można nieco

wpływać na zakres danych, które można zapisywać

w zmiennych. Modyfikator to nic innego jakokreślenie

różnych odmian jednego typu. Modyfikator u

okre-śla, że dany typ reprezentuje jedynie dane dodatnie.

Wszystkie numeryczne typy danych języka EnScript

zostały przedstawione w postaci tabelarycznej i

po-sortowane wg rozmiaru danych, jakie mogą

przecho-wywać(tab. 1).

(6)

Tabela 1 Zestawienie numerycznych typów danych

_.

Typ RozJ!ltar(B) Min. wartość Max. wartość

Short 2 -32768 32767 Ushort 2 O 65535 Int 4 -2147483648 2147483647 Uint 4 O 4294967295 Long 8 -9223372032559808513 9223372032559808512 Ulong 8 O 18446744065119617025

Double 8 -1.79*1E+308 1.79*1E+308

Przykład: class MainClass {

void Main(CaseClass c) {

II

Usunięcie zawartości konsoli SystemClass::ClearConsole()j

II

Zmienna typu short

short short_min_value -32768j

short short_max_value

=

32767j

Console. WriteLine("Min. wart. zmiennej typu (j)

'short' wynosi: 00 + short_min_value)j

Console .WriteLine(ooMax. wart. zmiennej typu (j)

'short' wynosi: 00 + short_max_value)j

Console.WriteLine(OO - - - --- - -- - - -- -OO)j

II

Zmienna typu ushort ushort ushort_min_value

=

ej ushort ushort_max_value

=

65535j

Console.WriteLine("Mi n. wart. zmienn ej typu (j)

'us hort' wynosi: " + ushort_min_value)j

Console.WriteLine(OOMax. wart. zmi ennej typu (j)

'ushort' wynosi: " + ushort_max_value)j

Console.WriteLine("--- - -- - --- --- - - --- - - - - OO)j

II

Zmienna typu int

int int_min_value -2147483648j

int int_max_value

=

2147483647j

Console.WriteLine(OO Mi n. wart . zmiennej typu (j)

'int' wynosi: " + int_min_value)j

Console.WriteLine(OO Max. wart. zmiennej typu (j)

'int' wynosi: 00 + int_max_value)j

Console.WriteLine(" - -- ---- - - -- - --- - - --- - -- -")j

II

Zmienna typu unit unit unit_min_value ej

unit unit_max_value

=

4294967295j

Console. WriteLine("Min. wart . zmiennej typu (j)

'unit' wynosi : " + unit_min_value)j

Console.WriteLine("Max . wart. zmiennej typu (j)

'uni t ' wynosi : 00 + unit_max_value)j

Console.WriteLine(OO--- -- - - -- -- - - - ---- -- --OO)j

Wynik:

Min. wart. zmiennej typu 'shorf' wynosi: -32768 Max. wart. zmiennej typu 'short' wynosi: 32767 Min. wart. zmiennej typu 'ushort' wynosi: e Max. wart. zmiennej typu 'ushort' wynosi: 65535 Min. wart. zmiennej typu 'int' wynosi:

-2147483648

Max. wart. zmiennej typu 'int' wynosi: 2147483647

Min. wart. zmiennej typu 'uint' wynosi: e Max. wart. zmiennej typu 'uint' wynosi: 4294967295

void

Ten specjalny, tzw. pusty, typ danych używanyjest do wskazania,żefunkcja nie zwracażadnegowyniku.

Przykładzastosowania ww. typu został również przed-stawiony podczas omawiania funkcji.

Przykład:

class MainClass {

void Main(CaseClass c) {

II

Usunięcie zawartości konsoli SystemClass::ClearConsole()j

II

Wywołanie funkcji NoData()j

NoData()j

II

Wywołanie funkcji ReturnData()

II

i przypisanie zwróconej wartości do

II

zmiennej 'text'

String test

=

ReturnData()j Console.WriteLine(text)j

}

} }

Console.WriteLine(sl)j

II

II

wartościFunkcja typu void - nie zwraca żadnych void NoDataO {

Console.WriteLine(OO Funkcj a NoReturn() nie (j) zwraca żad n ej wartoś ci . ") j

(7)

II

Funkcja typu String - zwraca tekst

String ReturnData(){

String msg

=

"Funkcja ReturnData() zwraca ~ wartość zmiennej typu String.";

return msg; }

}

Wynik:

Funkcja NoReturn() nie zwraca żadnej wartości.

Funkcja ReturnData() zwraca wartość zmiennej typu String.

variant

Zmienna typuvariantprzechowuje dane dowolnego typu. Zawiera również odniesienie do obiektu repre-zentującego przypisaną wartość, który jest dostępny zapomocąfunkcji TypeO.

Przykład: class MainClass {

void Main(CaseClass c) {

II

Usunięcie zawartości konsoli

SystemClass::ClearConsole();

II

Deklaracja zmiennych typu variant

variant vl

=

"Witaj", v2

=

lee,

v3

=

2.5;

Console.WriteLine("Zmi enna typu " ~

+ vl. TypeO .NameO + " " + vl); Console. WriteLine("Zmienna typu " ~

+ v2.TypeO.NameO + " " + v2); Console.WriteLine("Zmi enna typu " ~

+ v3. TypeO . Name O + " " + v3);

}

}

Wynik:

Zmienna typu String

=

Witaj Zmienna typu int =

lee

Zmienna typu doubLe

=

2,5

bool

Najprostszym, ale bardzoczęsto używanym typem danych jest typ logiczny. Do jegookreślenia służy sło­ wo kluczowe bool(skrót od Boolean - boole'owski, logiczny). Do zmiennej typu logicznego możemy

przy-pisać wyłącznie wartośćtrue(1) lubfalse (O).Zmienną

tego typu najczęściej stosuje się do określenia, czy jest coś włączone czy wyłączone, prawdziwe lub fałszywe.

PROBLEMY KRYMINALISTYKI 288(2) 2015

Przykład: class MainClass {

II

Metoda, która zmienia wartość

II

zmiennej 'b' na false void Zmien(bool &b) {

b

=

false;

}

void Main() {

II

Klasa Main

II

Usunięcie zawartości konsoli

SystemClass::ClearConsole();

II

Przypisanie wartości 'true' do zmiennej b bool b

=

true;

Console. WriteLine(" Wa rt o ś ć zmniennej ~

logicznej b

=

"

+ b);

Zmien(b);

II

Zmiana wartości zmiennej 'b' Console.WriteLine(" Wa rto ś ć zmniennej b ~

po zmianie: " + b);

II

Jeżeli warunek jest prawdziwy zostanie

II

wyświetlony komunikat

i f (b

==

9) {

Console.WriteLine("War unek 'b

=

e'

jest ~

prawdziwy") ; }

} }

Wynik:

Wartość zmiennej logicznej b = 1

Wartość zmiennej b po zmianie:

e

Warunek 'b

=

e' jest prawdziwy

Zmiennezłożone

Typ wyliczeniowy

Wyliczeniowy typ danych umożliwia powiązanie

nazw z liczbami. Wyliczenie deklaruje sięza pomocą słowa kluczowego enum (pochodzącego zjęzyka C),

które automatycznie numeruje listę stałych, nadając

imwartości:O, 1,2 itd.Deklaracja typu wyliczeniowe-go przypomina deklaracjęstruktury.

I

enum nazwa_typu (

staŁa_l

[ =

wartość],

...J

Domyślna wartość pierwszej stałej w zbiorze typu wyliczeniowego wynosi O. Wartość każdej następnej stałej przyjmujewartość większąo 1 odwartości stałej poprzedzającej. Każdazestałych może zostać zdefi-niowana z określoną wartością. Jeżeli któraśz

warto-ści nie zostanie podana, to zostanie ona wyliczona na podstawie wartościpoprzedniej.

(8)

Nazwa stałej: Jeden

Nazwa stałej: Dwa

Nazwa stałej: Trzy

Nazwa stałej: Cztery

Nazwa stałej: Pięć

Wynik: } }

Console.WriteLine("Nazwa stałej: " ~

+ LiczbY::SourceText(28»j

Console.WriteLine("Nazwa stałej: " ~

+ Liczby::SourceText(21»j

Console .WriteLine("Nazwa stałej: " ~

+ Liczby::SourceText(38»j

=

8

=

1 28 21 38

II

Wartość

II

Wartość

II

Wartość

II

Wartość =

II

Wartość =

II

Deklaracja typu wyliczeniowego

enum Liczby {

II

Nazwy stałych Jeden, Dwa, Trzy = 28, Cztery, Pięć = Trzy + 18 } Przykład: void Main(CaseClass c) {

II

Usunięcie zawartości konsoli

SystemClass::ClearConsole()j class MainClass { Console.WriteLine(" Wa rtoś ć = " ~ + Liczby::Jeden)j Console.WriteLine(" Wa rt o ś ć = " ~ + Liczby: :Dwa)j Console.WriteLine(" Wa rt o ś ć = " ~ + Liczby:: Trzy) j

Console. WriteLine("Wartość = " ~

+ Liczby::CzterY)j

Console.WriteLine(" Wa rto ś ć = " ~

+ Liczby::Pięć)j

Tablice

Tablica jest strukturą złożoną z określonej liczby elementów tego samego typu. Wszystkie elementy tablicy umieszczanesą w pamięci komputera razem w jednym miejscu i do każdego elementu można odwołać się za pomocą nazwy tablicy oraz indeksu

określającegonumer danego elementu.

} } Wynik: Wartość = 8 Wartość =1 Wartość = 28 Wartość

=

21 Wartość = 38

Tablicę tworzy się za pomocą słowa kluczowe-go typedef, po którym określa się rodzaj danych przechowywanych w tablicy. Po utworzeniu tablicy

można zadeklarować oraz zainicjować zmienną typu tablicowego.

typedef typ_tabLicy StringArrayj Nazwę stałejtypu wyliczeniowegomożna uzyskać

poprzez jej wartość. W tym celu należy posłużyć się statyczną funkcjąo nazwie souroetexu).

Przykład: Przykład: class MainClass { void Main(CaseClass c) { class MainClass { enum Liczby { Jeden, Dwa, Trzy

=

28, Cztery, Pięć

=

Trzy + 18 }

II

Wartość = 8

II

Wartość

=

1

II

Wartość = 28

II

Wartość 21

II

Wartość =38

II

Utworzenie dwóch tablic typedef String[] StringArrayj

typedef int[ ] IntArrayj

void Main(CaseClass c) {

II

Deklaracja zmniennej tablicowej 'nazwisko'

StringArray nazwisko(3)j

I

I

Przypisanie wartości nazwisko[8] "Kowalski"j nazwisko[l] = "Nowak"j nazwisko[2] = "Mikulski"j

II

Us u n i ę c i e zawartości konsoli SystemClass::ClearConsole()j

Console.WriteLine("Nazwa stałej: u ~

+ Liczby::SourceText(8»j

Console.WriteLine("Nazwa st a ł ej : " ~

+ Liczby::SourceText(l»j

II

Deklaracja zmniennej tablicowej 'l i czba'

IntArray liczba(3)j

II

Przypisanie wartości

liczba[8] = 1j

liczba [1] 2j

(9)

"

II

Wyświetlenie zawartości tablicy foreach (String,s in nazwisko){

Console. Writeline (s); , }

Console.WriteLinę(U lic zba [ 2 ] u + liczba[il); }

}

Wynik:

o

1 2

5

Istnieje możliwość inicjalizacji tablicy

w

momencie jej deklaracji. Po nazwie tablicy należy w nawiasach klamrowych ({}) podać wariośĆ kolęjnych elementów tablicy. Na podstawie liczbywartości inicjalizujących ko.mpilatorautomatyczhiezdefiniuje rozmiar,tablicy.

Przy/cład:

class MainClass {

II

Utworienie tablicy

typedef St r i ng[ ] StringArray';

void Main(CaseClass c) {

II Deklaracja zmniennej tablicowej

II

Inicjalizacja zmniennej

StringArray nazwisko,{UKowalskiuJ "NowakuJ '~ UMikulskiu; } '

II Wyświetlenie zawartościtablicy fóreach(Strings in nazwisko) { ,Console. WriteLine( s); " } } } Wynik: Tablice wielowymiarowe

Wjęzyku EnScripfmożna utworzyć tablicęznacznie'

bardziejzłożoną- naprzykład tablicę,dwuwymlarową,

którą można grafi.cznią zobrazować IN następiJjący

~~~~ .

PROBL.ENI'YKRYMINALISTYKI28~(21.2015

Tablip§l, dwuwymiarowa zostanie utworzona za

pomocą instl1lkcjisterującej foreach, którazostahte

ornówiońa w dalszej części, pracy: Rbtmia"rtablicy

dwuwymiaroweiokreślany jest przez'liczbę' wiersży

i kolumn. " '

Przykład:

class MainC1ass {

II

Utworzenie tablicy

typedef int[ l IntArray;

II

Utworzenie zmienhej tablicowej 'multiArray'

typedef IntArra~[lmultiArray;

void Maii1(CaseClass c) {

II

Określenie rozmiaru tabel i multiArray m(2);

II

Utworzenie,trzech tabel, kolejno wkażdej

II

'

komórce tabeli 'mul t i Ar r ay '

II Wynik: powstanie tablicy dwuwymiarowej

foreach (IntArraya in m) ,{ a,

=

new IntArray(2); "

} " '

II Inicjalizacja tabeli dwuwymiarowej

m[e] [e] = '1 ; m[e][l] ='2; m[l][e] = 3; m[l][l] == 4; int Index = ej drugiIndex= e;

Il ,Wyświetlęnie zawartoŚci tabeli foreach (IntArray a in,m) {

,I i'ldex =e;

foreach (int i in a)

Cóns~le.WriteLine C\tm [ U + Index + U][U <p. + drugiIndex + U] = U+

i);

drugiIhdex++~ } Index++; '} } , Wynik: 23

(10)

Przykład:

while (i< le) {

I

I

Sprawdzenie warunku

int i

=

ej

II

Deklaracja zmiennej 'i'

class MainClass { void Main(CaseClass c) {

II

Instrukcja Wynik: Console.Write(i + " n) ; i++j } } }

(warunek) zwróci wartośćfa/se. Składnia

ww.

instrukcji jestnastępująca:

I

whiLe (warunek) instrukcja

Instrukcjesterujące

Wkażdym językuprogramowaniaistniejąinstrukcje pozwalającenasterowanie wykonywaniem programu. Instrukcje wykorzystuje sięprzy podejmowaniudecy-zji. Koniecznośćstosowania instrukcji wynikastąd,.że kodowane algorytmy tylko w prostychprzypadkachsą czysto sekwencyjne, wykonywane linia po linii w

kolej-ności ich występowania. Bardzo często kolejne kroki

algorytmusą zależneodspełnieniapewnego warunku lub kilku warunków.

Instrukcja warunkowaif

Instrukcja jfpozwala wykonać kod programu tylko wtedy, gdyspełnionyjestokreślonywarunek.Działanie

ww.instrukcji sprowadzasię więcdo sprawdzenia wa-runku i,jeśli zostanie stwierdzona jego prawdziwość, wykonania wskazanego bloku kodu.Dziękipewnej mo-dyfikacji instrukcji jfmożliwejest określenie poleceń, które zostaną wykonane, gdy warunek nie zostanie spełniony. Taką zmodyfikowaną instrukcjęwarunkową

określa sięjako jf•••e/s.e. Najprostsza forma instrukcji

ifwygląda następująco:

Przykład:

class MainClass {

void Main(CaseClass c) {

I

I

Deklara cj a zmiennej 'a'

int s

=

2;

II

Dekl aracj a zmiennej 's'

String s

=

"Wi t aj";

Instrukcjado ••• while

Instrukcja do... whi/e jest modyfikacją

ww.

pętli

whi/e.Różnica to moment sprawdzania warunku pętli

- wpętli

white,

warunek jest sprawdzany napoczątku, w pętlido... while - nakońcu. Pętlado..,whj/e wyko-na zawsze co wyko-najmniej jeden przebieg. SkładniawW.

instrukcji jestnastępująca:

II

Je ś l i 'a' wykonaj ins t ru k c j ę

i f (a)

console'. WriteLine("Wartość zmiennej 4)

'a' równa się 2") ;

II

Jeśli 's' wykonaj instruk cję i f (s) Console,WriteLine(s)j Przykład: class MainClass { void Main(CaseClass c) { Console.Write(i + " O); i--j . if (a

==

3)

II

Jeśli 'a'

=

3 Console.WriteLine(s);

else { I I w przeciwnym razi e Console.WriteLine(" Wartoś ć zmiennej 4)

'a' jest rói na od 3") ; } } } int i

=

lej do { } while (i >e);

II

Deklaracja zmiennej 'i'

I

I

Instrukcja II Sprawd zenie warunku Wynik:

Instrukcjawhile

Instrukcja whilejest blokiem instrukcji, które wyko-nywane są aż do momentu, gdy wyrażenie kontrolne

. }

}

(11)

Instrukcja for

Instrukcja for łączy w sobie trzy działania pętli: inicjalizację (poprzedzającą pierwszą iterację), spraw-dzenie warunku oraz zmianę wartości. Pierwsza instrukcja to inicjalizacja zmiennej kontrolującej wyko-nywanie pętli. Druga instrukcja to sprawdzenie warun-ku. Trzecia instrukcja to akcja - zazwyczaj umieszcza

się tu inkrementację (++) albo dekrementację (--)

zmiennej kontrolującej pętle. Składnia ww. instrukcji jest następująca:

for (inicjaLizacja; warunek; krok) instrukcja; Przykład: class MainClass { void Main(CaseClass c) { for (i nt i

=

0; i < 10; i++) { Console.Write(i + "") ; II Instrukcja } } } Wynik:

I

e

12 3 4 S 6 7 8 9 Instrukcjaforeach

Instrukcja foreach pozwala na sekwencyjne

prze-glądanie różnych zbiorów danych, np.: tablic, list.

Składnia ww. instrukcji jestnastępująca:

foreach (typ_eLementu nazwa in koLekcja) instrukcja

Przykład:

class MainClass {

enum Tydzień { II Wyliczeniowy typ danych

Poniedziałek = 1; Wtorek, Środa, Czwartek, Piątek, Sobota, Niedziela } void Main(CaseClass c) {

foreach (Tydzień d) { II Pętla foreach Console.WriteLine(Tydzień::SourceText(d)~ + Ił

=

+ d)j } } } PROBLEMY KRYMINALISTYKI 288(2) 2015 Wynik: Poniedziałek

=

1 Wtorek

=

2 Środa

=

3 Czwartek

=

4 Piątek

=

S Sobota = 6 Niedziela

=

7 Instrukcjaforali

Instrukcja foralI pozwala na sekwencyjne przeglą­

danieróżnychzbiorów danych,podobnie jak instrukcja

foreach. Różnica pomiędzy

ww

.

instrukcjamiwystępu­ je podczas przetwarzania zbiorów danych w postaci struktury drzewa, które w języku programowania EnScriptsą obiektami NodeClass. Działanieinstrukcji

foralI zostanie przedstawione w dalszej części pracy, podczas omawiania różnic w języku EnScript zdefi-niowanego w wersji 6 i 7 programu EnCase.Składnia

instrukcji foralI jest następująca:

foraLL (typ_eLementu nazwa in kpLekcja) instrukcja

Instrukcje:break, continue

Wewnątrz dowolnej konstrukcji tworzącej pętlę,

można sterowaćjej przebiegiem za pomocąinstrukcji

break i continue. Instrukcja break powoduje opusz-czenie pętli, bez wykonywania pozostałych zawar-tych w niej instrukcji. Natomiast instrukcja continue zatrzymuje wykonanie aktualnej iteracji, powodując

powrót do początku pętli w celu rozpoczęcia nowej iteracji. PrzYk,ład: class MainClass { void Main(CaseClass c) { for (i nt i = 1; i < 11; i++) { Console.WriteLine(i); if (i

==

4) {

Console.WriteLine("Zat r zymani e bie~ącej ~

iteracji i powrót do początku") ;

continue;

}

if (i

==

6) {

Console.WriteLine(" Pęt l a została ~

przerwana i dalsze cyfry: 7,8,9,10 ~

nie zostaną wyświetlone") ;

break; } } } } 25

(12)

Operacje na zmiennych

Operacje na zmiennych dokonywane są przy uży­

cłuoperatorów. Operator działa na jednym lub kilku

argumentach, a wynikiem jego działaniajest zupełnie

nowawartość:Argumentymają inną postać niż zwykłe

wywołaniafunkcji, alerezultat jest wobu przypadkach

taki sam. Operatory wjęzyku EnScript można

podzie-lićna dwie grupy zewzględunaliczbęargumentów, na których działają. Wyróżnia się więc operatory unarne

- wymagające jednego argumentu - oraz binarne

-wymagającedwóch.arqurrtentów,

Operatoryuilarne

Operatory unarne występujące w języku progra-mowania EnScript, przedstawione zostanąw formie tabeli. Regułąjest, żeoperatory te znajdują się przed

wyrażeniem. Wyjątek stanowią opęratory ,,++" i ,,__", które również mogą występowaćpowyrażeniu.

Wynik: iteracji i powrótj:l() Wynik:

I

Zmienna 'liczba' ,4 Przykład: class MainClass { void Main(Casetlass c) { int liczba = 4; switch( l i czba) {

case

e:

Console.Write("Zmi enna ma wartość:

e"

);

break; case 1: C6nsol~.Write(" Zm i e nn a

ma wartość: 1") ; break; case 2: Console.Write("Zmi enna

ma wartość: 2") ; break; case 3: Console.Write("Zmi enna

ma wartość: 3") ; break;

~a s e 4: C6nsole.Write("Zmi enna ma wartość: 4") ; b r ~ a k ; } } } 'liczba' <Jj 'liczba' <Jj 'liczba' <Jj 'liczba' <) 'liczba' <Jj

Tabela 2 Zestawienieoperatorówunarnych

Operator Qpi~

.

--New' Tworzenienowego~obiektu

typeofO Określenie typu,obiektu

! Negacja logiczna - zwracazanegowaną.

wę.rtąśę WYr~eni~ .

", "',,' !, ++ Inkrementacja - zwięksiawartość

zmiennej

Dekrementacja - zmniejszawartość

zmiennej

-

wyrażeniaUnarńyminus-służydo zmianyinaku

~. Negacja bitowa - zwracazmienną

z zanegowanymibitami Operatory binarne

Operatory binarne występujące w języku proqra-mowania EnScript, również przedstawione zostaną w formie tabeli. Operatory binarne występują pomię­

dzy wyrażeniami. Operatory binarne można podzielić

na operatory: arytmetyczne, bitowe, logiczne, relacji, przypisania oraz zasięgu.

Tabela 3 Zestawienie operatorówzasięgu

'Operator

."

Opis

Dereterencla,czyliwyłuskanie,uzyskanie ,dostępu dąpe'v'łnej ~~~C?$.9i ' .

.

.

Służydouzyskaniadostępudo funkcji

..

(13)

Tabela 4 Zestawienie operatorów arytmetycznych Operator I' Opis + Dodawanie

-

Odejmowanie * Mnożenie / Dzielenie

% Operator reszty z dzielenia

Tabela 5 Zestawienie operatorów bitowych

Operator Opis

« Przesunięciebitowe w lewo

» Przesunięciebitowe w prawo

&

Iloczyn bitowy

1\ Różnicabitowa

1 Suma bitowa

Tabela 6 Zestawienie operatorów logicznych

Operator Opis

&&

Iloczyn logiczny II Suma logiczna

Tabela 7 Zestawienie operatorów relacji

Operator Opis

< Oznacza: mniejsze od ...

> Oznacza:większeod ...

<= Oznacza: mniejsze lub równe z... >= Oznacza:większelub równe z...

--

Oznacza: równe z...

1= Oznacza:różneod ...

Tabela 8 Zestawienie operatorów przypisania

Operator Opis

= Przypwartość wyrażeniaisujezmiennej po lewej stronieprawej strony *=

/= %=

+=

-= Służądo skrócenia zapisu operacji, które

można zapisaćprzyużyciuoperatorów

«= arytmetycznych oraz bitowych »= &= 1\= 1= PROBLEMY KRYMINALISTYKI 288(2) 2015 Programowanie obiektowe

Każdy program (skrypt) programu EnCaseskłada się z jednej lub wielu klas. W dotychczasowych

przy-kładach byłato tylko jedna klasa o nazwieMainCIass.

class MainClass {

void Main(CaseClass c) {

Console.WriteLine("Hello Wor ld") ;

} }

Klasy

Klasy są opisami obiektów, czyli bytów progra-mistycznych, które mogą przechowywać dane oraz

wykonywać polecone przez programistę zadania. Schematyczny szkielet klasywygląda następująco:

cLass nazwa_kLasy {

l/treść kLasy

}

Obiekt, któryzostał stworzony na podstawie danej klasy nazywany jest jej instancją. Obiekt tworzy się

przy użyciu operatora

new.

Klasa jest jak gdyby

ma-trycą służącą do tworzenia obiektów. Informuje ona

wirtualną maszynę, jak należy utworzyć obiekt kon-kretnego typu. Każdy obiekt utworzony na podstawie klasy może mieć unikalne wartości składowych. Na

przykład można użyć klasy o nazwie Pies, do stwo-rzenia kilku różnych obiektów, z którychkażdy będzie

np. innej rasy.

Przykład:

class MainClass {

void Main(CaseClass c) {

IlUtworzenie nowych obiektów typu Pies

Pies pies_l

=

new Pies () ;

Pies pies_2

=

new Pies

O;

Pies pies_3

=

new PiesO;

II Składowe obiektów - informacje o obiektach

pies_l.wielkość

=

58;

pies_l. rasa

=

"Husky";

pies_l. nazwa = "Bor ys ";

pies_2.wielkość

=

48;

pies_2.rasa

=

"Bokser";

pies_2.nazwa

=

"Kol ec";

pies_3.wielkość

=

38;

pies_3.rasa

=

"Beagle";

pies_3.nazwa

=

"Rewin";

}

II Utworzenie klasy 'Pies'

class Pies { int wielkość; String rasa; String nazwa; } } 27

(14)

Powyższy przykładzawiera trzy zmienne referen-cyjne o nazwach: pies_1, pies_2 i pies_3 . Zmienne referencyjne zawierają bity reprezentujące sposób dotarcia do danego obiektu. Można użyć operatora kropki (.) wraz zezmienną referencyjną, aby uzyskać

dostęp do składowych obiektu. Użycie operatora

kropkiwraz zezmiennąreferencyjnąmożna wyobrazić sobie jako naciskanie przyciskuna pilocie sterującym konkretnym obiektem.

Funkcje

Klasy,oprócz pól przechowującychdane,zawierają

także funkcje, które wykonują zapisane przez

pro-gramistę operacje. Funkcjemogą modyfikować dane

i zwracać różne wartości. Wywołanie funkcji polega

na wpisaniu jej nazwy w programie. W momencie napotkania wywołania funkcji program przechodzi do wykonania kodu funkcji. Kiedy funkcja się kończy,

program wraca do miejsca jej wywołania. Składnia deklaracji funkcjiwygląda następująco:

typ nazwa (dekLaracja argumentów) {

instrukcje; }

Przykład: cIa ss MainClass {

II

Deklaracja pierwszej funkcji bezargumentowej

void Wyświetl() {

Console.WriteLine("Hel l o World") ;

}

II

Deklaracja drugiej funkcji z argumentem

void PobierzTekst(String text) {

Console.WriteLine(text); }

II

Deklaracja trzeciej funkcji z 2 argumentami

II

zwracająca wartość całkowitą

int Suma(i nt a, int b){

int c

=

a + bj return Cj }

void Main(CaseClass c){ IIFunkcja główna 'Main'

II

Wywołanie kolejno wszystkich funkcji

Wyświetl()j

PobierzTekst("Tekst prz ekazywa ny do funkcj i ~

jako argument") j int d

=

Suma(3,7)j Console.WriteLine(d)j } } Wynik: Hello World

Tekst przekazany do funkcji jako argument 10

Funkcje określają również czynności, jakie obiekt jest w staniewykonać.

Przykład: class MainClass {

void Main(CaseClass c) {

IlUtworzenie obieku

Pies pies_l

=

new Pies();

II

Składowe obiektu - informacje

pies_l.wielkość

=

S0j

pies_l. rasa

=

"HuskY"j

pies_l. nazwa

=

"Borys "j

pies_l.szczekaj()j }

II

Utworzenie klasy 'Pies'

class Pies { int wielkość;

String rasa; String nazwaj

II

Funkcja - zachowanie obiektu

void szczekaj() {

Console.WriteLine("Hau! Hau!") j

} } } Wynik:

I

Hau! Hau! Funkcje statyczne

Funkcjeskładowe klasy mogą być zadeklarowane jako statyczne. Funkcje temożna wywołaćnawet wte-dy, gdy nie istnieje jeszczeżadenobiekt klasy. Do na-zwy klasy statycznej odwołujemy się poprzez nazwę tej klasy oraz operatora zasięgu (::).Słowo kluczowe

stafie pozwala wywoływać funkcję bez konieczności

posługiwania sięobiektem tej klasy.Funkcja statyczna

umożliwia działanie, które niezależy od składowych,

a zatem nie wymagaużyciaobiektu. Przykład:

class MathClass {

II

Klasa MathClass

II

Definicja funkcji statycznej

static lon g Potęga(l o ng x) { return x

*

Xj

} }

class MainClass {

void Main(CaseClass c) {

II

Wywołanie funkcji statycznej

Console. WriteLine("5 do potęg i 2

=

"

~

+ MathClass::Potęga(S»j

} }

(15)

Wynik:

S do potęgi 2

=

25

Konstruktor

Konstruktor jest specjalną funkcją wykonywaną podczas tworzenia obiektu. Konstruktor zawiera kod, który zostaje wykonany w momencie użycia operato-ra new. Innymi słowy, konstruktor zawiera instrukcje wykonywane w momencie tworzenia nowego obiektu. Funkcja będąca konstruktorem nigdy nie zwraca żad­ nego wynikuimusimieć nazwę zgodnąznazwąklasy.

cLass nazwa_kLasy { nazwa_kLasy(){

II kod konstruktora

} }

Każda tworzona klasa ma konstruktor, nawet jeśli nie zostanie on napisany przez programistę. W takim przypadku konstruktor zostanie stworzony przez kom-pilator. Podstawową cechąkonstruktora jest to, iżjest on wykonywany, zanim obiekt zostanie skojarzony z odwołaniem. Wwiększości przypadków konstruktor używany jest do inicjalizacji stanu obiektu, czyli do określenia wartościjegoskładowych.

Przykład:

class MainClass {

void Main(CaseClass c) {

IlUtworzenie obieku

Pies pies_l

=

new Pies ();

II

Wyświetlenie cech obiektu

Console.WriteLine(pies_l.wielkość); Console.WriteLine(pies_l.rasa); Console.WriteLine(pies_l.nazwa); }

II

Utworzenie klasy 'Pi es ' class Pies { int wielkość; String rasa; String nazwa; Pies() {

II

Konstruktor

II

Określenie wartości obiektu

wielkość =

sa;

rasa

=

"Husky"; nazwa

=

"Borys"; } } void szczekaj() {

Console.WriteLine("Hau! Hau!") ; } } } PROBLEMY KRYMINALISTYKI 288(2) 2015 Wynik:

I

~~'kY

Borys Dziedziczenie

Dziedziczenie to jeden z fundamentów progra-mowania obiektowego. Umożliwia sprawne i łatwe

wykorzystanie już raz napisanego kodu czy budowa-nie hierarchii klas przejmujących swoje właściwości. Dziedziczenie polega na budowaniu nowych klas na bazie już istniejących. Każda taka nowa klasa przejmuje zachowanie i właściwości klasy bazowej.

Projektując klasy przy wykorzystaniu

dziedzicze-nia, należy umieścić wspólny kod w klasie bazowej,

a następnie poinformować klasy wyspecjalizowane,

iż konkretna wspólna (bardziej abstrakcyjna) klasa, jest ich klasą bazową. W przypadku, gdy jedna klasa dziedziczy po drugiej, to klasa potomna dziedziczy po klasie bazowej. Potocznie mówisię, żeklasa potomna rozszerza klasę bazową. Relacja dziedziczenia ozna-cza, że klasa potomna dziedziczy po klasie bazowej.

W języku EnScript dziedziczenie wyrażane jest za

pomocądwukropka (:), acaładefinicja schematycznie wygląda następująco:

cLass kLasa_potomna:kLasa bazowa {

II wnętrze kLasy } klasa bazowa Lekarz ~ lednaskładowa 1(ęg~~jęDJ!1U jednametoda klasy potomne

-:

-,

<

,

I

Chirurg

I

1=1

[oo<t.nową-... l!RP1ł~ Pl'J9U~ II Ilodłjo nową

"-

4

Ilodłjonową_

Ryc. 1.Przykładdziedziczenia.

Przykład:

class MainClass {

void Main(CaseClass c) {

I

I

Utworzenie obiektu lekarza rodzinnego

II

Atrybuty

LekarzRodzinny lekarz

=

new LekarzRodzinny(); lekarz.pracujeWDomu

=

true;

lekarz.pracujeWSzpitalu

=

true;

Console.WriteLine("Lekar z rodzinny: ") ; Console.WriteLine("Pr acuj e w domu: " + ~

lekarz.pracujeWDomu); Console.WriteLine("Pr acuj e w szpitalu: " + ~

lekarz.pracujeWSzpitalu);

(16)

Console.WriteLine("Por ada lekarza: "l ;

lekarz.podajPorade();

}

II Klasa bazowa 'Lekar z '

class Lekarz {

bool pracujeWDomu;

void leczpacjenta() {

Console.WriteLine("Leczy pacjenta") ;

} }

II Klasy podstawowe: LekarzRodzinny, Chirurg,

II które dziedziczą po klasie Lekarz

class LekarzRodzinny:Lekarz {

bool pracujeWDomu;

void podajPorade() {

Console.WriteLine("Pacj ent musi za2ywa ć ~

witaminę (") ;

} }

class Chirurg:Lekarz {

void zróbNacięcie() {

Console. WriteLine("Wy konuję nacięcie") ; } } } Wynik: Lekarz rodzinny: Pracuje w domu: 1 Pracuje w szpitalu: 1

Porada lekarza: Pacjent musi zażywać witaminę C

Graficzny interfejs użytkownika(GUl)

Wykorzystując obiekty, można tworzyć

zaawan-sowane aplikacje działające w oparciu o graficzny

interfejsużytkownika. Tworzącgraficzny interfejsużyt­

kownika, należy pamiętać, że składa się on właśnie

z obiektów: przycisków, etykiet, pól tekstowych itd.,

które mają własne składowe oraz funkcje. W

niniej-szym artykule przedstawione zostaną jedynie dwa

przykładygraficznego interfejsuużytkownika. Przykład:

GroupBoxClass

Dane osobowe

Podaj swojeimię:

OK

I

~ncel

I

Ryc. 2. Przykładoweokno dialogowe (obiekt).

Kodźródłowy wyświetlającyww.okno:

class InputDialogClass: DialogClass {

GroupBoxClass Group;

StringEditClass StringEdit;

InputDialogClass(DialogClass parent,String &5):

DialogClass(parent, "Gro upBoxCl as s Exampl e") , Group(t hi s, "Dane osobowe", START, START, ~

25a, aa, a),

StringEdit(t hi s, "Podaj swoje imię: ", 15, ~

15, 2aa, 12, a, s, 255, a) { } } class MainClass { void MainO { String s; InputDialogClass diag(null, s); diag. ExecuteO; } }

Graficzny interfejs użytkownika związany jest

z przechwytywaniem zdarzeń generowanych przez

użytkownika. W programie EnCase Forensic v.B

za przechwytywanie zdarzeń, np. kliknięcie przez

użytkownika przycisku, odpowiedzialna jest klasa EventC/ass, zaś w wersji 7

ww.

programu klasa Hand/erC/ass.

Button Demo

OK

I

<:ancel

Ryc. 3. Przykładoweokno dialogowe z przyciskiem 'Kliknij'.

Error

[

~ Użytkownikukliknąłeśprzycisk

OK

Ryc. 4. Okno z komunikatemwyświetlonepokliknięciu

(17)

Kod źródłowy wyświetlający

ww.

okna i

prze-chwytującyzdarzenia:

class ButtonOiagClass: OialogClass {

ButtonClass Buttonj

ButtonOialClass(DialogClass parent

=

null): OialogClass(parent, "Button Demo") , Button(t his, "Kli kni j !", START, START, ~

75, 3e, e) II Przycisk

{

}

virtual void ChildEvent(const EventClass ~

&event) {

II Obsługuje zdarzenie kliknięcia

OialogClass::ChildEvent(event)j if (Button.Matches(event» {

II Wyświetla komunikat

ErrorMessage("Ui yt kowni ku kliknąłeś ~

przycisk") j } } } cl as s MainClass { void MainO { ButtonOiagClass bd()j bd. Execute() j } }

zwanym korzeniem (root nade) ipozostałymi węzłami (wierzchołkami)podzielonymina podzbiory,będącymi poddrzewami głównego drzewa. Każde poddrzewo ma swój korzeń, który z kolei ma swoje poddrzewa itd.,a zatemwęzełjest korzeniem pewnego poddrze-wa.Liśćjest to węzeł (element) drzewa,który nie ma potomków, np. plik lub pusty folder.Często liśćmi są

węzłynajbardziej oddaloneod korzenia.

Za przedstawienie danych w programie EnCase w postaci drzewa odpowiada klasa NadeCIass. Większość klas programu EnCase dziedziczy skła­ dowe i funkcje

ww.

klasy. Wybrane funkcje klasy

NadeCIass, tj.: Perenu), FirstChild(), LastChild(),

Next(), umożliwiają przetwarzanie danych w postaci

struktury drzewa. Przykład

class NodeClass {

NodeClass(parent

=

null)j II konstruktor NodeClass FirstChild()j

NodeClass LastChild()j NodeClass Next()j NodeClass Parent()j }

EnCase Forensic v.6 i 7 - podstawowe różnice

wjęzyku EnScript

Ryc. 5. Struktura danych w postaci drzewa.

Listypołączone,struktura drzewa

Root ---ł Węzeł główny

(ang.root node)

class MainClass {

void Main(CaseClass c) {

forall (EntrYClass entry in c.EntryRoot(» { Console.WriteLine(entry.Name(»j

} }

}

V6

Język programowania EnScript jest językiem

nie-kompatybilnym, co oznacza, że skrypty napisane

w programie EnCase Forensic v.6 nie będą działały w najnowszej wersji programu. Jedynym wyjściem,

jakie pozostaje użytkownikowi programu EnCasev.7, jest przepisanie skryptów z wersji 6 w taki sposób,

abydziałałyone

w

najnowszej wersjiprogramu. Przed przystąpieniemdo aktualizacji skryptów wartopoznać podstawowe różnice występujące w języku EnScript zdefiniowanym w obydwu wersjach programu EnCase Forensic.

Iteracja danych

Podstawowa różnicawjęzyku EnScript zdefiniowa-nym w

ww

.

wersjach programu EnCase Forensic wy-nika ze sposobu przetwarzania danych widniejących w programie w postaci struktury drzewa.W programie

EnCase v.6w celu przetworzenia danychnależy użyć jednej z dwóch instrukcjisterujących:foreachlubforaII.

Instrukcja sterująca foreach, pozwala na uzyskanie

dostępu do wszystkich wierzchołków węzła główne­

go, natomiast instrukcja foralI pozwala na uzyskanie dostępudo wszystkichelementów struktury drzewa.

Folder (poddrzewo) Plik-liść (ang.lea'nade) Plik2 Plik1 Folder 2 Folder 3 Folder 1

W celu zrozumienia sposobu wyświetlania oraz prze-twarzania danych w programie EnCase pomocne jest zrozumienie struktury drzewa oraz struktury list połączonych.

Listapołączonajest to struktura danychskładająca się z elementów przystosowanych do łączenia sięze

sobą w miarę potrzeb. Elementy listy nazywane są

węzłami (nade). Listy połączone występują w trzech

odmianach: listapołączonapojedynczo, listapołączo­ na podwójnie oraz drzewo.

Drzewo jest najbardziej złożoną odmianą listy

łączonej orazpodstawową strukturądanych

wykorzy-stywanąw programie EnCasesłużącądo

prezentowa-nia danych w oknie struktury danych (A). Drzewo to

skończonyzbiórwęzłów(nodes) orazliści(/eaf nodes)

z wyróżnionym węzłem głównym (wierzchołkiem)

(18)

W przypadku programu EnCase Forensic v.7w celu przetworzenia lub wyświetlenia danych w postaci struktury drzewa należy posłużyć się obiektem typu

ItemlteratorClass. V7 elass MainClass { void Main(CaseClass e) { ItemlteratorClass iter (eJ ItemlteratorClass::NORECURSE ItemlteratorClass::NOPROXYJ ItemlteratorClass::ALL)j

while (EntryClass entry

=

iter.GetNextEntry(»

{

Console.WriteLine(entry.Name(»j

} } }

Urządzenie- uzyskaniedostępu

Kolejną różnicąjest sposób uzyskania dostępu do

urządzeniadodanego do sprawy.Wprogramie EnCase Forensicv.6bezpośredni dostępdourządzenia można uzyskaćzapomocąobiektu typu DeviceClass.

V6

elass MainClass {

void Main(CaseClass e) {

foreaeh (DevieeClass dev in e.DevieeRoot(»

{

Console.WriteLine(dev.Name(»j

} } }

W programie EnCase Forensic v.7pomiędzy obiek-tami typu DeviceClassiCaseClass,znajdujesięobiekt

EvidenceClass. Przykłady:

V7

elass MainClass {

void Main(CaseClass e) {

foreaeh (EvideneeClass ev in e.EvideneeRoot(»

{

EvideneeOpenClass evOpen()j

if (DevieeClass dev

=

e.GetDeviee ~

(eJ eVOpen» { Console.WriteLine(dev.Name(»j } } } }

Iteracjazawartości urządzenia

V6

elass MainClass {

void Main(CaseClass e) {

foreaeh (DeviceClass dev in e.DevieeRoot(» { foreaeh (EntryClass entry in ~

dev.GetRootEntry(» { Console.WriteLine(dev.Name(»j } } } } V7 elass MainClass { void Main(CaseClass e) {

foreaeh (EvideneeClass ev in e.EvideneeRoot(»

{

EvideneeOpenClass eVOpen()j

if (DevieeClass dev

=

e.GetDeviee ~

(eJ eVOpen» { Console.WriteLine(dev.Name(»j ItemlteratorClass iter(dev)j

while (EntryClass entry

=

~

iter.GetNextEntry(» { Console.WriteLine(entry.Name(»j } } } } }

Uzyskaniedostępudo pliku

Skrypty programu EnCase pozwalają na uzyska-nie dostępu do pliku, który został zaznaczony przez

użytkownika. Wprogramie EnCasev.6funkcjonalność

ta była ograniczonawyłączniedo elementów prezen-towanych przez obiekty typu EntryClass, widocznych w oknieEntries.

V6

elass MainClass {

void Main(CaseClass e) {

long offset

=

ej

long size

=

2ej

if (EntryClass entry

=

e.GetEntry(offset,size){ Console.WriteLine(entry.Name(»j

} } }

W wersji 7 funkcjonalność ta została znacznie rozszerzona i możliwe jest uzyskanie dostępu do za-znaczonego obiektu typuEntryClass, BookmarkClass, RecordClassitd.

(19)

V7 Zakładki- tworzenie notatek

class MainClass {

void Main(CaseClass c) { V6

lon g of fset

=

ej

long si ze

=

zej

if (Ent ry Class ent ry = c.Get Entry:: TypeCast ~

(c.GetCur rentltem(offset ,size») { Conso le.Write Line(ent ry.Name(» j }

}

class MainClass {

void Mai n(CaseClass c) {

BookmarkFolderClass folder ( c . Bookmar kRoot ( ) , ~

"Test")j fol der . AddNot e ("Not at ka", e, 16, ~

BookmarkClass::SHOWREPORT)j

}

Zakładki- tworzeniefolderów

Sposób tworzenia folderów w zakładkach pro-gramu EnCase został zmieniony nieznacznie. W wersji 6 należy posłużyć się obiektem klasy

BookmarkFo/derC/ass,zaśw wersji 7 programu ob iek-tem klasyBookmarkC/ass.

V6

class Mai nClass {

void Main(CaseClas s c) {

Bookmar kFolde rClass folder(c .BookmarkRoot() , ~

"Test")j } } V7 class MainClas s { void Mai n( CaseCla ss c) {

BookmarkCla ss folder(c .BookmarkRoot() , ~

"Test", NodeClass::FOLDER)j

} } } } V7 class MainClass { void Main(CaseClass c) {

Bookma rkClass booknote

=

c.Bookma r kRoot() j

BookmarkClas s not e ( booknote, "Notatka") j

note.SetComment(" Z awa rto ś ć notatki") j

} }

EnScriptAPI

Program EnCasejest dystrybuowany wraz z bogatą dokumentacjąw formie plikuHTMLokreślanąjako API (Application ProgrammingInterface).Dokumentacjata jest najlepszym źródłem pozwalającym na zdobycie szczegółowych informacji o klasach, ich składowych

ifunkcjach. DokumentacjaAPIzawierarównież

przy-kładoweprogramy (skrypty), któresąbardzo pomocne podczas tworzeniawłasnych aplikacji.Zawartość API programu EnCase Forensic można wyświetlić za

po-mocą menu programu:He/p->EnScript He/p.

6.18. .'~"r-~

mi ~

Ukryj Wstecz

11j'.

l!P<1'

.>NocIeclass_EB1lDleraUOD.lBsel1ODUOllS""r~f -,

.,;;" in...l4iitloll

NodeClass

,'. ~....; '~',j" :['F' :4;,k:r....H~?~ClissiE..iuneratloBNocIeoDUO....h·_ł

r.:v~.' '. ó;" ,':1.,,". "~:f', Yallle~~" '~ ", ~"":-,,:'''" ••

p.F?:?.~··----~_·~=-·~--~~··~:=)

..

·~--,--·-

..

~·--:~~~rf:od~'is a fol~" _. .. .. . - ..

-I"'SELECTED i2 _... iSELECTED _nodeis seleeted

r,.>imREPORT -- · --- -· - ---·fl6- - lNREPORt:,_"_Dod_e_is_in_repotI-'--"o:.."'"'-.-"- - - i NodeClassis a generictreedatastructure.

[lnner ClassesJ [EDumeratioD~ [Properti.nJ [Metllodsl [Examples]

-

--

- -

-

- - - -

-

-_._

-_.

_---

_ ._

._-

-

-_._--_

.

_

_

._---_._--

--_

.•

_

.

__

._--~--_. r--;:T .:;" ..•' r: ,''(:..r ... ~. Naae :_c' "' If ..:-!.VaI8eC' n,.,'

I

I

I

,

I

I

"

I ' 1=

I

-I I

~eillodeks W_illkJlli~

~10P01ICI"• • IPClas. • 1PEditOos. • I\oywordCl . .. • l8ng • lcngu<rg.a... • Un.Bt90k0 ... • LislEditOas. • LivelinkS1oreO... • LDcoJFdoO... • l.ocoIModIine • LogicolEvid.nceFilea... • LogRscordCl... . Ioog • LongEdiIO. .. • Mo;n'Mndow • Memorya... • Memo')Mlea..• • MenulluildO... • MonuClen • Mi••ingSedolClos. • NameEd"1lOou • NameUslCI . • NameVeN. a . • NomeVeriontClos. • Netlnterfocea... • N.lU••ra . • N.tworkO .

• No<esSlon>Cl... .nuIl

Ryc. 6. DokumentacjaEnscriptAPI.

(20)

Przykładyautorskich rozwiązań

programistycznych

MAC AddressfromLNK PawełOIber

C:\users\User\Desktop\Wyniki.c~

TheMeaning

ThisscriptreadsMAC addressfromlNKfiles.

Programtakesintoconsideration only L'IIKfiles,whichweren'lcopied

or moved by userfrorn/toanotherlogical disk.

That guaranleesmatreadedMACaddressconcerns networkcards

installedin evidencecornputer,

Search resultswillbedisplayedinConsoleview.

Alidetails(for example:filenarne,lastwOltendale.volurneObjectJD_l

willbesavedinCSVfile.

Source documentTheMeaningoflinkfilesInForensicExaminations,

ThisprogramhasbeenwrittenbyPawełOlber

Forensiclaboratory ofRegionalPoliceHeadquartersin Olsztyn

OK

Ryc. 9. Okno pomocy skryptu MAC Address from LNK.

MACAddressfrom lNK

Skrypt MAC Address from LNK powstał w

opar-ciu o dane zawarte w dokumencie The Meaning ot

Unkfiles in Forensic Examination2autorstwa Harry'ego

Parsonage. Dokument zawiera szczegółowy opis

analizy zawartości plików LNK w edytorze szesnast-kowym, z którego skorzystano w trakcie tworzenia skryptu.

Po uruchomieniu skryptu w programie EnCase Forensic v.6wyświetla sięokno dialogowe umożliwia­

jące określenie ścieżki dostępui nazwy pliku, w którym

zapisane zostanąwyniki działaniaskryptu.

W lewym górnym rogu

ww.

okna znajduje się przy-cisk Help" Po kliknięciu

ww.

przycisku wyświetla się

okno zawierającekrótki opis działaniaskryptu.

Unikalne adresy MAC oraz identyfikator dysku twar-dego odczytane z plików LNK,wyświetlane sąw oknie konsoli programu EnCase Forensic v.6.

Szczegółowe dane uzyskane w wyniku działania

ww.

skryptu zapisywane sąw postaci pliku tekstowe-go CSV. Wynikowy plik tekstowy o rozszerzeniu CSV zawiera m.in. listę plików, z których odczytano adresy MAC wraz zeszczegółowymidanymi.

SkryptRedundant Remover

Skrypt Redundant Removerpowstałw trakcie wy-konywania badań w ramach opinii kryminalistycznej

dotyczącej skimmera Atmel 45D8321 D. W trakcie

realizacji ww. badańodczytanozawartość urządzenia,

którązapisano w postaci pliku binarnegozawierające­

go zapissygnału dźwiękowego.

Odczytany zapis sygnału dźwiękowego zawierał

nadmiarowe dane uniemożliwiające prawidłową

ana-lizęamplitudysygnałui odczyt skopiowanych danych identyfikacyjnych kart płatniczych.

W celu usunięcianadmiarowych danych z ww. pliku

dźwiękowego zawartość dowodowego pliku

binar-nego odczytano za pomocą programu EnCase v.6.

A1001\ atthe pr.let..ic.llvałuetoIcrensic

exannnaucns ofdares and limes. and

objeL"idenlił1c(S in Windows shortrut fiłes.

F orensic Examinations

of

LinldUes OK

I

canceJ

I

~

OutputPath logFilePath:

Ryc. 7. Dokument The Meaning of Linkfiles in Forensic

Examinations.

Program MAC Address trom LNK

Skrypt MAC Address from LNK przeznaczony jest do odczytu adresów MAC kart sieciowych zapisanych w plikach o rozszerzeniu LNK,tzw. skrótach utworzo-nych na dysku twardym z systemem plików NTFS.

Każdorazoweutworzenie przezużytkownikaskrótu do

pliku lub programu na dysku z systemem plików NTFS skutkuje zapisaniem w utworzonym pliku adresu MAC karty sieciowej zamontowanej w komputerze. Skrypt

uwzględnia jedynie pliki z rozszerzeniem LNK, które

niezostałyskopiowane lub przeniesione z innego

no-śnikadanych lub partycji.

Przedmiotowy skrypt okazał się niezwykle istotny w sprawie, której celem było m.in.odczytanie adresu MAC karty sieciowej. Materiałem dowodowym w

ww

.

sprawie był notebook oraz nadesłany luzem dysk

twardy. W wyniku działania ww. skryptu z dowodowe -go dysku twarde-go (nadesłanegoluzem) odczytano 2 adresy MAC kart sieciowych.

Ryc. 8. Okno skryptu MAC Address from LNK.

2 http://computerforensics.parsonage.co.uk/downloads/

Cytaty

Powiązane dokumenty

The measurements were done on a laboratory stand by application of a high-speed video camera and a software for the computer analysis of motion (Książek and Tarnowski, 2003).

Reasumując, należy podkreślić, że społeczna odpowiedzialność biznesu to strategia prowadzenia działalności gospodarczej w sposób uwzględniający aspekty społeczne oraz

Zaobserwowano także wpływ badanego preparatu na wzrost masy korzeni rzepaku ozimego, a także lepsze przezimowanie roślin.. Uzyskano 15–19% przyrost plonu rzepaku ozime- go

Bijlagen 1.. In vervol g op de nota's &#34;Ervaringen mep taludbekledingen&#34; deel I en 11, waarin de ervaringen met de meest voorkomende taludbekledingen langs

,Q WKLV SDSHU ZH UHSRUW H[SHULPHQWDO PHDVXUHPHQWV RQ WKH H[SORVLRQ VHYHULW\ IRU

Poza obiektam i wydobyto głównie ułamki naczyń późno rzym skich.. położony na teren ie zamku

Badania będą kontynuowane. ŁUPAWA,

The work should be sent in an electronic version in the Microsoft Word editor (in .doc or .docx format) with two copies of the printout. The work should include: a) the name