neděle 28. prosince 2014

BCEL

Zkratka BCEL značí slovní spojení Byte Code Engeneering Library, tedy se jedná o knihovnu pro práci s bytekódem. Tato knihovna je vyvíjena společností The Apache Software Foundation a taktéž spadá pod licenci Apache 2.0

Balík BCEL není určený pro plnou dekompilaci kódu. Jeho účel je majoritně zaměřený na modifikaci již zkompilovaného kódu (bytekódu). Při zpracování však dává k dispozici tyto informace:

  • Název třídy
  • Název souboru
  • Název balíku
  • Název rodičovské třídy
  • Příznaky třídy
  • Názvy implementovaných rozhraní
  • Seznam atributů třídy (název, datový typ)
  • Seznam metod třídy (název, datový typ návratové hodnoty, datové typy parametrů)

Nevýhodou tohoto balíku je možnost zpracování pouze souborů .class, tedy nikoliv .jar a omezené množství poskytovaných informací. Na druhou stranu je doba zpracování velice krátká (jednotky sekund) na rozdíl od dekompilace pomocí balíku Procyon.



Zdroje:
http://commons.apache.org/proper/commons-bcel/
http://greg-dip.blogspot.cz/2014/11/bcel-vypis.html

sobota 27. prosince 2014

Procyon

Balík Procyon je open source projekt vyvíjený pod licencí Apache 2.0. Vývoj započal koncem roku 2012 hlavním vývojářem Mikem Strobelem. Domovské stránky s možností stažení zdrojových kódů, drobným popisem a návodem lze nalézt na adrese https://bitbucket.org/mstrobel/procyon.

Procyon je balík nástrojů pro generování a analýzu zdrojového kódu. Hlavní části (knihovny) jsou Core framework, Reflection framework, Expression framework, Compiler toolset a Java decompiler.

Je nutno podotknout, že dekompilace je poměrně náročná operace a vyžaduje hodně vypočetního času procesoru. Dekompilace velkého projektu může na průměrném stroji trvat několik jednotek až desítek minut.

Použití


Pokud je stažen již zkompilovaný procyon-decompiler.jar , lze si spuštěním tohoto programu vypsat nápovědu:

java -jar procyon-decompiler.jar -?

Nebo je možné se rovnou pokusit dekompilovat nejaký soubor. Pro vyzkoušení funkčnosti lze vyzkoušet dekompilovat standardní knihovny javy jako například java.lang.String. Soubor pro dekompilaci se zadává jako parametr programu.

java -jar procyon-decompiler.jar java.lang.String

V případě použití dekompilátoru v terminálech, které neposkytují obarvení textu (vyznačení syntaxe) bude uživatel značně ochuzen. Proto se doporučují terminály s možností zabarvování textu a pokud přesto detekce ANSI selže, je možné toto vynutit přidáním argumentu -DAnsi=true.

java -DAnsi=true -jar procyon-decompiler.jar java.lang.String

Balík Procyon umožňuje také dekompilaci celých .jar souborů. K tomu je potřeba přidat dekompilátoru argumet -jar, oznamující typ přícozího souboru a dále je možné si výsledek uložit do vybraného umístění.

java -jar procyon-decompiler.jar -jar soub.jar -o out

 

Decompiler API


Tolik k použití již hotového řešení dekompilace. Dále se podíváme na způsob použití balíku Procyon v kódu. V kódu je totiž potřeba Decompiler API, které však obsahuje pouze dvě metody.


public static void decompile(
    final String internalName, 
    final ITextOutput output
);

public static void decompile(
    final String internalName, 
    final ITextOutput output
    final DecompilerSettings settings
);

Prvním parametrem funkce decompile je proměnná typu String, která požaduje v textovém tvaru identifikaci souboru pro dekompilaci. Identifikace může být definována buď adresou v souborovém systému nebo adresu v Java notaci k standardní knihovně (např.: java.lang.String). Druhý parametr je výstup metody v datovém typu ITextOutput, který je definován v rámci balíku Procyon. Poslední parametr je volitelný a je jím možno nastavit některé parametry dekompilace. V následujícím příkladu lze vidět jednoduché použití této funkce s výstupem na terminál.



final DecompilerSettings settings = DecompilerSettings.javaDefaults();

