CreateToolhelp32Snapshot()==INVALID_HANDLE_VALUE mit notepad.exe
-
Hallo
Ich möchte ein kleines Konsolenprogramm schreiben womit ich einzelne Module in einem Prozess dumpen kann. Mit dumpen meine ich das Modul als xy.bin auf der Festplatte speichern.
Als erstes erstelle ich einen Snapshot aller laufenden Prozesse und lasse alle mit ProzessID auflisten. Dann muss die gewünschte PID eingegeben werden. Jetzt wollte ich eine Liste der Module anzeigen lassen indem ich vom Prozess mit der angegeben ProzessID einen Snapshot mache. Nun wollte ich es mit "notepad.exe" testen und bekomme immer ein invalid handle. Warum?
Notepad habe ich natürlich geöffnet, die PID ist auch korrekt.
Der Fehler liegt in der Funktion moduls(). GetLastError() gibt Fehler 299 "ERROR_PARTIAL_COPY" zurück.
MSDN meint dazu:
"Only part of a ReadProcessMemory or WriteProcessMemory request was completed."
Damit kann ich leider nichts anfangen!?#include <windows.h> #include <iostream> #include <Tlhelp32.h> LPDWORD PID=0; HANDLE hproc=0; HANDLE hsnap=0; bool SetDebugPrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tokenPriv; tokenPriv.PrivilegeCount = 1; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { return 0; } if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid)) { return 0; } tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken, false, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { return 0; } return 1; } bool OpenProc(char* targetproc) { hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // Create snapshot of all processes and store the handle if (hsnap==INVALID_HANDLE_VALUE) return false; PROCESSENTRY32 process; // Create process struct process.dwSize = sizeof(PROCESSENTRY32); // Set size long nprocess = Process32First(hsnap, &process); // Store infos for first process std::cout << "PID Threads Flags Size Name" << std::endl; while (nprocess) // Are there any more processes? { std::cout << process.th32ProcessID << "\t" << process.cntThreads << "\t" << process.dwFlags << "\t" << process.dwSize << "\t" << process.szExeFile << std::endl; nprocess = Process32Next(hsnap, &process); // Store infos for next process } std::cout << "enter the processID you want to dump: " << std::endl; std::cin.clear(); char strPID[81]; std::cin.getline(strPID, 80); PID=(LPDWORD)atoi(strPID); if ( (hproc = OpenProcess(PROCESS_ALL_ACCESS, 0, DWORD (PID))) != 0)// Open process { CloseHandle(hsnap); hsnap=0; return true; // success, return true } CloseHandle(hsnap); hsnap=0; return false; // failed, return false } void moduls() { MODULEENTRY32 modul; hsnap=CreateToolhelp32Snapshot( TH32CS_SNAPMODULE32, (DWORD)PID); if (hsnap==INVALID_HANDLE_VALUE) { int e=GetLastError(); // **** FEHLER **** 299 ERROR_PARTIAL_COPY 299 0x12B std::cout << "error:" << e << std::endl; return; } modul.dwSize=sizeof(MODULEENTRY32); if (!Module32First( hsnap, &modul)) { return; } do { std::cout << modul.szModule << modul.modBaseAddr << std::endl; } while ( Module32Next(hsnap, &modul) ); CloseHandle(hsnap); } int main(int argc, char *argv[]) { std::cout << "[PROCESSDUMP]" << std::endl; std::cout << "~~~~~~~~~~~~~" << std::endl; std::cout << "SetDebugPrivileges() ... "; SetDebugPrivileges(); std::cout << "done" << std::endl; if (!OpenProc(argv[1])) { std::cout << "error: unable to open " << argv[1] << std::endl; std::cin.get(); return 0; } std::cout << "opened ProcessID: hex 0x" << PID << " - decimal " << (int)PID << std::endl; moduls(); std::cout << "Press [RETURN] to quit processpump" << std::endl; std::cin.get(); return 0; }
-
Ich lese gerade im aktuelleren MSDN online:
If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
Heißt das jetzt es ist unmöglich von einem 32Bit Prozess ein Handle zu einem 64Bit Prozess zu bekommen?
Notepad ist bei mir ein 64Bit Prozess (WinXP 64)
Mein Prozess, also der "callerprocess", ist ein 32Bit Prozess.Ich habe nun...
TH32CS_SNAPALL
TH32CS_SNAPMODULE
TH32CS_SNAPMODULE32
probiert und über keine Variante bekomme ich ein valid Handle.
-
Ja!
Genauso wenig wie es möglich ist 32Bit Code zu thunken, so wie das bei 16bit/32bit möglich war.
http://blogs.msdn.com/oldnewthing/archive/2008/10/20/9006720.aspx
-
danke für die schnelle Hilfe

Um das zu lösen dachte ich mir jetzt "dann compiliere ich einfach noch eine 64Bit-Version" - aber nixda, VC++ 2008 Express hat nur einen 32Bit Compiler und erst ab der Standard Edition gibts wohl 64Bit. Außerdem frag ich mich ob man einfach so eine Konsolenanwendung überhaupt als 64Bit compilieren kann? ... keine Ahnung, damn it...
Allerdings denke ich schon das es möglich ist, weil wenn ich bei mir "cmd" aufrufe wird der Prozess als 64Bit angezeigt und läuft nicht mehr über den 'WOW64'-Emulator. Möchte ja auch sein bei einem 64Bit OS ^^
Gibt es ein freies VC++ von Microsoft wo ein 64Bit Compiler dabei ist?
-
Ich weiß es nicht sicher, aber war im SDK nicht ein 64bit Compiler mit drin?
-
Auf jeden Fall war mal einer dabei... es war mal der Plan den x64 Compiler wieder zu entfernen, da es ja jetzt (ab VS2005) einen Compiler in der IDE gibt... zumindest ist älteren PSDKs in der 64-Bit Compiler dabei.
Im PSDK, welches mit VS installiert wird ist auf jeden Fall keiner dabei...