[C++] DLL-Injection

Hallo Leute

Bin neu hier in dem Forum....
Habe mich letzte Tage mal mit DLL-Injection auseinander gesetzt.
Bin dabei auf den Beitrag http://wiki.hackerboard.de/index.php/DLL-Injection im HaBo-Wiki gestoßen.

Natürlich sofort ausprobiert ;-)

Allerdings habe ich nun ein Problem:
Immer wenn ich CreateRemoteThread benutze, scheißt der Zielprozess ab...

Code:
WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL);
	CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0);
	WaitForSingleObject(hProc,INFINITE);
	CloseHandle(hProc);

Dies sind die letzten Zeilen meines Programms.
Hat Jemand eine Idee, warum es dort kracht?

Und ja, natürlich habe ich schon gegoogled und etc. ;-)
Über ne schnelle Hilfe wär ich sehr dankbar 8) :)
Ich benutze msvc++ 2008 Express

Gruß
TheMapf
 
Ich habe den Beitrag mal in einen Extrathread verschoben, da es sich hier um ein konkretes Problem handelt ;)

Zum Thema:
vor allem hier:
Code:
DWORD WINAPI threadstart(LPVOID addr)
{
	HINSTANCE hDll;
	fpFunktion funktion;
	INJECTSTRUCT * is = (INJECTSTRUCT*)addr;       
	hDll = is->LoadLibrary(is->path);
	funktion = (fpFunktion)is->GetProcAddress(hDll, is->func);
	funktion();
	return 0;
}
void threadend()
{
}
kann es gut sein, dass der Compiler die Funktionen im Maschinencode woanders platziert, so dass funcsize nicht mehr korrekt berechnet wird.

Überprüfe mal entweder mit einem Debugger oder in dem Du die Rückgabewerte auswertest, ob WriteProcess erfolgreich war und zusätzlich mittels dem
lpNumberOfBytesWritten Parameter im WriteProcessMemory Aufruf, wieviele Bytes geschrieben wurden.
 
Ja, stimmt...Es ist ein konkretes Problem :D Wollte nur nicht unnötig Threads eröffnen, dache es passt da gut rein :-). Aber danke!

Also ich bin nicht der hellste in Sachen Programmierung, aber ich verstehe in etwa was Du meinst CDW.
Ich werde bei Gelegenheit natürlich schauen, das ich mir das Ding mal mit dem Debugger zur Brust nehme, denn es KOTZT mich förmlich an mittlerweiel, dass es nicht geht :D

Wenn Jemand noch weitere Tipps dazu hat, BITTE immer her damit ! :)

/*
EDIT:
Also WriteProcessMemory gibt 1 zurück..demnach schlägt es nicht fehl :)
Aber ich komm gerade nicht weiter, wie gebe ich eine Variable des Types SIZE_T mit Printf aus? %i ?....Muss die Uhrzeit sein :D :x

....Habe mich nun doch noch drangesetzt...xD
Code:
printf("Funktion Size:        %d\n",funcsize);
printf("Written Bytes:        %i\n",writtenBytes);
Die Ausgaben stimmen miteinander überein. Beides 48
*/

Gruß
TheMapf
 
Wie gesagt, ich kann nich nicht allzuviel,
aber sowie ich das einschätzen würde, würde ich glatt sagen ne.
Aber mag sein das ich mich täusche :D
 
schreib doch mal das, was WriteProcessMemory in den Speicher schreibt, zusätzlich in eine Datei und häng die hier mal an. Denn 48 Bytes sind tatsächlich etwas wenig - alleine die API Strings dürften 37 Bytes beanspruchen.

Alternativ setze die funcsize "manuell" auf 512 oder 1024. Wegen dem "Return" am Ende der Funktion ist es eher nicht so schlimm, wenn man "mehr" schreibt. Der Code nach Return wird dann eher nicht ausgeführt.
 
So so, in eine Datei schreiben.......ehhhhhhhhm...wie mach ich das? :x ;D

Schon dumm, versuche eine DLL zu injecten aber kann so'n pislfitz nicht :D
Ich schau mal ob ich es hinbekomme :)

/*
EDIT:
Also ich habe funcsize mal einmal auf 1024 und nochmal auf 2048 gesetzt, trotz dessen kackt Notepad dann ab. In der Ausgabe hat er mir auch bestätigt, dass jeweils soviel Byte geschrieben wurden.

Das mit der Datei, da wusel ich noch rum. Wenn mir Jemand helfen könnte, wäre ich sehr glücklich! :D
*/
 
Original von CDW
schreib doch mal das, was WriteProcessMemory in den Speicher schreibt, zusätzlich in eine Datei und häng die hier mal an. Denn 48 Bytes sind tatsächlich etwas wenig - alleine die API Strings dürften 37 Bytes beanspruchen.

Ich glaube nicht, dass 48 Bytes zu wenig sind: Der Datei- und Funktionsname ist in dem INJECTSTRUCT und die Adresse von LoadLibrary wird vor dem Injecten ermitteln und in das struct eingefügt. Übrig bleibt also nur noch:
Code:
	HINSTANCE hDll;
	fpFunktion funktion;
	INJECTSTRUCT * is = (INJECTSTRUCT*)addr;       
	hDll = is->LoadLibrary(is->path);
	funktion = (fpFunktion)is->GetProcAddress(hDll, is->func);
	funktion();
	return 0;