try (final FileOutputStream stream = new FileOutputStream("path/to/file");
     final OutputStreamWriter writer = new OutputStreamWriter(stream)) {

    Decompiler.decompile(
        "java/lang/String",
        new PlainTextOutput(writer),
        settings
    );
}
catch (final IOException e) {
    // handle error
}




Zdroje:
https://bitbucket.org/mstrobel/procyon
https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler
https://bitbucket.org/mstrobel/procyon/wiki/Decompiler%20API

Titan

Tato knihovna pro grafové databáze je implementována v jazyce Clojure. Jazyk Clojure je dialekt jazyka Lisp. Domovskou stránkou knihovny Titan je http://thinkaurelius.github.io/titan/. Titan je šířený jako open source projekt a spadá pod licenci Apache 2.0. Pro ovládání databáze vytvořené pomocí knihovny Titan není vytvořen speciální databázový jazyk, jako je tomu u Neo4J. Grafová knihovna Titan umožňuje použití několika úložných beck-endů. Lze zde využít databáze Apache Cassandra, Apache HBase nebo Oracle BerkeleyDB.

Databázi můžeme ovládat pomocí přiložené aplikace, která využívá grafového dotazovacího jazyka Gremlin nebo pomocí Blueprints. Blueprints je uváděno jako standard API grafových databází.

Gremlin

Spuštěním následujícího příkazu se spustí terminál Gregmlin, ve kterém je již možné spouštět dotazy a příkazy ve stejnojmenném dotazovacím jazyce.

./bin/gramlin.sh
Dále, pro připojení k databázi a případnému vytvoření databáze, je nutné zadat adresu ke konfiguračnímu souboru. Příazy jsou připojení databáze a k ukončení připojení jsou následující:

g=TitanFactory.open('/directory/file')
g.shutdown()
Podrobný popis tvorby konfiguračního souboru lze nalézt ve složce conf stažené knihovny Titan, kde je to popsáno v souboru titan-cassandra-es.properties. Jednoduchým příkladem funkční konfigurace může být následující text tohoto konfiguračního souboru:

storage.backend=berkeleyje
storage.directory=db/berkeley
index.search.backend=elasticsearch
index.search.directory=db/es
index.search.elasticsearch.client-only=false
index.search.elasticsearch.local-mode=true
Klíčovou informací z configuračního souboru je použití úložného back-endu, který je v tomto případě BerkleyDB (berkeleyje).

Pro vytvoření vrcholu se použije funkce addVertex() a následně se vrcholu funkcí setProperty() nastaví požadované vlastnosti.

prom1 = g.addVertex()
prom1.setProperty('name','Jirka')
K vytvoření hrany se potom použije funkce addEdge(), kde se spojí například hrana prom1 a prom2 a nastaví se typ resp. popisek. Dále je samozřejmě zase možné dát hraně další vlastnosti podobně jako vrcholu.

g.addEdge(null,prom1,prom2,'KNOWS')

Jednudochý dotaz může vypadat následovně, kdy se grafové databáze ptáme na vrchol, který má vlastnost name s hodnotou "Jirka"

 g.V.has('name','Jirka')

Blueprint API

Aplikaci Gremlin a tento standard API vyvíjí stejná skupina lidí (TinkerPop), díky tomu je použití Blueprint v Javě velice podobné příkazům v aplikaci Gremlin. Zpracování databáze je zde transakční, proto je vhodné operace nad databází uzavírat do klauzule pro odchytávání vyjímek a po ukončení bloku příkazů zakončit příkazem shutdown().

Za zmínku už zde stojí asi jen fakt, že proměnná g, která se používala i v aplikaci Gremlin (zde má stejný význam) je datového typu TitanGraph, vrcholy vytvořené funkcí addVertex() jsou datového typu Vertex a hrany jsou typu Edge.



1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.*;


public class test {

