Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: OpenGL hook

Sivun loppuun

Hennkka [06.11.2011 14:58:42]

#

Eli kuinka saan hookattua (koukutettua?) oman ohjelmani kaikkiin OpenGL-ohjelmiin? Haluaisin siis, että aina, kun ohjelma kutsuu SwapBufferssia, niin samalla se kutsuisi myös omaa SwapBufferssiani. Tarkoitus olisi aluksi tehdä perus FPS-counter ja sen jälkeen nauhoitusohjelma. Tiedän, että on mahdollista ja olen jopa löytänyt koodeja, jotka toimivat nauhoittajina, mutta en saa selvää, mitkä kohdat ovat hookkauksen kannalta oleellisia. Olisiko jollain täysin riisuttu ohjelma, joka tekee vain ja ainoastaa hookkauksen kaikkii OpenGL-ohjelmiin?

Edit. Windowsille olisi tarkoitus, muttei Linux-versiokaan haittaa

jimi-kimi [06.11.2011 15:11:04]

#

http://research.microsoft.com/en-us/projects/detours/

Materiaalia netti pullollaan. Suosittelen kääntymään http://www.gamedeception.net/ foorumin puoleen. Tuolla on myös paljon tutoriaaleja, sekä täysin valmiita pohjia. Etsi tuolta gd:stä ohjelma nimeltä winject ja käytä dll injektointia näin alkuun.

Hennkka [06.11.2011 15:50:26]

#

Luin vähän Wikipediasta. Ymmärtääkseni pitäisi tietää ohjelman osoitin. Mistäs saan kaikkien OpenGLää käyttävien ohjelmien osittimet talteen? Sen jälkeen pitäsisi onnistua.

jimi-kimi [06.11.2011 16:29:31]

#

Jos asenne on tuo, niin kannattaa varmaan jättää koko homma väliin ja tyytyä Frapsiin. Et tarvitse kaikkien OpenGL käyttävien ohjelmien osoitteita talteen, vaan tähän on ihan fiksukin ratkaisu. Pienellä oma-aloitteisuudella ja viitseliäisyydellä olisit jo tehnyt tuon ohjelmasi.

Luin vähän wikipediasta, jos joku kertoisi miten tienaan miljoonan minuutissa niin minun pitäisi rikastua.

EDIT: https://github.com/nullkey/glc/wiki

Hennkka [07.11.2011 20:02:03]

#

Olen kyllä yrittänyt etsiä netistä, mutta ei ole osunut silmiin koodia, jonka saisin toimimaan. Todennäköisesti vika on minussa. Olen uusi näiden WinAPI:den ja dll injektion kanssa, joten voiko jo käynnissä olevan prosessin injektoida? Tässä koodia, josta joku saisi kertoa, missä vika:

bool DLLInjektoi(DWORD dwPid, char *DllPath) {
	HANDLE hProc;
	DWORD dwMemSize;
	LPVOID lpRemoteMem, lpLoadLibrary;
	BOOL ret = FALSE;

	if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, dwPid)) != NULL) {
		std::cout << "Vaihe 1: Suoritettu" << std::endl;
		dwMemSize = strlen(DllPath) + 1;
		if ((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL) {
			std::cout << "Vaihe 2: Suoritettu" << std::endl;
			if (WriteProcessMemory(hProc, lpRemoteMem, (LPCVOID) DllPath, dwMemSize, NULL)) {
				std::cout << "Vaihe 3: Suoritettu" << std::endl;    // Pääse tähän saakka ja GetProcAddress:kin toimii
				lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
				if (CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE) lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL) {
					std::cout << "Vaihe 4: Suoritettu" << std::endl;
					ret = TRUE;
				}
			}
		}
	}

	CloseHandle(hProc);

	return false;
}

int main(int argc, const char* argv[])
{
	#define DLL_PATH "D:\\...\\OGL_FPS_Dll.dll"

	std::cout << DLLInjektoi(2436 /*Otettu Tehtävienhallinnasta*/, DLL_PATH) << " " << GetLastError() << std::endl;
	std::cin.get();
	return 0;
}

Koodi on kopioitu tästä videosta: http://www.youtube.com/watch?v=H3O3hmXkt1I

Niin ja koodi tulostaa "0 0"

Metabolix [07.11.2011 20:07:06]

#

Koodin tulostus voisi olla kiinnostavampi, jos palauttaisit funktiosta joskus muutakin kuin falsen ja jos kutsuisit GetLastError-funktiota heti virheen jälkeen etkä vasta CloseHandlen jälkeen.

Hennkka [07.11.2011 20:25:32]

#

Ei tuosta "mielenkiintoisesta" tulostuksesta ollut tarkoituskaan katsoa muuta kuin GetLastErrorin koodi. Tässä näkee tietouteni WinAPI:sta, kun yritin kutsua GetLastErroria toisen funktion jälkeen. No, laitoin sen tuonne väliin ja tulostaa 5.

Edit. Koodi tulostaa nuo vaiheet kolmeen saakka. Eikä paljoa sano, että virhe on "Access Denied".

Deffi [08.11.2011 09:26:01]

#

Anna OpenProcessille PROCESS_ALL_ACCESS.

Hennkka [08.11.2011 14:28:46]

#

Jostain kumman syystä sekään ei auta :(

if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)
// Eikä
if ((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)

Molemmat tulostavat saman virheen.

jimi-kimi [08.11.2011 15:16:59]

#

http://www.gamedeception.net/forums/238-Public-Releases

Deffi [08.11.2011 17:54:50]

#

Koodi toimii minulla, kunhan käyttää PROCESS_ALL_ACCESSia. Et voi injektoida 32-bittisestä prosessista 64-bittiseen tai toisin päin. Et voi myöskään injektoida esimerkiksi järjestelmänvalvojan oikeuksilla pyörivään prosessiin, jos ohjelmaasi ei ajeta yhtä korkeilla oikeuksilla.

Hennkka [10.11.2011 08:09:46]

#

Kiitos paljon Deffi. Juuri tuo bittisyys oli vialla. Eipä olisi kyllä millään tullut mieleen, mutta nyt toimii. Kiitos myös muille vastanneille. Tästä dll-injektiosta voisi myös olla aihetta koodivinkiksi, jos joku jaksaa tehdä :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta