IV. Annexe A : Obfuscation▲
Il existe cependant une méthode capable de protéger le code source : l'obfuscation
En gros, on utilise un programme que l'on appelle obfuscateur tel que ProGuard. Ce programme va modifier le bytecode afin de remplacer les noms de méthodes, les noms des champs par des noms totalement abstraits. Cela n'empêche pas un décompilateur de faire son travail, mais le code ainsi régénéré est nettement plus difficile à lire.
Certains obfuscateurs vont même jusqu'à ajouter du bytecode, qui ne sera jamais réellement atteint, afin de tromper le décompilateur qui n'arrive plus à comprendre ce code.
Cependant, ce genre de processus n'est pas possible sur n'importe quel code. En effet, on ne peut pas obfuscer les interfaces publiques d'une API au risque de ne plus permettre son utilisation correcte.
Une information importante est qu'un Obfuscateur comme ProGuard va, en plus de rendre illisible, optimiser le code. Il en résulte parfois ainsi du code plus léger et plus rapide.
IV-A. Petit exemple avec ProGuard▲
Voici notre classe ByteCode, ainsi qu'une classe TestMain qui l'utilise simplement.
package
com.developpez.hikage.bytecode;
public
class
ByteCode {
private
String nom;
public
String getNom
(
) {
return
nom;
}
public
void
setNom
(
String nom) {
this
.nom =
nom;
}
public
void
maMethode
(
){
String texte =
"Visitez Developpez.com"
;
for
(
int
i =
0
; i <
10
; i++
){
System.out.println
(
texte);
}
}
}
package
com.developpez.hikage.bytecode;
public
class
TestMain {
/**
*
@param
args
*/
public
static
void
main
(
String[] args) {
ByteCode code =
new
ByteCode
(
);
code.setNom
(
"test"
);
code.maMethode
(
);
}
}
Et voici le résultat après une obfuscation grâce à ProGuard, et une décompilation avec JAD :
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
package
test;
import
java.io.PrintStream;
public
final
class
a
{
public
a
(
)
{
}
private
String Code
(
)
{
return
Code;
}
public
final
void
Code
(
String s)
{
Code =
s;
}
public
static
void
Code
(
)
{
String s =
"Visitez Developpez.com"
;
for
(
int
i =
0
; i <
10
; i++
)
System.out.println
(
s);
}
public
String Code;
}
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
package
test;
// Referenced classes of package test:
// a
public
final
class
b
{
public
b
(
)
{
}
private
static
void
Code
(
)
{
a a1;
(
a1 =
new
a
(
)).Code =
"test"
;
a.Code
(
);
}
}
On remarque très rapidement que le code est nettement moins lisible :
- les méthodes ont été renommées, avec le même nom tant que leurs signatures ne sont pas identiques ;
- la variable privée nom a été placée en public, et les appels aux modificateurs/accesseurs ont été remplacés par des appels sur la variable elle-même ;
- les noms de package ont été renommés (com.developpez.hikage.bytecode => test).
Mais on peut remarquer aussi que la méthode static void main (String args[]) a disparu… et donc il n'y a plus moyen de lancer l'application !
Il existe bien sûr des options dans ProGuard, afin de spécifier quelles modifications sont permises, ainsi que d'exclure certaines classes et méthodes de toutes modifications.
V. Remerciements▲
Un grand merci à Dutmatlab et ddm pour la relecture orthographique de mon article, ainsi qu'à wichtounet et Ricky81.