 public static void main(String[] args) {
  
  TitanGraph g = TitanFactory.open("/home/greg/Plocha/experiment/soub");
  
  Vertex oz = g.addVertex(null);  
  oz.setProperty("name", "Jiri Bilek");  
  oz.setProperty("age", "24");  
    
  Vertex sz = g.addVertex(null);  
  sz.setProperty("name", "Tatka Bilek");  
    
  Edge e = g.addEdge( null, sz, oz, "parent");
  
  g.commit();
  
  
  if (g.getVertices("name", (Object)"Jiri Bilek").iterator().hasNext())
   System.out.println("Jiri Bilek is "+g.getVertices("name", (Object)"Jiri Bilek").iterator().next().getProperty("age")+" years old");
  else
   System.out.println("Zadny Jiri Bilek v databazi neni");
  
  
  g.shutdown();
 }

}


Zdroje:
http://www.tinkerpop.com/
http://s3.thinkaurelius.com/docs/titan/0.5.0/
http://titanium.clojurewerkz.org/articles/getting_started.html
http://thinkaurelius.github.io/titan/
http://euranova.eu/upl_docs/publications/an-empirical-comparison-of-graph-databases.pdf
http://clojure.org/

pátek 26. prosince 2014

Neo4J

Knihovna pro práci s grafovýni databázemi Neo4J je implementována v programovacím jazyce Java. Tato grafová knihovna využívá dotazovacího jazyka Cipher a její domovká stránka je na adrese http://neo4j.com/. Na těchto stránkach je taktéž k dispozici stažení knihovny určené pro komunitu a tedy zdarma pod licencí Apache 2.0. Neo4J je možné získat i v komerční verzi.

Používat grafovou knihovnu Neo4J lze několika způsoby. Jedním ze způsobů je spuštění databázového serveru používání pomocí prohlížeče (viz Cipher). Další možností je Java API.

Cipher


Po stažení balíku s databází lze spustit následující příkaz, který spustí databázový server:
 ./bin/neo4j console
Následně lze v prohlížeči navštívit stránku http://localhost:7474/, kde je k dispozici manuál, rychlý tutoriál a hlavně příkazová řádka pro příkazy (dotazy) v jazyce Cipher.

Jazyk Cipher je deklarativního typu. Jeho syntace byla pro větší intuitivnost inspirována jazykem relačních databází databází SQL. Tímto jazykem se nezadávají příkazy způsobem "jak chci hledat", ale "co chci najít".

Vytvoření hrany:
CREATE (ee:Person { name: "Emil", from: "Sweden" })
Tímto příkazem bude pomocí jazyka Cipher v databázi vytvořena hrana označená jako "Person". Tato hrana bude mít vlastnosti name s hodnotou Emil a from s hodnotou Sweden.

Tvorba hran:

MATCH (ee:Person) WHERE ee.name = "Emil"
MATCH (ef:Person) WHERE ef.name = "Franta"
CREATE (ee)-[:KNOWS {since:1989}]->(ef)
Zde jsem si vyhledal vrchol s vlastností name, která má hodnotu "Emil" a uložil jsem si tento vrchol do proměnné ee. Podobně do proměnné ef jsem vložil vrchol s vlastností name, které má hodnotu "Franta" a následně vytvořil vztah s typem KNOWS a vlastností since s hodnotou "1989".

Dotaz na Emila a jeho známé:

MATCH (ee:Person)-[:KNOWS]-(friends)
WHERE ee.name = "Franta" RETURN ee, friends
Díky tohoto dotazu je možné vyhledat všechny uzly, které mají vztah s uzlem, který má vlastnost name s hodnotou "Franta". Dalším specifikem musí být typ vztahu KNOWS. Dále se vykreslí příp. vypíše výsledek příkazu, který je možné vidět na následujícím obrázku.




Java API

Pro vytvoření databáze Neo4J s využitím Java API je potřeba vytvořit instanci třídy GraphDatabaseService. Vytvoření databáze tak i spustí databázový server. Při instanciaci je potřeba zadat parametr, který značí adresu v souborovém systému k úložišti. Např:. 


1
private static final String DB_PATH = "/home/greg/Plocha/test-data";



Vytvoření databáze a spuštění databázového serveru se potom provádí takto:


1
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );


Následující příkaz potom náš databázový server zase ukončí.


1
graphDb.shutdown();


Veškerá manipulace s databází probíha v transakcích a proto je potřeba po každé takovéto transakci zadat příkaz pro potvrzení transakce. Navíc je nutné tuto manipulaci s ukončovacím potvrzením kvůli možným chybám uzavřít do klauzule pro odchytávání vyjímek.


