Warning: Use of undefined constant ipaddress - assumed 'ipaddress' (this will throw an Error in a future version of PHP) in /home/www/acp/lib/session.php on line 98

Warning: Use of undefined constant useragent - assumed 'useragent' (this will throw an Error in a future version of PHP) in /home/www/acp/lib/session.php on line 98

Warning: Use of undefined constant request_uri - assumed 'request_uri' (this will throw an Error in a future version of PHP) in /home/www/acp/lib/session.php on line 98

Warning: Cannot modify header information - headers already sent by (output started at /home/www/acp/lib/session.php:98) in /home/www/acp/lib/functions.php on line 82

Warning: Cannot modify header information - headers already sent by (output started at /home/www/acp/lib/session.php:98) in /home/www/acp/lib/functions.php on line 82

Warning: Cannot modify header information - headers already sent by (output started at /home/www/acp/lib/session.php:98) in /home/www/acp/lib/functions.php on line 82

Warning: Cannot modify header information - headers already sent by (output started at /home/www/acp/lib/session.php:98) in /home/www/acp/lib/functions.php on line 82
Forum www.Kopierschutzsysteme.de - Hier findet Ihr Informationen rund um das Thema Kopierschutz - Codeverschleierung
Registrierung Mitgliederliste Administratoren und Moderatoren Suche Häufig gestellte Fragen Stellen Sie hier Ihre spezielle Kopierschutzanfrage Zur Startseite  

Forum www.Kopierschutzsysteme.de - Hier findet Ihr Informationen rund um das Thema Kopierschutz » Programmierung » C / C++ » Codeverschleierung 1 Bewertungen - Durchschnitt: 5.00 1 Bewertungen - Durchschnitt: 5.00 1 Bewertungen - Durchschnitt: 5.00 1 Bewertungen - Durchschnitt: 5.00 1 Bewertungen - Durchschnitt: 5.00 » Hallo Gast [anmelden|registrieren]
Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
rob
Grünschnabel


Dabei seit: 21.03.2008
Beiträge: 8

Codeverschleierung Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Hallo,

steh vor folgendem Problem:

Ich möchte mein Programm (Visual C++ V6.0) gegen Tracing schützen. Hierfür habe ich schon ein paar Debugger Erkennungen eingebaut. Abgeprüft werden die bekannten Debugger wie SICE, OllyDbg und WinDbg. Nun möchte ich gern ein paar Codeverschleierungs-Routinen integrieren, hab nur keinen Plan wie ich das machen kann.

Wäre für jeden Hinweis dankbar.

Gruß
Robert

22.03.2008 16:40 rob ist offline Email an rob senden Beiträge von rob suchen Nehmen Sie rob in Ihre Freundesliste auf
Michael Bauer Michael Bauer ist männlich
Administrator


Dabei seit: 03.02.2007
Beiträge: 127

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Hallo Robert,

willkommen im Forum.

Zuerst mal eine Anmerkung zu Deiner Debugger Erkennung. Da es von OllyDbg auch einige Klons gibt (z.B. Shadow, flyODBG und OllyICE), solltest Du diese auch abfragen. Zusätzlich würde ich vorschlagen, prüf auch noch auf den Syser-Debugger, der wird unter Hackern als Wiederaufstehung der Ring0 Debugger gefeiert, da Softice nicht mehr weiterentwickelt wird.

Nun aber zum eigentlichen Thema.

Du könntest die Codeverschleierung z.B. mittels Anti-Disassembling Makros realisieren. In Visual C++ lässt sich das leicht durch Inline-Assembling machen. Nachfolgend ein Beispiel dazu:

Code ohne Verschleierung:
code:

void Beispiel_Codeverschleierung ()
{
    If (  Check_RegCode() )
    {
         /* RegCode ungültig */
         Goto Exit
     }      
}


Code mit Verschleierung:
code:

#define ANTI_DISASSEMBLING_MACRO() \
    __asm \
    { \
    __asm __emit 0x60 /* pushad */\
    __asm __emit 0xE8 /* call JUMP1 */\
    __asm __emit 0x03 \
    __asm __emit 0x00 \
    __asm __emit 0x00 \
    __asm __emit 0x00 \
    __asm __emit 0xD2 \
    __asm __emit 0xEB /* JUMP4: jmp JUMP5 */\
    __asm __emit 0x0B \
    __asm __emit 0x58 /* JUMP1: pop eax */\
    __asm __emit 0xEB /* jmp JUMP2 */\
    __asm __emit 0x01 \
    __asm __emit 0x48 \
    __asm __emit 0x40 /* JUMP2: inc eax */\
    __asm __emit 0xEB /* jmp JUMP3 */\
    __asm __emit 0x01 \
    __asm __emit 0x35 \
    __asm __emit 0xFF /* JUMP3: jmp eax -> JUMP4 */\
    __asm __emit 0xE0 \
    __asm __emit 0xE7 \
    __asm __emit 0x61 /* JUMP5: popad */\
    }


