[c++] DLL Injector Problem

07/28/2012 12:33 hackiosa#1
Hallo,

ich hab ein Problem mit meinem DLL Injector Source Code.
Er kompiliert (mit CodeBlocks u. MinGW) problemlos aber er funktioniert einfach nicht, d.h er lädt die DLL nicht.
Das ist der Source:
Code:
#include <windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <iostream>

using namespace std;

BOOL DllInject(char* process, char* dll);
int GetProcessIdByName(char* prc);

int main(INT argc, char* argv[])
{
    if (argc != 3)
        puts("Usage: dll.exe process dll");

    cout << argv[1] << endl;

    DllInject(argv[1], argv[2]);
    return 0;
}

BOOL DllInject(char* process, char* dll)
{
    INT pid = GetProcessIdByName(process);
    HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, false, pid);
    LPVOID FreeSpace = VirtualAllocEx(hProcess, NULL, strlen(dll)+1, MEM_COMMIT, PAGE_READWRITE);
    HANDLE hThread;

    WriteProcessMemory(hProcess, FreeSpace, &dll, strlen(dll), NULL);
    hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA"), FreeSpace, NULL, NULL);

    if (!hThread)
        return false;
    CloseHandle(hThread);

    return true;
}

int GetProcessIdByName(char* prc)
{
    PROCESSENTRY32 pe;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    Process32First(hSnapshot, &pe);
    while (Process32Next(hSnapshot, &pe))
    {
        if (strcmp(pe.szExeFile, prc) == 0)
        {
            return pe.th32ProcessID;
        }
    }
    return 0;
}
Vielen Dank im Vorraus !
EDIT: Kann es daran liegen, dass ich Win7 64bit verwenden? Wenn ja wie kann ich ihn kompatibel machen, bzw. kann mir wenigstens jemand sagen ob er unter 32 bit funktioniert?
07/28/2012 12:41 Dr. Coxxy#2
Quote:
Originally Posted by hackiosa View Post
Hallo,

ich hab ein Problem mit meinem DLL Injector Source Code.
Er kompiliert (mit CodeBlocks u. MinGW) problemlos aber er funktioniert einfach nicht, d.h er lädt die DLL nicht.
Das ist der Source:
Code:
VirtualAllocEx(hProcess, NULL, strlen(dll)+1, [COLOR="Red"]MEM_RESERVE|[/COLOR]MEM_COMMIT, PAGE_READWRITE);
Code:
WriteProcessMemory(hProcess, FreeSpace, [COLOR="Red"]dll[/COLOR], strlen(dll), NULL);
Außerdem weise ich darauf hin, dass du deinen erstellten speicher nach erfolgreichem injecten mit virtualfreeex wieder freigeben solltest.
07/28/2012 13:19 hackiosa#3
Danke aber er kriegt anscheinend nichtmal gebacken den Path in den Prozess zu schreiben, trotz der Verbesserung..
Ich denke ich werde mal ne VM mit 32 bit installieren und dort testen.
07/28/2012 14:09 Nightblizard#4
Ich würde wetten, dass GetLastError() nach WriteProcessMemory(...) ERROR_ACCESS_DENIED (5) zurückgibt. Das hat nichts mit der bitness deines Betriebssystems zu tun. Dein Prozess benötigt einfach Debugrechte.
07/28/2012 17:29 hackiosa#5
Debugrechte = Adminrechte? Oder wie darf ich das verstehen.
Leider bin ich auf unserem PC kein Admin weswegen ich utilman.exe durch cmd.exe ersetzt habe, was es mir ermöglicht vorm Login eine Shell zu öffnen mit Systemrechten.
Dort habe ich es auch schon getestet, aber es funktioniert nicht.
Ich werde das mal testen mit dem ERROR_ACCESS_DENIED.

EDIT:
Ich habe folgenden Code hinter dem WriteByteToOffset eingefügt
Code:
if (GetLastError() == ERROR_ACCESS_DENIED)
        puts("Writing DLL Path failed :(");
Allerdings scheint kein Access Denied Fehler aufzutreten da er die Fehlermeldung nicht ausgibt.
07/28/2012 17:42 SmackJew#6
Quote:
Originally Posted by hackiosa View Post
Debugrechte = Adminrechte? Oder wie darf ich das verstehen.
Leider bin ich auf unserem PC kein Admin weswegen ich utilman.exe durch cmd.exe ersetzt habe, was es mir ermöglicht vorm Login eine Shell zu öffnen mit Systemrechten.
Dort habe ich es auch schon getestet, aber es funktioniert nicht.
Ich werde das mal testen mit dem ERROR_ACCESS_DENIED.

