C++ Remote-GetProcAddress

  • Ersteller Ersteller Tigerass 2.0
  • Erstellt am Erstellt am
T

Tigerass 2.0

Gast
Wieder mal etwas komplizierteres :)
Vll. kennt ihr es ja wenn man eine dll mit ihren Exportieren Funktionen lädt, kann mann mit GetProcAddress ihren Startpunkt erhalten und sie somit aufrufen. Also z.B. GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA") würde mir die Addresse von MessageBoxA liefern.
Ich habe jetzt aber nicht meinen Prozess gegeben, sondern will die Addresse der MessageBoxA Funktion in einem anderen Prozess herausfinden. Gibts da was spezielles dafür? Hat jemand schon sowas gemacht?

LG Tigerass
 
Einen remote thread starten, der diese funktion aufruft. Dafür wäre es praktisch die Addresse gleich zu wissen um nur einen call zu machen. Sonst muss ich halt zur not mir was in asm einfallen lassen, aber halt eher ungern :(
Es geht um einen bot der für mich in einem spiel ein paar sachen übernimmt :)
 
Schon geschehen :king: Mich hat aber auch eher die technische Herausforderung dahinter interessiert. gerade kann ich damit nur im Chat was automatisiert schreiben, einen chatbot. Das "interessante" hierbei war, das ganze aus einem anderen Prozess ohne Hilfe einer DLL zu machen. Ansonsten ist es ja easy. Aber mit sowas beschäftigen sich, wie es aussicht, nicht viele damit :)
 
Ob sich damit nicht viele beschäftigen, lässt sich nicht so leicht beantworten, schau dir beispielsweise mal die detours-lib an. Von MS nur für den Zweck, irgendwas zu machen, was so nicht vorgesehen ist.

Mal ne Frage, wie schreibst du in den Chat, per WriteRemoteMemory und Binärcode oder über Send*()?

Dir wird hier halt echt niemand helfen, falls du damit nur Unfug machen willst (cheaten, spammen, etc.).
 
Code:
    DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId) 
    { 
        MODULEENTRY32 lpModuleEntry = {0}; 
        HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId ); 
        if(!hSnapShot) 
        return NULL; 
        lpModuleEntry.dwSize = sizeof(lpModuleEntry); 
        BOOL bModule = Module32First( hSnapShot, &lpModuleEntry ); 
        while(bModule) 
        { 
            if(!strcmp(lpModuleEntry.szModule, lpModuleName ) ) 
            { 
                CloseHandle( hSnapShot ); 
                return (DWORD)lpModuleEntry.modBaseAddr; 
            } 
            bModule = Module32Next( hSnapShot, &lpModuleEntry ); 
        } 
        CloseHandle( hSnapShot ); 
        return NULL; 
    };

Nutzung ausschließlich zur Sicherung des Weltfriedens und Wiederaufzucht der Einhörner erlaubt .
 
Jetzt nur noch entsprechend das ganze PE parsen, bis man vielleicht an der richtigen Stelle ist...
Und dazu nur für 32 bit geeignet, aber nicht schlecht :).