void Beispiel_Codeverschleierung ()
{
    ANTI_DISASSEMBLING_MACRO(); 
    If (  Check_RegCode() )
    {
         /* RegCode ungültig */
         Goto Exit
     }      
}


Das ANTI_DISASSEMBLING_MACRO fügt folgenden Assemblercode hinzu:
code:

                                  ;..... eigentlicher Code
00000000          60                                           pushad
00000001          e8 03 00 00 00                         call 00000009
00000006          d2 eb                                       shr bl,cl
00000008          0b 58 eb                                   or ebx, [eax-15h]
0000000b          01 48 40                                 add [eax+40h], ecx
0000000e          eb 01                                      jmp 00000011
00000010          35 ff e0 e7 61                          xor eax, 61e7e0ffh
                                  ;..... eigentlicher Code


Aufgrund der Sprunganweisungen mitten in Instruktionen wird der Code sehr unleserlich. Ausgeführt ergibt sich folgender Code:

                                  ;..... eigentlicher Code
00000000          60                                           pushad                        ; Sichert alle Register
00000001          e8 03 00 00 00                         call 00000009               ; Sprung zu der Adresse
00000009          58                                           pop eax                       ; call return Wert in EAX Register = 00000006
0000000A         eb 01                                       jmp 0000000D
0000000D         40                                            inc eax                         ; return Wert um 1 erhöhen
0000000E         eb 01                                       jmp 00000011              ; Sprung
00000011          ff e0                                        jmp eax                       ; Sprung 00000007
00000007          eb 0b                                      jmp 00000014              ; Sprung
00000014          61                                           popad                         ; Register wieder herstellen
                                  ;..... eigentlicher Code



Durch wiederholtes platzieren verschiedenster Anti-Disasembling Makros erhält man eine gute Codeverschleierung.

Natürlich gibt es noch andere Methoden um Code zu verschleiern z.B. Virtuelle Maschine, polymorpher Code oder metamorpher Code, die sind aber wesentlich aufwendiger zu programmieren.

Gruss
Michael

22.03.2008 18:26 Michael Bauer ist offline Email an Michael Bauer senden Homepage von Michael Bauer Beiträge von Michael Bauer suchen Nehmen Sie Michael Bauer in Ihre Freundesliste auf
rob
Grünschnabel


Dabei seit: 21.03.2008
Beiträge: 8

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Wow cool, die Idee mit dem Makros ist genial. Hätte nicht gedacht, dass es so einfach geht.

Die Klons von OllyDbg sind mir bekannt. Den Syser-Debugger kenn ich noch nicht, danke für den Tip. Hast Du eine Idee wie man den erkennen kann?

24.03.2008 11:54 rob ist offline Email an rob senden Beiträge von rob suchen Nehmen Sie rob in Ihre Freundesliste auf
Onyx
Grünschnabel


Dabei seit: 20.03.2008
Beiträge: 2

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Hi,

@rob: es geht auch noch viel leichter und ohne inline assembler.schreibe dir einfach vier bis fünf functions die sich gegenseitig aufrufen und die nach einem speziellen abbruchkriterium enden. wenn du das so programmierst, das sich die functions gegenseitig prüfen und jede funciton ca. 1000 mal aufrufst dann ist das später im debugger ziemlich eklig zu debuggen.
diese functionsaufrufe führst du einfach immer an stellen aus die dir wichtig erscheinen (serial abfrage, hidden checks, speichern, etc.). in dem fall brauchst du dich nicht mit assembler rumärgern und es ist auch relativ schön wartbar, da alles in deiner programmiersprache geschrieben ist.

was das aufspüren von debuggern angeht, gibt es unzählige methoden. bei ring-0 debugger wie softice und syser z.B. kannst du immer die existenz verschiedener treiber prüfen. jeder ring-0 treiber unter windows ist auf einen treiber angewiesen. in der regel haben diese treiber immer den selben namen und man kann diesen überprüfen. existiert der treiber, ist der debugger installiert und du kannst reagieren.

bei ring-3 debugger wie, ollydbg oder der ida-debugger kann man es ähnlich handhaben. überprüfe einfach ob ein prozess mit einem speziellen namen existiert. z.b. "ollydbg.exe", ida.exe und so weiter.
fensternamen eignen sich auch. prüfe aber nicht auf das titelfenster sondern versuche fenstertitel von optionsdialogen und ähnlichem zu finden. das wird seltener gepatched.

noch ein letzter tipp bezüglich obfuscation. wenn du deinen code obfuscierst, sei die darüber im klaren, das du dir sicherheit in diesem fall mit performanceverlust erkaufst. je mehr obfuscation umso mehr performance verliert deine application.