EDIT:
Ich habe folgenden Code hinter dem WriteByteToOffset eingefügt
Code:
if (GetLastError() == ERROR_ACCESS_DENIED)
        puts("Writing DLL Path failed :(");
Allerdings scheint kein Access Denied Fehler aufzutreten da er die Fehlermeldung nicht ausgibt.
Wie wärs wenn du dir einfach mal den letzten Errorcode ausgeben lässt anstatt auf einen aus mehreren hunderten zu prüfen?
07/28/2012 18:17 hackiosa#7
Ich hab mir in der Funktion jetzt einfach mal nach jedem API Call die Fehlermeldung ausgeben lassen, wie du mir geraten hast. Dabei ist rausgekommen das wohl bereits bei OpenProcess ein Error 87 sprich invalider Parameter auftritt worauf bei den anderen Funktionen Error 6 (Invalid Handle) auftritt nur leider weiß ich nicht welcher Parameter falsch sein sollte. Der Compiler meckert ja auch nicht.

LG

EDIT: Was mich gerade etwas stuzig macht ist, dass die GetProcessIdByName Funktion anscheinend den Prozess nichtmal findet obwohl sie so afaik eigl. immer funktioniert hat o0
Ich werde mir das nochmal genauer angucken..

EDIT2: GetProcessIdByName funktioniert nun richtig, allerdings kriege ich jetzt folgendes
Code:
C:\Users\Microsoft\Desktop>dll explorer.exe C:\Users\Microsoft\Desktop\hack32.dll
explorer.exe
Process found!
Error at OpenProcess: 18 (ERROR_NO_MORE_FILES)
Error at VirtualAllocEx: 18 (ERROR_NO_MORE_FILES)
Error at WriteProcessMemory: 18 (ERROR_NO_MORE_FILES)
Error at CreateRemoteThread: 5 (ERROR_ACCESS_DENIED)
Failed! Sadly..
Wobei der letzere sich wahrscheinlich durch adminrechte beheben lässt (muss ich noch testen!)
Allerdings wundert es mich , dass ich bei den anderen einen No More Files Fehler kriege? Was hat das zu bedeuten? (Und was haben die Illuminaten damit zu tuhen *gg* )
07/28/2012 18:50 Dr. Coxxy#8
deine getprocessidbyname benutzt strcmp ist also case sensitive, guck mal ob du auf groß/kleinschreibung korrekt geachtet hast, oder benutz meine:

Code:
	DWORD GetPIdByProcessName(wchar_t* Name)
	{
		PROCESSENTRY32 entry;
		entry.dwSize = sizeof(PROCESSENTRY32);
		DWORD ProcessID = 0;
		HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
		if (Process32First(snapshot, &entry) == TRUE)
		{
			while (Process32Next(snapshot, &entry) == TRUE)
			{
				if (_wcsicmp(entry.szExeFile, Name) == 0)
				{
					ProcessID = entry.th32ProcessID;
				}
			}
		}
		CloseHandle(snapshot);
		return ProcessID;
	}
07/28/2012 19:26 SmackJew#9
Quote:
Originally Posted by hackiosa View Post
Ich hab mir in der Funktion jetzt einfach mal nach jedem API Call die Fehlermeldung ausgeben lassen, wie du mir geraten hast. Dabei ist rausgekommen das wohl bereits bei OpenProcess ein Error 87 sprich invalider Parameter auftritt worauf bei den anderen Funktionen Error 6 (Invalid Handle) auftritt nur leider weiß ich nicht welcher Parameter falsch sein sollte. Der Compiler meckert ja auch nicht.

LG

EDIT: Was mich gerade etwas stuzig macht ist, dass die GetProcessIdByName Funktion anscheinend den Prozess nichtmal findet obwohl sie so afaik eigl. immer funktioniert hat o0
Ich werde mir das nochmal genauer angucken..

