dem Wissen eines Cracks sollte es keine oder
nur unwesentliche Vorteile für den nächsten
Crack geben.
Hier kommt Ihnen als Softwarehersteller die
Komplexität Ihrer eigenen Software zu Gute.
Der Hacker kann zwar alles analysieren, was
über die CPU ausgeführt wird, aber dazu muss
es auch erst einmal ausgeführt werden. Bei
einer üblichen Businessanwendung setzen
Anwender nur 10 bis 20 Prozent der ange-
botenen Funktionen ein. Es wird also nur ein
Bruchteil des Codes wirklich ausgeführt. Dies
erschwert dem Hacker das Beobachten, denn
er muss sich eine Strategie einfallen lassen,
wie er den kompletten Code einmal ausführt.
Wer diese Quadratur des Kreises lösen könnte,
wäre der König der Testtools und müsste sein
Geld nicht mehr damit verdienen, anderer
Leute Software zu cracken.
Eine Voraussetzung dafür ist, dass der Kopier-
schutz und die Lizenzierung dort im Code erfolgt,
wo er benötigt wird. Die oft gebräuchliche Stra-
tegie der Erstellung einer Lizenz-Wrapper-Klasse
und des Aufrufs dieser Klasse an vielen Stellen ist
hier kontraproduktiv. Der Hacker muss lediglich
den Code dieser Lizenz-Wrapper-Klasse analysie-
ren, verstehen und austauschen. Auch das Ver-
schlüsseln dieser Klasse durch den AxProtector
behebt diese Schwachstelle nicht und bietet eher
ein falsches Gefühl von Sicherheit. Die bessere
Lösung ist es hier, mit AxProtector .NET und Ix-
Protector möglichst viele Funktionen im Code zu
verschlüsseln. Denn dann muss der Hacker die
Software wirklich komplett ausführen. Gegen
automatische Analysen können Fallen einge-
streut werden, die den CmDongle bzw. auch die
CmActLicense im Falle eines Angriffes sperren.
Mehr Details zu dieser Art der Integration finden
Sie im vorherigen KEYnote Magazin 34.
CodeMoving
Die ultimative Sicherheit bietet die dritte Stra-
tegie: die Auslagerung von Code in den Cm-
Dongle und die Ausführung im CmDongle
selbst. Damit ist eine Beobachtung durch den
Hacker komplett unmöglich.
Top-
Hacker
Profi -Hacker
Hobby-Hacker
Skript Kiddies
Die Möglichkeit, Code in den CmDongle zu
verschieben, steht für CmDongles mit Serien-
nummer 3-xxxxxx und Firmware 4.03 zur Ver-
fügung. Aktuell ist die Auslagerung von Code,
der in C geschrieben ist, möglich. Die Unter-
stützung von Java- und .NET-Code ist bereits in
Planung. Ein wichtiger Punkt beim Verschieben
von Code ist die Auswahl des richtigen Codes.
Ist er zu trivial, kann er anhand der Ergebnisse
erraten werden. Ist er zu komplex, verlangsamt
die Auslagerung des Codes den Ablauf oder die
Menge des auslagerbaren Codes von 3 kByte
wird überschritten. CodeMoving sollte nur mit
Einzelplatz-Dongles eingesetzt werden.
Der auszulagernde Code wird in einer separa-
ten C-Datei geschrieben. Der komplette Code
der Datei inklusive aller Unterfunktionen wird
dabei verschoben. Die C-Datei umfasst als Min-
destangabe eine Eingabestruktur, eine Ausga-
bestruktur und eine Entry-Funktion, die diese
Strukturen verwendet. Über die Eingabestruktur
werden Daten an den CmDongle übergeben.
Über die Ausgabestruktur werden Daten nach
der Berechnung im CmDongle an die Anwen-
dung zurückgegeben. Die Entry-Funktion ist die
Funktion, die im CmDongle ausgeführt wird.
Das Beste dabei ist: Sie können beliebig viele
Codefragmente erzeugen, die im CmDongle
ausgeführt werden. Um den Code zu verschie-
ben, wird die Anwendung mit AxProtector ver-
schlüsselt. Alle zu verschiebenden Funktionen
werden dabei vom AxProtector kompiliert und
verschlüsselt in der Anwendung abgelegt. Zur
Laufzeit wird der verschlüsselte Block an den
CmDongle übertragen, dort im CmDongle ent-
schlüsselt und mit den Eingabeparametern aus-
geführt. Die Ausgabeparameter werden dann
an die Anwendung zurückgeliefert.
Im CmDongle stehen einige Hilfsfunktionen
zur Verfügung. So können Sie kryptographische
Funktionen wie AES und SHA direkt verwenden.
Zusätzlich können Daten temporär gespeichert
und beim Aufruf der nächsten Funktion wieder-
verwendet werden. Auch der Zugriff auf Hidden
Data ist möglich. Aus Sicherheitsgründen ist
der Zugriff auf Hidden Data nur innerhalb des
Product Items möglich, mit dem das Codefrag-
ment verschlüsselt wurde.
// simple.h
// simple.h
Defi nition of the Input and Output structure
//
// Defi
between
and and
CmDongle
//
nition Software
of the Input
Output structure
// simple.h
#ifndef
simple_h and CmDongle
// Defi
between
//
nition Software
of the Input and Output structure
#defi
ne simple_h
simple_h
#ifndef
//
between
Software and CmDongle
#defi ne simple_h
simple_h
#ifndef
struct I {
#defi ne simple_h
int I a;
struct
{
int
int I b;
a;
struct
{
}; int b;
int a;
}; int b;
struct O {
};
int O result;
struct
{
}; int result;
struct O {
}; int result;
#endif
};
#endif
#endif
// simple.c
//
of a sample a + b = c function
// implementation
simple.c
#include
"code_moving_api.h"
//
implementation
of a sample a + b = c function
// simple.c
#include
"simple.h"
#include
"code_moving_api.h"
// implementation
of a sample a + b = c function
#include
#include "simple.h"
"code_moving_api.h"
// entry function which is executed in the CmDongle
#include "simple.h"
void
entry(const
const i, struct
o)
//
entry
function struct
which I*
is executed
in the O* CmDongle
{ void entry(const struct I* const i, struct O* o)
// entry function which is executed in the CmDongle
= i->a + i->b;
{ void o->result
entry(const struct I* const i, struct O* o)
} o->result = i->a + i->b;
{
} o->result = i->a + i->b;
}
// SimpleCodeMovingSample.cpp
//
1 + 2 in a CmDong le
// calculates
SimpleCodeMovingSample.cpp
#include
"stdafx.h"
//
calculates
1 + 2 in a CmDongle
// SimpleCodeMovingSample.cpp
#include "stdafx.h"
"wibuixap.h"
#include
// calculates 1 + 2 in a CmDongle
#include "wibuixap.h"
"simple.h"
#include
#include "stdafx.h"
#include
#include "simple.h"
"wibuixap.h"
int _tmain(int argc, _TCHAR* argv[])
#include "simple.h"
{ int _tmain(int argc, _TCHAR* argv[])
I input;
{ _tmain(int
int
argc, _TCHAR* argv[])
O output;
{ I input;
input.a
=
1;
output;
I O input;
input.b
= 1;
2;
input.a
=
O output;
input.b
=
2;
input.a = 1;
// execute moved function now
input.b = 2;
if (WupiExecuteMovedCodeId(
//
execute moved function now
1, 1, &input, &output) == 1) {
if // (WupiExecuteMovedCodeId(
execute moved function now
// 1,
print
the result
(3)
1, &input,
&output)
== 1) {
if (WupiExecuteMovedCodeId(
printf("%d\n",
output.result);
// 1,
print
the result
(3)
1, &input,
&output)
== 1) {
} printf("%d\n", output.result);
// print the result (3)
return
0;
} printf("%d\n", output.result);
} return 0;
}
} return 0;
}
Skalierbare Sicherheit
Mit CodeMeter können Sie selber bestimmen,
wie viel Sicherheit Ihre Anwendung benötigt.
Von einfachen Lizenzabfragen, um unbeabsich-
tigten Lizenzmissbrauch zu verhindern, bis zur
Ausführung von Code im CmDongle: CodeMe-
ter passt sich an Ihre Anforderungen an.
11