Was antidebugging angeht, so rate ich dir damit nicht zu viel zeit zu verschwenden. antidebugging wird immer umgangen, es ist lediglich eine frage der zeit. jeden debugger und jeden mod davon ins antidebugging aufzunehmen macht keine sinn. könzentriere dich auf generische methoden.

gruß,

onyx.

__________________
Benjamin Gnahm
Reverse Engineer & Software Entwickler
Aladdin Europe GmbH

25.03.2008 10:35 Onyx ist offline Email an Onyx senden Homepage von Onyx Beiträge von Onyx suchen Nehmen Sie Onyx in Ihre Freundesliste auf
rob
Grünschnabel


Dabei seit: 21.03.2008
Beiträge: 8

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Hi Onyx,

danke für Deine Tipps.

Bzgl. Anti-Debuging hätte ich noch die Frage, was genau meinst du mit generischen Methoden? Wäre eine generische Methode z.B. die API-Funktion IsDebuggerPresent()? Hiermit können alle Ring3 Debugger erkannt werden.

Gruß
Rob

26.03.2008 21:19 rob ist offline Email an rob senden Beiträge von rob suchen Nehmen Sie rob in Ihre Freundesliste auf
Michael Bauer Michael Bauer ist männlich
Administrator


Dabei seit: 03.02.2007
Beiträge: 127

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Richtig, die API-Funktion IsDebuggerPresent() wäre eine generische Methode.

Mit generischen Methoden ist gemeint, dass allgemeingültige Debugger-Merkmale überprüft werden sollen wie z.B.:
- mittels IsDebuggerPresent() Funktion
- Erkennung von Breakpoints
- Auswerten des Timingverhaltens z.B. mittels GetTickCount() oder RDTSC

27.03.2008 21:24 Michael Bauer ist offline Email an Michael Bauer senden Homepage von Michael Bauer Beiträge von Michael Bauer suchen Nehmen Sie Michael Bauer in Ihre Freundesliste auf
notme notme ist männlich
Grünschnabel


Dabei seit: 17.04.2008
Beiträge: 9

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Bau Dir ne Random_Obfuscation.. Wenn Du Angst hast das die Performance in den Keller geht, mach ne Messung (wenn es ein aufwendiges Program ist nimm zb. Fraps um DirectX FPS oder ähnliches zu messen).. Bei einer standard Windowsapp wirst Du nichts merken. Von mir geschriebene Engines generieren teilweise für 1 Instruktion 300+~Instruktionen-Junk+die Real und bei einer normalen App merkst Du nichts davon.

Zum Thema Antidebugging...
Das Thema ist wirklich abgegrast. Die wirklich guten Tools sind alle *private* bei den Crackergruppen und die detectest Du mit den herkömmlichen Routinen garantiert nicht. Darauf würde ich garnicht soviel Zeit setzen...

17.04.2008 12:55 notme ist offline Email an notme senden Beiträge von notme suchen Nehmen Sie notme in Ihre Freundesliste auf
rob
Grünschnabel


Dabei seit: 21.03.2008
Beiträge: 8

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Hi,

hättest Du auch ein Beispiel zu Deiner Random_Obfuscation?

Gruss
rob

17.04.2008 22:44 rob ist offline Email an rob senden Beiträge von rob suchen Nehmen Sie rob in Ihre Freundesliste auf
notme notme ist männlich
Grünschnabel


Dabei seit: 17.04.2008
Beiträge: 9

Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       IP Information Zum Anfang der Seite springen

Bei der Random_Obfuscation ändert sich halt einiges, damit der Code nicht mehr statisch analysiert werden kann...

Beispiel an einer realen Instruktion:

mov eax,12345678h

wird zu

pushfd
push ebx
sub eax,eax
mov ebx,12340000h
add eax,ebx
add ebx,987654
pop ebx
add eax,00005678h
popfd

Wobei sich die genutzten Register / Instruktionen natürlich alle verändern...

Das wäre also ein OpcodeExpander, da er aus einer Instruktion ein vielfaches macht. Dann könntest Du nen OpcodePermutator schreiben der die Reihenfolge ändert in der bestimmte Opcodes aufgerufen werden, oder einen OpcodeShrinker... Um komplex dargestellte Instruktionen durch einfache zu ersetzen...

Bei dem ganzen kommst Du um viel Asm nicht herum, aber wenn Du z.B Asm & C++ kannst kannst Du dir da ganz leicht was schreiben.

Gruß

18.04.2008 16:55 notme ist offline Email an notme senden Beiträge von notme suchen Nehmen Sie notme in Ihre Freundesliste auf
 
Neues Thema erstellen Antwort erstellen
Gehe zu:

Links / Impressum
Powered by Burning Board © 2001-2004 WoltLab GmbH
Partnerseiten: virenschutz.info | Hakin9.org