1
2
3
4
5
try ( Transaction tx = graphDb.beginTx() )
{
    // Database operations go here
    tx.success();
}

 
Vytvoření vrcholu a hrany je potom vidět až na komplexnějším příkladu. Dále přikládám funkční jednoduchý příklad, který vytvoří dva vrcholy, mezi nimi jednu hranu a následně vypíše hodnotu jedné vlastnosti každého tohoto elementu.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package priklady;

import org.neo4j.graphdb.*;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;

public class priklady {

 /**
  * @param args
  */
 private static enum RelTypes implements RelationshipType
 {
     KNOWS,
     UNKNOWS;
 }

 private static final String DB_PATH = "/home/greg/Plocha/test-data";
 
 public static void main(String[] args) {
  
  GraphDatabaseService graphDb;
  Node firstNode;
  Node secondNode;
  Relationship relationship;

  graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );
  registerShutdownHook( graphDb );
  
  try ( Transaction tx = graphDb.beginTx() )
  {
   //create data
   firstNode = graphDb.createNode();
   firstNode.setProperty( "message", "Hello, " );
   secondNode = graphDb.createNode();
   secondNode.setProperty( "message", "World!" );

   relationship = firstNode.createRelationshipTo( secondNode, RelTypes.KNOWS );
   relationship.setProperty( "message", "brave Neo4j " );
   
   // select data
   System.out.print( firstNode.getProperty( "message" ) );
   System.out.print( relationship.getProperty( "message" ) );
   System.out.print( secondNode.getProperty( "message" ) );
   
   
   // let's remove the data
   firstNode.getSingleRelationship( RelTypes.KNOWS, Direction.OUTGOING ).delete();
   firstNode.delete();
   secondNode.delete();
   
   
      // Database operations go here
      tx.success();
  }
  
  graphDb.shutdown();
 }

 private static void registerShutdownHook(GraphDatabaseService graphDb) {
  // TODO Auto-generated method stub
  
 }

}



Zdroje:
http://neo4j.com/
http://neo4j.com/developer/cypher-query-language/
http://neo4j.com/docs/stable/tutorials.html
http://neo4j.com/docs/stable/tutorials-java-embedded-hello-world.html

Grafové databáze


Databázový konzept označovaný zkratkou NoSQL (často vysvětlován jako "no only SQL" [1]) je specifický svým alternativním přístupem k ukládání dat a dotazováním nad nimi. S daty se nepracuje jako v klasických relačních databázích (tedy v tabulkách). Možným příkladem jsou grafové databáze, kde jsou data uložena v orientovaných grafech.

Grafové databáze využívají následujících 3 stavebních bloků
  • vrchol
  • hrana
  • vlastnost

Vrchol grafu (node) představuje záznamy databáze. Například vrchol 1 a 2 v následujícím obrázku. Hrany (relationships) představují vztahy mezi vrcholy v databázi. Nutným parametrem hrany je směr a typ. Podle následujícího obrázku je tak zřejmé, že vrchol 1 je ve vztahu s vrcholem 2. Tento vztah je otypován jako PART_OF, tedy objekt zastoupený záznamem vrchol 1 je pravděpodobně součástí jiného objektu zastoupeného záznamem vrchol 2. Posledním stavebním blokem je vlastnost (property). Lze takto blíže specifikovat jak vrchol, tak i hranu. Dle následujícího příkladu je tak už snadno pochopitelné, že vrchol 1, tedy kolo (wheel) je součástí vrcholu 1, tedy auta (které je mimochodem červené barvy) a že tyto součásti jsou hned 4 (number=4).

Stavební bloky grafové databáze [2]


Výhodou grafových databází je přirozený popis dat s podobnou strukturou. Příkladem může být mapování struktury objektově orientovaných aplikací bez pevně stanoveného schématu [1]. Dalším častým využitím grafových databazí je popis vztahů mezi lidmi (facebook, google+). Z následujícího komplexnějšího příkladu lze vyčíst, že se Alice a Bob znají (obousměrný vztah) a že oba jsou členové skupiny šachových hráčů.
Příklad grafové databáze [3]



