Crash bei: CreateRemoteThread Code-Injection

Guten Abend,

zuerst möchte ich mich dafür entschuldigen einen solch alten thread wieder ins Leben zu rufen.

Ich habe mir den Code von Biohazard angesehen und ihn auf meine Bedürfnisse umgeändert.

hier einmal meine Opfer exe:

Code:
#include <stdio.h>
#include <windows.h>

void Burn(int a,int b){
     printf("%i %i\n",a,b);
     return;    
}

int main(){
    Burn(1,2);
    SetConsoleTitle( TEXT("Opferprogramm") );
    getchar();
    return 0;   
}

und hier mein programm, mit welchem ich versuchen möchte die Funktion Burn aufzurufen:

Code:
#include <iostream>
#include <conio.h>
#include <windows.h>

#define NOP 0x90
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)

using namespace std;

typedef void (*burn)(int,int);

struct Parameter{
  burn pFunc;
  int a;
  int b;     
};

static void burnFunc(Parameter *p)
{  
   p->pFunc(p->a,p->b);
}
void endFunc(void) { }


void main (void)
{
    Parameter p;
    p.a = 10;
    p.b = 20;
    //Adresse der Funktion void burn(int,int) in burn.exe
    p.pFunc = (burn)0x00F81009;

    LPVOID param,func;
    HANDLE hThread;

    HWND hWindow;
    hWindow = FindWindow (NULL, TEXT ("Opferprogramm"));
    if (hWindow)
    {
        printf ("Opferprogramm wurde gefunden.\n");
        DWORD hProcessId;
        HANDLE hProcess;
        GetWindowThreadProcessId (hWindow, &hProcessId);
        hProcess = OpenProcess (CREATE_THREAD_ACCESS, NULL, hProcessId);

        cout << "hProcessId:\t" << hProcessId << "\n";

        //Speicher für Parameter Struktur reservieren
        param=VirtualAllocEx(hProcess, NULL, sizeof(Parameter), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        cout << "param:\t" << param << "sizeof (Parameter)" << sizeof (Parameter) << "\n";
    
        //Speicher für Funktion reservieren
        func=VirtualAllocEx(hProcess, NULL, (DWORD)((DWORD)endFunc-(DWORD)burnFunc), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        cout << "func:\t" << func << "\n";
    
        //Parameter schreiben
        WriteProcessMemory(hProcess, param, (LPVOID)&p, sizeof(Parameter), NULL);

        cout << "param:\t" << param << "\n";
    
        //Funktion reinschreiben
        WriteProcessMemory(hProcess, func, (LPVOID)burnFunc, (DWORD)((DWORD)endFunc-(DWORD)burnFunc), NULL);

        cout << "func:\t" << func << "\n";
    
        //Funktion aufrufen
        hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)func, param, 0, NULL);

        cout << "hThread:\t" << hThread << "\n";

        //Warten bis Thread fertig
        WaitForSingleObject(hThread,INFINITE);
        
        //Funktion aus dem Speicher entfernen
        VirtualFreeEx(hProcess,(LPVOID)func,0,MEM_RELEASE);
    
        //Parameter entfernen
        VirtualFreeEx(hProcess,(LPVOID)param,0,MEM_RELEASE);
        
        //Handle schließen
        CloseHandle(hProcess);
    }
    else
    {
        printf ("Opferprogramm konnte nicht gefunden werden.\n");
    }
    getch ();
}

doch leider bringt das mein Opferprogramm nur zum crashen.

Die Adresse habe ich mir mit ollydbg rausgesucht, und habe natürlich die genommen wo der Call steht.

hier die paar zeilen aus ollydbg:

Code:
00F81000 >/$ 6A 02          PUSH 2                                   ; /<%i> = 2
00F81002  |. 6A 01          PUSH 1                                   ; |<%i> = 1
00F81004  |. 68 F420F800    PUSH OFFSET Opferpro.??_C@_06DLCJAAAF@?$>; |format = "%i %i
"
00F81009  |. FF15 A420F800  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf

MfG
 
Zuletzt bearbeitet von einem Moderator:
Deine Adressen kommen mir etwas komisch vor. Ist es eine DLL oder sind es die "RandomLayout" Features von Windows Vista/7 ? (üblicherweise hatte sonst eine Exe 0x400000 oder 0x1000000 als Imagebase).
Wie dem auch sei: wenn Du sicher bist, dass die Adressen stimmen, solltest Du die Adresse der "Burn" Funktion direkt aufrufen. Denn im Moment rufst Du
Code:
00F81009  |. FF15 A420F800  CALL DWORD PTR DS:[<&MSVCR90.printf>]
also "printf" auf. Mit 2 integer-Parametern (obwohl printf eigentlich den ersten dann als Format-String nimmt ;)). Das würde den Crash gut erklären.