Dafür könnten 48 Byte durchaus hinkommen.

Ansonsten: Ich finde es sinnvoller die Funktion, die die DLL lädt, "manuell" in den Speicher zu schreiben, da man sich dann nicht mehr mit den Compileroptimierungen etc. rumschlagen muss.
 
Also statt der DLL einfach meine Funktion dareinschreiben meinst du?

Soetwas ist mir auch schon in den Sinn gekommen, aber wenn es mehrer Funktionen sind und umfangreichere...Dann ist es denk ich doch praktischer diese in eine DLL zu packen und dann die DLL zu laden, oder nicht?

/*
EDIT:
Mit der Datei habe ich es immernoch nicht hinbekommen :-(
*/
 
Original von TheMapf
Also statt der DLL einfach meine Funktion dareinschreiben meinst du?

Soetwas ist mir auch schon in den Sinn gekommen, aber wenn es mehrer Funktionen sind und umfangreichere...Dann ist es denk ich doch praktischer diese in eine DLL zu packen und dann die DLL zu laden, oder nicht?

/*
EDIT:
Mit der Datei habe ich es immernoch nicht hinbekommen :-(
*/

Nein, ich meinte den Aufruf von LoadLibrary direkt in den Prozess schreiben, ohne dass man diesen aus dem eigenen Programm vorher ausliest(hier threadstart), was anfällig für Compileroptimierungen ist.
Bezüglich der Ausgabe in eine Datei schau dir mal fprintf (C) oder fstream (C++) an.
 
Ja man könnte, klar, wenn man wüsste wie's geht, lol.

Und ja klar, fprint kenn ich ja...
Das sind meine beiden WirteProcessMemory-Zeilen:
Code:
checkWPM1 = WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL);
thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
checkWPM2 = WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, &writtenBytes);

Im ersten wird ja die INJECTSTRUCT-Struktur geschrieben, und im zweiten ja der threadstart Shit...Wie soll ich dann, dass, was WirteProcessMemory in den Speicher schreibt in deine Datei schreiben?

Leuchtet mir gerade nicht ein :(
 
Du öffnest eine Datei, und schreibst die selben Bytes, die du WriteProcessMemory schreiben lässt, auch in die Datei rein(start bzw. thread).
 
in etwa so müsste es laufen:
Code:
  FILE *file;
  file=fopen("output.txt","wb");
  if (file==NULL)
  {
     printf("fehler beim erstellen!");
  } 
  fwrite(&is,sizeof(INJECTSTRUCT),1,file);
  fclose(file);
(nur GCC getestet).
 
das hab ich letztens als teil eines schulprojekts abgegeben...

nicht zum einfügen in deinen code durch copy paste geeignet ^^...

kommentare hab ich jetzt eingefügt, waren vorher nicht.

es ist so ziemlich der gleiche ansatz, lediglich vereinfachter.

Code:
   // Speicher im fremden prozess anlegen ( hExp = HANDLE auf den prozess ) und davon die start adresse speicher ( minimum werden 4kb reserviert )
    unsigned BaseAddr = (unsigned)VirtualAllocEx( It->hExp, NULL, DllPath.length() + 50, MEM_COMMIT, PAGE_READWRITE );
    if ( !BaseAddr ){ // wenn virtual alloc fehlgeschlagen, beenden :) 
      //continue;  
    }
   // Länge des DLL namens ermitteln, und neues array anlegen, 10 mehr weil baum ^^
    int BufferLen = DllPath.length() + 10;
    char * Buffer = new char[BufferLen];
    // DLL namen in den buffer kopieren
    std::fill(Buffer,Buffer+BufferLen,0);
    std::copy(DllPath.begin(),DllPath.end(),Buffer);
    SIZE_T WB;
    // den buffer in den fremden prozess schreiben, an die adresse des reservierten speichers
    if ( !WriteProcessMemory( It->hExp, (LPVOID)BaseAddr, Buffer, BufferLen, &WB ) ){
      continue;
    }

    
   // Thread im fremden prozess starten, mit loadlibary als startadresse
   // Parameter wird der anfang des DLL namens im fremden prozess 
   if ( !CreateRemoteThread( It->hExp,
                              NULL,
                              0,
                              (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"),
                              (LPVOID)BaseAddr,
                              0,
                              &ThreadId ) ){

     //wenn fehlgeschlagen -> continue;
    }
  }

übrigens das konzept ist nicht von mir, das hab ich mir aus der beschreibung ( nicht dem projekt ) hier geholt ^.^

http://www.codeproject.com/KB/system/hooksys.aspx
 
Hallo Leute!

Erstmal danke für Eure Antworten!
Ich habe die letzten Tage leider null Zeit für Coding usw. .. :(

Sobald ich wieder Zeit habe, melde ich mich 8-)
Werde natürlich frühstmöglich versuchen die neuen Ansätze zu probieren :)

Bis dahin :)

/*
EDIT:
So, ich habe jetzt mal &is und threadstart in 2 *.txt's geschrieben. Ihr findet die im Anhang

CDW, ich hoffe es ist das, was Du haben wolltest
*/

Gruß
TheMapf
 
Zurück
Oben