Eine kleine Proxy-Exe (einmal für 32 bit und einmal für 64 bit kompilieren. Verwendung: proxy-exe <DLL-Name> <PID>).
Der Rückgabewert ist der HMODULE, aber möglicherweise nur das untere DWORD.
Code:
#include <windows.h>
#include <stdlib.h>
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	if(__argc!=3){
		return -1;
	}
	size_t len=strlen(__argv[1]);
	HANDLE hp=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION| PROCESS_VM_WRITE| PROCESS_VM_READ,NULL,atoi(__argv[2]));
	HMODULE ret=0;
	void*hloadlib=(void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"LoadLibraryA");

	void*addr=VirtualAllocEx(hp,NULL,len+1,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);

	WriteProcessMemory(hp,addr,__argv[1],len+1,NULL);
	HANDLE hthread=CreateRemoteThread(hp,0,0,
			(LPTHREAD_START_ROUTINE)hloadlib,
			(LPVOID)addr,0,0);
	WaitForSingleObject(hthread,INFINITE);
	VirtualFreeEx(hp,addr,0,MEM_RELEASE);

	GetExitCodeThread(hthread,(DWORD*)&ret);
	CloseHandle(hthread);
	CloseHandle(hp);
	return (int)ret;
}
Und jetzt die DLL im Prozess selber:
Code:
#include <Windows.h>
HMODULE hmod;
int thread(DWORD handle)
{
	WaitForSingleObject((HANDLE)handle,INFINITE);
	CloseHandle((HANDLE)handle);
//Stuff here
FreeLibraryAndExitThread(hmod,0);//Note: After that, the DLL is unloaded, comment out for persistent things
	return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved)
{
	hmod=hModule;
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		CreateThread(0,0,(LPTHREAD_START_ROUTINE)thread,OpenThread(SYNCHRONIZE,false,GetCurrentThreadId()),0,0);
		break;
	}
	return TRUE;
}
Der Code in der DLL wird asynchron ausgeführt und gibt den Handle auch wieder frei.
Wie man 64 bit und 32 bit unter einen Hut bringt, bleibt als Übung übrig.
 
Falls es wen Interessiert, hier ist meine Version (ich weiß, dass es noch nicht schön ist)
Und eine Frage noch diesbezüglich: Was mache ich falsch, dass der angeforderte Speicher im fremden Prozess nicht wieder freigegeben wird?

Code:
DWORD GetProcAddressEx(HANDLE hProcess, LPCSTR lib, LPCSTR func)
{
	BYTE code[] = 
	{
		0x68, 0x11, 0x11, 0x11, 0x11, 0xe8, 0x22, 0x22, 0x22, 0x22, 0x68, 0x33,
		0x33, 0x33, 0x33, 0x50, 0xe8, 0x44, 0x44, 0x44, 0x44, 0xa3, 0x55, 0x55,
		0x55, 0x55, 0xc3
	};

	BYTE liblen = strlen(lib)+1;
	BYTE funclen = strlen(func)+1;

	DWORD start = (DWORD)VirtualAllocEx(hProcess, NULL, 64, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	HMODULE kernel = LoadLibrary("kernel32.dll");
	*(DWORD*)(code+1) = (DWORD)start;
	*(DWORD*)(code+6) = (DWORD)GetProcAddress(kernel, "LoadLibraryA")-start-0x0A-liblen-funclen;
	*(DWORD*)(code+11) = (DWORD)(start+liblen);
	*(DWORD*)(code+17) = (DWORD)GetProcAddress(kernel, "GetProcAddress")-start-0x15-liblen-funclen;
	*(DWORD*)(code+22) = (DWORD)(start);

	WriteProcessMemory(hProcess, (void*)start, lib, liblen, NULL); start+=liblen;
	WriteProcessMemory(hProcess, (void*)start, func, funclen, NULL); start+=funclen;
	WriteProcessMemory(hProcess, (void*)start, code, sizeof(code), NULL);

	HANDLE rthread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)start, NULL, NULL, NULL);
	WaitForSingleObject(rthread, INFINITE);
	DWORD res,read; start-=(liblen+funclen);
	ReadProcessMemory(hProcess, (void*)start, &res, sizeof(DWORD), &read);
	CloseHandle(rthread);
	VirtualFreeEx(hProcess, (void*)(start),64,MEM_RELEASE);
	
	return res;
}

Möge es jemandem helfen :)
LG Tigerass
 
OK, also:
Z. 10,Z. 11: Warum BYTE, das ist doch eine unsinnige Beschränkung der Länge...
Z. 13: sizeof(code)=? 64? Aber du schreibst möglicherweise doch viel mehr, besser sizeof(code)+liblen+funclen

Warum dann der Speicher immer noch drin bleibt... Mal die 64 in Z. 30 rausgenommen?
Falls du das ganze noch effizienter machen willst :), spring doch in GetProcAdddress rein und les den Rückgabewert per GetExitCode aus, das ist dann deine gewünschte Adresse.
 
Zurück
Oben