EDIT2: GetProcessIdByName funktioniert nun richtig, allerdings kriege ich jetzt folgendes
Code:
C:\Users\Microsoft\Desktop>dll explorer.exe C:\Users\Microsoft\Desktop\hack32.dll
explorer.exe
Process found!
Error at OpenProcess: 18 (ERROR_NO_MORE_FILES)
Error at VirtualAllocEx: 18 (ERROR_NO_MORE_FILES)
Error at WriteProcessMemory: 18 (ERROR_NO_MORE_FILES)
Error at CreateRemoteThread: 5 (ERROR_ACCESS_DENIED)
Failed! Sadly..
Wobei der letzere sich wahrscheinlich durch adminrechte beheben lässt (muss ich noch testen!)
Allerdings wundert es mich , dass ich bei den anderen einen No More Files Fehler kriege? Was hat das zu bedeuten? (Und was haben die Illuminaten damit zu tuhen *gg* )
Kann mir nicht vorstellen, dass eine dieser drei Funktionen ERROR_NO_MORE_FILES schmeißt. Ich vermute eher das kommt von Process32Next (daher auch "FILES" im Plural). Poste mal deinen Code mit den GetLastErrors.
07/28/2012 20:39 hackiosa#10
Ich könnte mal gucken ob er schon nach Process32Next den Error scmeißt

BOOL DllInject(char* process, char* dll)
{
INT Error;
INT pid = GetProcessIdByName(process);
if (pid != -1)
printf("Process found! (PID: %d)\r\n", pid);
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, false, pid);
Error = GetLastError();
if (Error != 0)
printf("Error at OpenProcess: %d\r\n", Error);

LPVOID FreeSpace = VirtualAllocEx(hProcess, NULL, strlen(dll)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
Error = GetLastError();
if (Error != 0)
printf("Error at VirtualAllocEx: %d\r\n", Error);
HANDLE hThread;

WriteProcessMemory(hProcess, FreeSpace, dll, strlen(dll), NULL);
Error = GetLastError();
if (Error != 0)
printf("Error at WriteProcessMemory: %d\r\n", Error);
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHa ndle("KERNEL32.DLL"), "LoadLibraryA"), FreeSpace, NULL, NULL);
Error = GetLastError();
if (Error != 0)
printf("Error at CreateRemoteThread: %d\r\n", Error);

if (!hThread)
return false;
CloseHandle(hThread);

return true;
}

EDIT: Lag noch an dem Process32Next *gg* kann ich aber getrost ignorieren , da er ja die richtige ID rausfindet ^^
Ich muss jetzt noch gucken obs mit Admin rechten funktioniert ^^
Trotz den Systemrechten durch meine "Backdoor-Shell" gibt er bei CreateRemoteThread immer noch einen Access Denied Error aus. Kann das daran liegen, dass ich versuchte habe in einen Prozess zu injecten der im Besitz von dem User SYSTEM ist?

In 30 Minuten kann ich endlich mit XP testen ^^
Ich halte euch auf dem laufenden ^^
07/28/2012 20:53 Dr. Coxxy#11
bitte codetags benutzen.
Code:
WriteProcessMemory(hProcess, FreeSpace, dll, strlen(dll)[COLOR="Red"]+1[/COLOR], NULL);
sollte zwar keinen unterschied machen, weils eh 0-initialisiert sein sollte, aber sauber ists sauber.

Code:
INT pid = GetProcessIdByName(process);
if (pid != -1)
die pid sollte eigtl ein DWORD sein, ist auch schon in der funktion falsch.
die funktion liefert 0 zurück und nicht -1 wenn sie failt.

Code:
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, false, pid);
Error = GetLastError();
werte die rückgabewerte auf ungleichheit mit 0 aus, die GetLastError funktion ist dafür da erweiterte informationen zu holen wenn der rückgabewert signalisiert, dass etwas fehlgeschlagen ist, nicht um generell auf fehler zu testen.
eine funktion muss nicht unbedingt lasterror auf 0 setzen wenn sie erfolgreich ist.
07/29/2012 10:26 hackiosa#12
Wieso gesagt er schreibt jetzt schon den String, aber bei CreateRemoteThread kriege ich eine NO_ACCESS Exception.
07/29/2012 14:12 Nightblizard#13
Quote:
Originally Posted by Nightblizard View Post
Dein Prozess benötigt einfach Debugrechte.
Code:
#define W32_CALL(fun) if(FALSE == fun) throw Win32Exception(_T(#fun), GetLastError())
void Process::SetDebugPrivileges()
{
	TOKEN_PRIVILEGES tp;
	HANDLE hToken;

	W32_CALL(LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, &tp.Privileges[0].Luid));

	W32_CALL(OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken));

	if(hToken != INVALID_HANDLE_VALUE)
	{
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		tp.PrivilegeCount = 1;
		W32_CALL(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, nullptr, nullptr));
		W32_CALL(CloseHandle(hToken));
	}
}
Pass das für dich an, ruf es am Anfang des Programmes auf und die Zugriffsfehler sind weg.
08/02/2012 09:47 hackiosa#14
danke ^^
probiers sofort aus.
kriegst nen fettes thanks!