Bei mir jedenfalls sitzt die "Burn" an 004012D0.
Code:
004012D0  /$  55            PUSH EBP
004012D1  |.  89E5          MOV EBP,ESP
004012D3  |.  83EC 18       SUB ESP,18
004012D6  |.  8B45 0C       MOV EAX,[ARG.2]                          ; |
004012D9  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ; |
004012DD  |.  8B45 08       MOV EAX,[ARG.1]                          ; |
004012E0  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ; |
004012E4  |.  C70424 003040>MOV DWORD PTR SS:[ESP],opfer.00403000    ; |ASCII "%i %i",LF
004012EB  |.  E8 00020000   CALL <JMP.&msvcrt.printf>                ; \printf
004012F0  |.  C9            LEAVE
004012F1  \.  C3            RETN
(compiliert mit "gcc main.c -o opfer.exe", wobei mein Windows-gcc noch im 4.3 Versionsbereich ansiedelt).
Passe ich Deinen Source an (also meine Adresse einsetzen) und compiliere es mit "g++ injector.cpp -o injector"
So klappt es mit dem RemoteThread - Aufruf auf meiner XP-Maschine:
Injector-Ausgabe:
Code:
Opferprogramm wurde gefunden.
hProcessId:     2312
param:  0x3f0000sizeof (Parameter)12
func:   0x460000
param:  0x3f0000
func:   0x460000
hThread:        0x34
Opfer.exe:
Code:
1 2
10 20
Edit: Habe den Beitrag nun als Extra-Thema platziert (bessere Übersicht + Grundsatz: "bei neuen Problemen ein neuer Thread" ;) )
 
hmm, erst einmal danke für deine Mühe!

ich dachte mir schon, dass es nicht die richtige adresse sein kann, dennoch habe ich jetzt ein Problem. (Ich compilere meine .exe-Konsolenanwendung in Visual Studio 2008 mit den Standart einstellungen).

Wenn ich diese dann in ollydbg lade, kommen solche Adressen raus wie oben gepostet, nichts mit 0x400000. Außerdem sind die Adressen welche ich bekomme alle dynamisch also immer unterschiedlich.

Mache ich nun etwas direkt beim Compilern falsch oder bei der Benutzung von ollydbg?
 
sehr schön, danke, dass mit den dynamischen Adressen wäre geklärt, danke!

doch ein weiteres problem bleibt trotzdem.

Code:
004012D0  /$  55            PUSH EBP
004012D1  |.  89E5          MOV EBP,ESP
004012D3  |.  83EC 18       SUB ESP,18
004012D6  |.  8B45 0C       MOV EAX,[ARG.2]                          ; |
004012D9  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ; |
004012DD  |.  8B45 08       MOV EAX,[ARG.1]                          ; |
004012E0  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ; |
004012E4  |.  C70424 003040>MOV DWORD PTR SS:[ESP],opfer.00403000    ; |ASCII "%i %i",LF
004012EB  |.  E8 00020000   CALL <JMP.&msvcrt.printf>                ; \printf
004012F0  |.  C9            LEAVE
004012F1  \.  C3            RETN

wo bekommst du bitteschön diesen code her :s
ich habe nach "all intermodular calls" gesucht, hab alles mögliche mit brakepoints ausprobiert, doch ich komme immer wieder nur auf diesen code hier:

HTML:
00401000 >/$ 6A 02          PUSH 2                                   ; /<%i> = 2
00401002  |. 68 21320100    PUSH 13221                               ; |<%i> = 13221 (78369.)
00401007  |. 68 F4204000    PUSH OFFSET Opferpro.??_C@_06DLCJAAAF@?$>; |format = "%i %i
"
0040100C  |. FF15 A4204000  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf
(den wert mit den 13221 hab ich jetzt nur hier stehen, da ich den einen Übergabeparameter in meiner Opfer-exe testweise geändert hatte)

und hier noch mal ein bild zur besseren vorstellung:
ollydbg4.png


was mache ich falsch?
 
Zuletzt bearbeitet:
wo bekommst du bitteschön diesen code her :s
aus dem gcc :)
was mache ich falsch?
Du optimierst :)
Zumindest schaut es so aus, als ob der Compiler die Funktion automatisch inlinen würde (da sie ja nur 1 mal aufgerufen wird). Irgendwo in den Tiefen der Einstellungen müsste der Optimierungsgrad zu finden sein. Oder im Zweifelsfall die Debugversion der Exe ausprobieren. Oder es mit
Code:
__declspec(noinline) void Burn(
Anweisung versuchen.
 
ich sitze gerade in der Schule und habe es nach vielen probieren endlich geschaft die exe so zu generieren, das der von dir oben gepostet code in ähnlicher form zu stande kommt :)

werde dann daheim den injector ausprobieren (funktioniert hier nicht, habe keine adminrechte an den rechnern) :(

sollten noch probleme auftreten, werde ich meinen post editieren.

Vielen dank für eure hilfe und die mühe mit dem thread!

//edit

sehr schön, konnte nun testen und es funktioniert wie gewollt :) danke
 
Zuletzt bearbeitet:
Zurück
Oben