[C] Debugger erkennen - eine Funktion tut's, die andere nicht?!

B

boss3D

Guest
Hallo!

Folgende Aufgabenstellung:

Implementieren Sie zumindest folgende Anti-Debugging-Mechanismen:
- IsDebuggerPresent()
- Unhandled Exception
- OutputDebugString()
Testen Sie die Ausführung sowohl im Debugger als auch ohne.

Hier meine Lösung:
Code:
#include <windows.h>
#include <stdio.h>

LONG WINAPI exHandler(PEXCEPTION_POINTERS pExecpPointers) {
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)pExecpPointers->ContextRecord->Eax);
    pExecpPointers->ContextRecord->Eip += 2;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main(void) {
    
    if (IsDebuggerPresent()) {
        MessageBox(NULL, L"Debugger detected by IsDebuggerPresent!", L"Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, L"No Debugger detected.", L"No Debugger", MB_OK);
    }
    
    DWORD Val = 666;
    SetLastError(Val);
    OutputDebugString(L"anything");
    if (GetLastError() == Val) {
        MessageBox(NULL, L"Debugger detected by OutputDebugString!", L"Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, L"No Debugger detected.", L"No Debugger detected", MB_OK);
    }

    int flag = 0;
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exHandler);
    __asm {
        xor eax, eax;
        div eax;
    }
    MessageBox(NULL, L"No Debugger detected.", L"No Debugger", MB_OK);

    printf("Hello, world!\n");

    return 0;
}
Das Problem:
Führe ich in Visual Studio 2013 "Start Without Debugging" aus, kriege ich trotzdem "Debugger detected by OutputDebugString!".
Führe ich in Visual Studio 2013 "Start Debugging" aus, kriege ich (korrekterweise) "Debugger detected by IsDebuggerPresent!". Danach beendet sich das Programm (wie's sein soll).
^^ Woran könnte das Problem bei OutputDebugString liegen? Ich sehe den Fehler nicht ... :huh:

Danke für baldige Antworten!
 
Es muss irgendwie möglich sein, weil wir im Studium auf Windows 7 PCs arbeiten. Und es passt ja auch schon alles, außer dass OutputDebugString eben genau das "verkehrte" erkennt ...
 
Moment.. worum gehts dir?
Wollt ihr nur einen "normalen netten" Debugger wie gdb und den von VS erkennen oder
geht es hier um Sicherheitstechnisches, wo man jegliche Art von überwachter Ausführung unterbinden soll?
 
VS ist nur die IDE meiner Wahl. Ich hätte das auch mit allem möglichen anderen schreiben können ...

Es geht darum, eben einen C Code (und später das ganze auch in Assembler) zu schreiben, der die drei genannten Funktionen zur Erkennung eines Debuggers implementiert. Anschließend soll ich das ganze im OllyDbg (unter Windows 2000) manuell umgehen. Und dann das ganze mit Hilfe von Plugins im Debugger umgehen.
 
Es muss irgendwie möglich sein, weil wir im Studium auf Windows 7 PCs arbeiten. Und es passt ja auch schon alles, außer dass OutputDebugString eben genau das "verkehrte" erkennt ...
In Windows 7 verändert OutputDebugString nicht den letzten Error code, das meinte ich. Daher erkennt dein Programm das auch nicht richtig. Unter Windows XP müsste das funktionieren.
 
^^ Achso, hm ... Ich habe jetzt versucht, den Code unter Windows 2000 in OllyDbg zu starten (die .exe), allerdings kommt da gleich ein Error, dass mein Programm keine gültige Win32 Anwenung sei. Weil ich es unter Windows 7 64 erstellt habe? K. A. ... :huh:
Visual Studio 2013 habe ich ja auch in der 32 bit Version (da gibt's ja gar keine 64 bit, oder?) zum Programmieren des Codes verwendet.
 
Visual Studio ist die Entwicklungsumgebung, die es tatsächlich nur in 32bit gibt. Aber das ist egal. Dein Programm ist für die Architektur, für welche es der Compiler compiliert hat. Und den Compiler kannst du oben in VS umstellen (da is so ein Dropdown Menü wo man zwischen x86 und x64 auswählen kann).
 
^^ Kannst du's bitte auf meinem Screenshot markieren, wo genau ich schauen soll?! So finde ich das nicht ...

Untitled.png
 
Auf deinem Screenshot isses nich drauf. Was mich wundert. Eventuell liegt es an einer anderen VS Version, aber eigentlich nicht. Es müsste direkt neben Dropdown menü "Debug" sein. Sonst such mal in den Einstellungen zu deinem Projekt.
ABER: Ich hab nie gesagt, dass das der Fehler ist, der dich gerade stört. ollydbg sollte eigentlich auch x64 Code debuggen können oder ähnliches.
Was du allerdings mit dem Compiler noch bedenken solltest: Wenn du mit dem Standard Visual C++ Compiler in der neusten Version kompilierst, gibts sicher Probleme in Bezug auf Laufzeitbibliotheken. Selbst WinXp wird nurnoch teilweise unterstützt (oder so). Windows 2000 wird echt verdammt schwer.

Aber ich hab nich wirkliche ne Ahnung. Ich geb dir nur ein paar Hinweise woran es liegen könnte.
 
^^ Irgendwie muss sich das ganze lösen lassen, sonst würde ja die ganze Übung nicht gehen. Windows 2000 habe ich in einer VM. Da drinnen muss es auch irgendeinen Compiler geben, aber ich habe noch nichts gefunden. Wenn ich den Code aber einfach unter Windows 2000 kompiliere, dann müsste ihn auch der in der VM enthaltene OllyDbg ausführen können ...
 
Du könntest es mal mit MinGW probieren. Mit Visual Studio geht das AFAIK nur bis VS2008, danach wird Windows 2000 nicht mehr als Plattform unterstützt.
 
Internetzugriff ist für die VM gesperrt, da kriege ich MinGW nicht rein.
(Das downloadbare File ist ja auch nur ein "Starter", der dann während der Installation die Daten herunterladen will)
 
Kannst du das denn mit MinGW (oder älterem VS) auf nem anderen Rechner kompilieren und das dann in die VM packen?
 
Ich habe jetzt MinGW auf meinem Windows 7 installiert, aber was fange ich dann damit an? Ich habe folgenden Aufruf im Command Prompt probiert: "mingw -std=99 -pedantic -Wall -o filename.exe", aber da kommt nur "'mingw' ist not recognized as an internal or external command, operable program or batch file" ...
 
^^ Nein, ich blicke da gar nicht durch. Die Doku ist auch nicht die geringste Hilfe ... :(

[EDIT]
Hab's jetzt doch geschafft, die PATH Variable zu setzen, kommt aber immer noch der gleiche Fehler.

[EDIT2]
Ich pfeif auf die PATH Variable. Ich habe jetzt einfach mein C file in das Vezeichnis von gcc reinkopiert und das ganze dann so aufgerufen. So arbeitet der Compiler zumindest, allerdings kriege ich (neben unzähligen Warnings) folgende Errors:

Capture1.JPG

Hier nochmal der Code (nicht Zeilen-zählen, weil ich oben ein paar Kommentare gelöscht habe. Ich habe den Bereich blau markiert, wo die Fehler her sind [Zeile 36 - 38]):
Code:
#include <windows.h>
#include <stdio.h>

LONG WINAPI exHandler(PEXCEPTION_POINTERS pExecpPointers) {
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)pExecpPointers->ContextRecord->Eax);
    pExecpPointers->ContextRecord->Eip += 2;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main(void) {
    
    if (IsDebuggerPresent()) {
        MessageBox(NULL, L"Debugger detected by IsDebuggerPresent!", L"Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, L"No Debugger detected.", L"No Debugger", MB_OK);
    }
    
    DWORD Val = 666;
    SetLastError(Val);
    OutputDebugString(L"anything");
    if (GetLastError() == Val) {
        MessageBox(NULL, L"Debugger detected by OutputDebugString!", L"Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, L"No Debugger detected.", L"No Debugger detected", MB_OK);
    }

    int flag = 0;
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exHandler);
    [COLOR=royalblue][B]__asm {
        xor eax, eax;
        div eax;[/B]    }
    MessageBox(NULL, L"No Debugger detected.", L"No Debugger", MB_OK);

    printf("Hello, world!\n");

    return 0;
}
^^ Kann mir bitte jemand helfen, die Errors weg zu kriegen?!
 
Zuletzt bearbeitet:
Der inline Assembler sieht in gcc anders aus als in MS, den müsstest du neu schreiben. Kann auch sein, dass du von der Intel Syntax auf die AT&T Syntax wechseln musst, wobei ich da mal irgendwo nen flag gesehen habe, wie man dem gcc die Verwendung der Intel Syntax klarmacht...
 
Ah, danke. Das Umschreiben habe ich geschafft und damit die Errors weggekriegt, aber leider kommt beim Kompilieren keine exe raus?! :huh:
Folgender Befehl: gcc -std=c99 -pedantic -Wall mal.c -o mal
Code:
#include <windows.h>
#include <stdio.h>

LONG WINAPI exHandler(PEXCEPTION_POINTERS pExecpPointers) {
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)pExecpPointers->ContextRecord->Eax);
    pExecpPointers->ContextRecord->Eip += 2;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main(void) {
    
    if (IsDebuggerPresent()) {
        MessageBox(NULL, "Debugger detected by IsDebuggerPresent!", "Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, "No Debugger detected.", "No Debugger", MB_OK);
    }
    
    DWORD Val = 666;
    SetLastError(Val);
    OutputDebugString("anything");
    if (GetLastError() == Val) {
        MessageBox(NULL, "Debugger detected by OutputDebugString!", "Debugger detected", MB_OK);
        exit(0);
    } else {
        MessageBox(NULL, "No Debugger detected.", "No Debugger detected", MB_OK);
    }

    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exHandler);
    asm("xorl %eax, %eax\n\t");
    asm("divl eax");
    MessageBox(NULL, "No Debugger detected.", "No Debugger", MB_OK);

    printf("Hello, world!\n");

    return 0;
}
Hier noch die Warnings.

Capture.JPG

Beim googeln bin ich auf folgendes gestoßen:
According to the C standard (appendix J.5.10), asm is a common language extension. In gcc it is disallowed (together with all gcc extensions), if you use a flag like -std=c90, -std=c99 or -ansi. If you want C99 with gcc extensions, use -std=gnu99 instead.
^^ Scheint dann einfach an meinen Befehlsparametern zu liegen?!

Ist jetzt aber auch nicht mehr wirklich schlimm. Viel wichtiger wäre mir, eine mal.exe dabei rauszukriegen, die ich dann in die VM reintun und dort mit OllyDbg testen kann! *Hilfe*
 
Zurück