Ich habe keine Ahnung von Lua.
Dass aber kompliziertere Sachen als die primitiven Datentypen genau so behandelt werden, ist in fast jeder Sprache so.
Ich habe keine Ahnung von Lua.
Dass aber kompliziertere Sachen als die primitiven Datentypen genau so behandelt werden, ist in fast jeder Sprache so.
Verstand op nul, frituur op 180.
Habe mal eine Frage zu Interthread-Kommunikation unter Windows.
Ich starte im Hauptthread einen zweiten mittels
Nun würde ich gerne auf bestimmte Events im zweiten Thread reagieren, d.h. ich mussCode:HANDLE hThread = CreateRemoteThread(processInformation.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, pReservedSpace, 0, NULL);
zum einen warten und zum anderen Nachrichten von dort empfangen können.
Ursprünglich ging mein Beispielcode folgendermaßen weiter:
Hier wird nur ganz kurz gewartet. Dann beendet sich der Hauptthread und der andere läuft weiter.Code:WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(processInformation.hProcess, pReservedSpace, strlen(dllPath), MEM_COMMIT);
Das reine Warten auf den zweiten Thread bekomme ich auch noch hin:
Aber wie kann ich Nachrichten vom zweiten Thread, bei dem ich nur Einfluss auf einen kleinen Teil des Codes (DllMain) habe, an den ersten Senden?Code:WaitForSingleObject(processInformation.hProcess, INFINITE); // Stoppt bis Prozess endet.
Ich habe es probiert mit
Das hängt sich dann aber in einer ewigen Schleife (Ping, Ping, Ping...) auf.Code:int Wait(const HANDLE handle) // handle == processInformation.hProcess { MSG messageInfo = { 0 }; while (WM_QUIT != messageInfo.message) { DWORD result = MsgWaitForMultipleObjectsEx(1, &handle, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); std::cout << "Ping" << std::endl; if (WAIT_FAILED == result) { wprintf(L"MsgWaitForMultipleObjectsEx failed (%d)\n", GetLastError()); continue; } assert(WAIT_IO_COMPLETION == result || WAIT_OBJECT_0 == result); if (WAIT_OBJECT_0 == result) { while (PeekMessage(&messageInfo, 0, // any window 0, // all messages 0, // all messages PM_REMOVE)) { std::cout << "Pong" << std::endl; if (WM_QUIT == messageInfo.message) { break; // WM_QUIT retrieved so stop looping } DispatchMessage(&messageInfo); } } } assert(WM_QUIT == messageInfo.message); return static_cast<int>(messageInfo.wParam); }
Das könnte auf der Hilfsseite zu MsgWaitForMultipleObjectsEx mitgemeint sein, aber ich habe eigentlich keine AhnungIf one of these handles is closed while the wait is still pending, the function's behavior is undefined.
Hat jemand eine Idee, wie ich die Infos übertragen bekomme? (Muss nicht zwingend über die MS-Boardmittel sein.)
Kann ich dem zweiten Thread einen Pointer mitgeben, damit er weiß wohin er Daten für den ersten Thread schreiben kann? Das würde mir eigentlich schon reichen.
Auf pLoadLibrary (das soll die übergebende Funktion sein?) hast du keinen Einfluss?
Ansonsten wüsste ich auch nicht, wie man das machen sollte. Normalerweise verwende ich globale Variablen, die durch die den Threads übergebenden Funktionen verändert/gelesen werden.
pLoadLibrary ist
Die könnte ich also ändern und eine eigene Funktion zwischen schiebenCode:void* pLoadLibrary = (void*)GetProcAddress(GetModuleHandleA("kernel32"), "LoadLibraryA");
Ich bin jetzt noch über WriteProcessMemory gestolpert. Damit kann ich vermutlich eine Speicher-Adresse an den zweiten Thread übertragen. (Ob ALSR den Pointer nutzlos macht ist mir noch unklar. Edit: Vielleicht sollte ich am besten die Threadid des ersten Threads übergeben um einen stabilen Rückkanal zu erhalten.)
Das wird auch schon an anderer Stelle im Programm genutzt um einen String zu setzen. Wie/Wo dieser String dann auf der anderen Seite genutzt wird ist mir aber noch unklar.
Code:char *dllPath = "BlaBla.dll" void* pReservedSpace = VirtualAllocEx(processInformation.hProcess, NULL, strlen(dllPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(processInformation.hProcess, pReservedSpace, dllPath, strlen(dllPath), NULL); // Schreibt den String in den reservierten Platz
Dumme Frage: Bei deiner Funktion "Wait" oben, was übergibst du genau? Wirklich den Prozess? Sollte nicht der Thread übergeben werden?
Keine dumme Frage. Ja, das war ein Fehler der daher kommt, dass Wait() bei der Übergabe des Threads überhaupt nicht gehalten hat.
Das müsste daran liegen, dass der erstellte Thread einfach sehr kurzlebig ist, da er nur LoadLibrary("[Dll Name]") ausführt?!
Den Prozess zu übergeben, ist aber falsch und macht das Verhalten beim Programmende plausibel.
Glaube ich muss mir noch mal in Ruhe angucken, was da passiert...
Du kannst ja mittels "GetExitCodeThread" abfragen, ob der Thread noch aktiv ist.
Dadurch stoppt der Prozess des äußeren Programms aber auch nicht. Der Thread endet sehr schnell, weil er nur eine DLL läd.
Nun gut, ich konnte mein Problem aber heute lösen
Zum einen war es eine dumme Idee den Thread „T2“ im äußeren Prozess zu starten. Ich habe das nun doch in den inneren Prozess verlegt.
Das war ursprünglich auch so, aber damals wurde T2 in DllMain ( DLL_PROCESS_ATTACH ) gestartet und bei DLL_PROCESS_DETACH
gestoppt. Letzteres führte dann aber beim Programmende zum Crash. (Es crashte außerdem auch, wenn ich T2 nicht manuell beenden wollte.)
In den Dokumentationen wird ja auch immer davor gewarnt in DllMain komplexe Sachen zu unternehmen.
Ich habe es jetzt so gelöst:
Ich lade meine DLL und lasse mir den Exitcode übergeben. Bei 32-Bit-Programmen stimmt dieser Wert
mit der Rückgabe von der remote aufgerufenen Funktion, LoadLibrary, überein.
Bei 64bit würde die Adresse nicht in die 32bit von GetExitCodeThread passen. Da kann man tricksen, aber das brauche ich im meinem Fall, Civ4:BTS, nicht.
Dann habe ich einen Blogeintrag gefunden, der zeigte wie man bei einem Remote-Prozess an die Adresse einer Funktion gelangt. Das ist im Allgemeinen nicht die gleiche Adresse die man beim Nachschlagen im äußeren Prozess erhält!Code:HANDLE hThread = CreateRemoteThread(processInformation.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, pReservedSpace, 0, NULL); DWORD exitCode; GetExitCodeThread(hThread, &exitCode);
Damit konnte ich dann im inneren Prozess den gewünschten zweiten Thread starten. Nun läuft alles wie gewünscht ab und es kommt nicht mehr zum Absturz beim ProgrammendeCode:HMODULE dllHandleRemote = (HMODULE) exitCode; void * pStartServerRemote = (void *) /*FARPROC*/ GetRemoteProcAddress (processInformation.hProcess, dllHandleRemote, "StartServer"); /* NOTE: Above differs from address determined by this process, i.e... */ /* HMODULE dllHandle = LoadLibraryEx(dllPath, NULL, DONT_RESOLVE_DLL_REFERENCES); void* pStartServer = (void*)GetProcAddress(dllHandle, "StartServer"); */
Code:HANDLE hThread2 = CreateRemoteThread(processInformation.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pStartServerRemote, pReservedSpace2, 0, NULL);
Endlich hat sich jemand an die Arbeit gemacht und bringt eine moderne Renderingengine in die Konsole
https://www.pro-linux.de/artikel/2/1...-terminal.html
Woran erinnert euch der Smiley-Code von (:6rw:)?
Boboy: 636348, Teenesha: 1322986, kleiner Boboy: 639544, Rep Enton: 1254521, Party: 1043769, Rüdiger: 914845, Bumsel: 1068045, Señor Burnsy: 811480, Bären-Facepalm: 1102516
Kann mir jemand die Tomaten von den Augen nehmen?!
Folgender code soll einen Pfad mit einen Dateinamen joinen, aber es kommt am Ende nur der Dateiname an.
Edit: Ok, ich habe den dummen Fehler gefunden. Lasse es mal als Rätsel unaufgelöst stehen.
Das Log enthält dannCode:// irgendwo anders definiert/ Funktionsargumente std::string path; std::string tmp_path; // Länge des internen stringbuffers garantieren. if( tmp_path.length() < MAX_TMP_NAME_LEN){ tmp_path.resize(MAX_TMP_NAME_LEN, ' '); } // Füllt tmp_path mit Pfad auf temporäres Verzeichnis. unsigned int tmp_len = GetTempPathA(MAX_TMP_NAME_LEN, (char *)tmp_path.c_str()); //tmp_path.resize(tmp_len); // otherwise many ' ' follow the \0 inserted by GetTempPathA // hm, bringt nix... LOGPRINT("tmp_path: " << tmp_path); path.clear(); path.append(tmp_path.c_str()); path.append(Tmp_Name); LOGPRINT("path: " << path);
Code:tmp_path: C:\Users\Username\AppData\Local\Temp\ path: Pitboss.CivBeyondSwordSave
Geändert von Ramkhamhaeng (13. August 2018 um 23:57 Uhr)
Ich raffs nicht . Hat es was mit deinem Auffüllen (wozu ) zu tun?
Muss man da die Syntax kennen, um den zu finden?
Meine Stories:Zitat von Leonard Bernstein
Civ VI aus der Sicht von Civ IV BTS, englischer Weltraumsieg auf König
Der Erste Kaiser wieder aufgenommen