Zdroje:
[1] https://otik.uk.zcu.cz/bitstream/handle/11025/7596/diplomova_prace.pdf?sequence=1
[2] http://www.infoq.com/articles/graph-nosql-neo4j
[3] http://en.wikipedia.org/wiki/Graph_database

úterý 23. prosince 2014

pátek 5. prosince 2014

Java Dekompilátory

Dekompilátorů Java kódu je poměrně velké množství. Mnohé již ale nejsou dále vyvíjeny a další postrádají kvalitu. V následujícím přehledu charakterizuju většinu známějších dekompilátorů.


Procyon
Nový, poměrně kvalitní dekompilátor, který je stále vyvíjen.

Licence: Apache licence 2.0
Internetové stránky: https://bitbucket.org/mstrobel/procyon


CRF (Class File Reader)
Vytvořen v Java 6. Podporuje Java 6, Java 7 i Java 8. Stále vyvíjen. Občas ještě vypisuje kontrolní výpisy.

Licence: MIT licence
Internetové stránky: http://www.benf.org/other/cfr/


Krakatau
Stále vyvíjen. Vytvořen v jazyce Python (Python 2.7). Částečná podpora Java 8.

Licence: GNU GPL
Internetové stránky: https://github.com/Storyyeller/Krakatau/


Candle
Dekompilátor programovaný v Javě. Vývoj pravděpodobně skončil v roce 2013. Přestože je vývoj opřen o firmu Red Hat, není dekompilátor úplně dokončený.

Internetové stránky: https://github.com/bradsdavis/candle-decompiler


JBVD (Java Bytecode Viewer & Decompiler)
Vývoj skončil v roce 2011. Přestože označovaný jako OpenSource, nepodařilo se mi na internetu najít zdrojový kód.

Licence: Academic Free License (AFL)
Internetové stránky: http://jbdec.sourceforge.net/


EDJC (Emilio's Java Decompiler)
Dekompilátor vytvářen v jazyce Java. Vývoj skončil alfa verzí v roce 2011.

Licence: GNU GPL
Internetové stránky: http://sourceforge.net/projects/ejdc/


JD
Součásti JD-Code a JD-Gui programovány v jazyve C++. Podpora jdk1.1.8, jdk1.3.1, jdk1.4.2, jdk1.5.0, jdk1.6.0 a jdk1.7.0. Tento dekompilátor poskytuje plugin k vývojovému prostředí Eclipse.

Licence: MIT licence, uzavřený kód
Internetové stránky: http://jd.benow.ca/


FernFlower
Vytvořeno v jazyce Java. K projektu není žádná dokumentace ani bližší informace.

Licence: Freeware License 1.0
Internetové stránky: pravděpodobně nemá, ale zdrojový kód je ke stažení zde http://forum.xda-developers.com/showthread.php?t=2029842


JaD (JAva Decompiler)
Dekompiler podporující dekompilaci Java 7. K dispozici je také plugin pro vývojové prostředí Eclipse s názvem JadClipse.

Licence: Komerční program (pro nekomerční použití zdarma)
Internetové stránky: http://varaneckas.com/jad/


DJ
Určený pro operační system Windows. Součástí je i editor.

Licence: Komerční (poslední verze s použitím zdarma byla 3.7.7.81)
Internetové stránky: http://www.neshkov.com/dj.html (stránka http://dj.navexpress.com/ je již nefunkční)


Mocha
V roce 1996 vydána betaverze, poté vývoj skončil.

Internetové stránky: http://www.brouhaha.com/~eric/software/mocha/


Závěr
Je zřejmé, že máme k dispozici velké množství dekompilátorů pro Java bytekód. Avšak kvalitní open source dekompilátor vyvíjený v Javě je pouze Procyon.



Zdroje:
https://developer.jboss.org/people/ozizka/blog/2014/05/06/java-decompilers-a-sad-situation-of
https://bitbucket.org/mstrobel/procyon
http://www.benf.org/other/cfr/
https://github.com/Storyyeller/Krakatau/
https://github.com/bradsdavis/candle-decompiler
http://jbdec.sourceforge.net/
http://sourceforge.net/projects/ejdc/
http://jd.benow.ca/
http://forum.xda-developers.com/showthread.php?t=2029842
http://www.neshkov.com/dj.html 
http://www.brouhaha.com/~eric/software/mocha/