C/C++: Wer testet/verbessert mein kleines Experiment?

Diskutiere mit über: C/C++: Wer testet/verbessert mein kleines Experiment? im Mac OS X Entwickler, Programmierer Forum

  1. der_Kay

    der_Kay Thread Starter MacUser Mitglied

    Beiträge:
    1.693
    Zustimmungen:
    7
    Registriert seit:
    02.09.2004
    Hallo,

    ich versuche mich gerade an Anti-cracking/reverse-engineering-Tricks. Ein Schritt dazu ist gepackter (verschlüsselter und signierter) Code, oder Teile davon. Dazu muss man vorab assemblierten Code im Quelltext unterbringen, zur Laufzeit entpacken und dann die Anwendung auf den Speicherbereich springen lassen, wo der Code entpackt/hinkopiert wurde. Das bringt Disassembler/Debugger fürs erste aus dem Trab und hilft, die Routine für die Seriennummer zu verstecken.

    Auf einem intel-Prozessor (unter Windows) weiss man genau, wie die CPU den Stack verwendet um Rücksprungadressen und Variablen zu verwalten aber von PowerPC-Assembler hab ich keinen blassen Schimmer. Ich dachte, vielleicht geht das auch ohne.

    Und zu meiner Verblüffung scheint das der Fall zu sein: Untenstehend ein simples Programm mit einem Block "roh" assemblierten PowerPC-Codes, der (hoffentlich) eine triviale C-Funktion ("do_exp_sqrt") implementiert, die die Wurzel aus dem Logarithmus zur Basis 10 einer double zurückgibt.

    Als weiteres Problem ergibt sich, das der kompilierte Code keine Importtabelle abbekommt; ich übergebe als Abhilfe eine "Mini-Importtabelle" als Pointer-Array in einem Argument, in dem Fall die Adressen von sqrt und log10 aus der math-library.

    Wie schon erwähnt, funktioniert das auf meinem G4 (MPC7447A, OS X 10.4.7): Es schreibt brav sqrt(log10(10000.0))=2.0 in die Konsole. :D

    Meine Fragen:
    - Kann das mal wer auf einem G5 ausprobieren?
    - Kann man sich darauf verlassen/ist garantiert, dass das immer funktioniert? Insbesondere: Funkt das Betriebssystem nie dazwischen, wenn man Code auf dem Heap laufen lässt?
    - Verstosse ich u. U. gegen Aufrufkonventionen, wenn ich den Code einfach per Cast in den Heap springen lasse? Kann das Probleme mit den Rücksprungadressen auf dem Stack geben?
    - Kann es sein, dass einem solche Sachen in "großen" Programmen "um die Ohren fliegen"?
    - Ob das auch mit dynamischen Bibliotheken klappt?

    Ich würde mich freuen, wenn sich nun jemand inspiriert fühlt und das z.B. weiterbastelt, austestet und ein paar Sachen mehr ausprobiert. Ideen gibt es genug; z.B. Packen, Verschlüsseln, Signaturen(<- interessant), Selbstmodifikation usw.

    Zum Assemblieren habe ich pasm - a portable PowerPC assembler verwendet, den ich leicht patchen musste; binary im ZIP-File. Irgendwie ging das mit as nicht.

    Alles Wissenswerte/Quellcode/Tools/binaries im ZIP untendran; Anleitungen in den Quellcode-Dateien.
    PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>
    #include <math.h>

    #define BYTE unsigned char

    /*
    double do_exp_sqrt ( double d, void** import_table  )
    {
        DFD dfd1 =     (double (*) (double)) import_table[0],
            dfd2 =     (double (*) (double)) import_table[1];

        return (*dfd2)((*dfd1)(d)); 

    */
    /* kompilierter Code */
    BYTE code [] = {
        
    0x7c0x080x020xa60xbf0xc10xff0xf80x900x01
        
    0x000x080x940x210xff0xa00x7c0x3e0x0b0x78
        
    0xd80x3e0x000x480x900xbe0x000x800x800x5e
        
    0x000x800x800x020x000x000x900x1e0x000x3c
        
    0x800x5e0x000x800x380x420x000x040x800x02
        
    0x000x000x900x1e0x000x380x800x1e0x000x3c
        
    0xc80x3e0x000x480x7c0x0c0x030x780x7d0x89
        
    0x030xa60x4e0x800x040x210xfc0x000x080x90
        
    0x800x1e0x000x380xfc0x200x000x900x7c0x0c
        
    0x030x780x7d0x890x030xa60x4e0x800x040x21
        
    0xfc0x000x080x900xfc0x200x000x900x800x21
        
    0x000x000x800x010x000x080x7c0x080x030xa6
        
    0xbb0xc10xff0xf80x4e0x800x000x20
    };

    /*    Funktionszeigerdeklaration für sqrt() & log10() */
    typedef double (*DoubleFuncDouble) (double);

    /*    Funktionszeigerdeklaration für kompilierten Code    */
    typedef double (*DoubleFuncDoubleVoidPP) (doublevoid**);

    /*    leserlicheres Typecasting auf obigen Funktionszeiger     */
    #define CAST_DFDVPP(pointer) (double (*)(double, void**)) (pointer)

    int main int argcchar** argv )
    {
        
    /*    Mini-Importtabelle    */
        
    DoubleFuncDouble my_import_table [] = { log10sqrt };
        
        
    /*    Platz für den Code    */
        
    voidcode_relocated malloc sizeof code ) );
        
        
    /*    Funktionszeiger für impliziten Aufruf */
        
    DoubleFuncDoubleVoidPP func CAST_DFDVPP(code_relocated);
        
        
    /*    wird 2.0 ;)    */
        
    double result;
        
        
    /*    Codeblock auf den Heap kopieren, später entpacken usw....    */
        
    memcpy(code_relocatedcodesizeofcode )); 
        
        
    /*    Spannung...    */
        
    result = (*func)( 10000.0, (void**) my_import_table);

        
    printf("%f\n"result);

        
    /* damit keiner hinterher hineinschaut ;) */
        
    memset (code_relocated0sizeof(code));
        
        
    free code_relocated );
        
        return 
    0;    
    }
    Viel Spass,

    Kay
     

    Anhänge:

    Zuletzt bearbeitet: 28.08.2006
Die Seite wird geladen...
Ähnliche Themen - C++ testet verbessert Forum Datum
Suche einfache IDE für C Mac OS X Entwickler, Programmierer 13.08.2016
C++ Programm von Windows zu Mac? Mac OS X Entwickler, Programmierer 05.05.2016
Buchtip für C++ Mac OS X Entwickler, Programmierer 13.10.2015
C: Array in Funktionsprototyp Mac OS X Entwickler, Programmierer 26.08.2015
C - Problem mit "fflush(stdin); wahl = getchar();" unter OSX? Mac OS X Entwickler, Programmierer 13.06.2015

Diese Seite empfehlen

Benutzerdefinierte Suche