Amer Posted November 6, 2016 Share Posted November 6, 2016 (edited) Most of us know there is one ID for each process, actually no, there is more than one. Very Simple and new for some users: 1- How many PID ( Process Identifier ) for each process? 2- Why windows task listing methods or enumerating methods deal with one PID (the first one of them) ? Regards Amer Edited November 6, 2016 by Amer Link to comment
evlncrn8 Posted November 6, 2016 Share Posted November 6, 2016 it doesnt depend.. EACH process has its own processid, given to it by the system at the time of launch, the pid of each process is UNIQUE - look at task manager, it lists all the processes, and their id's if you look closely enough.. each processid typically goes up by 4, so process 0 = system idle process, 4 = the next one and so on... sometimes the system will recycle unused id's from processes that previously exited.. but in a nutshell 1 process, 1 pid 1 Link to comment
Amer Posted November 6, 2016 Author Share Posted November 6, 2016 12 hours ago, kuqadk3 said: It's depend Not Clear 6 hours ago, evlncrn8 said: it doesnt depend.. EACH process has its own processid, given to it by the system at the time of launch, the pid of each process is UNIQUE - look at task manager, it lists all the processes, and their id's if you look closely enough.. each processid typically goes up by 4, so process 0 = system idle process, 4 = the next one and so on... sometimes the system will recycle unused id's from processes that previously exited.. but in a nutshell 1 process, 1 pid No evlncrn8, it is more than one PID for each process and windows use the first (Smallest) one from the sequence. Link to comment
kao Posted November 6, 2016 Share Posted November 6, 2016 Process ID is unique, each process has one and only one. http://materias.fi.uba.ar/7508/WI6/Windows Internals Part 1 (6th Edition).pdf - chapter 5. 3 Link to comment
evlncrn8 Posted November 6, 2016 Share Posted November 6, 2016 (edited) no they dont, process id is unique, check in task manager..the ones recorded in the system modules info is the parent process id edit : kao got there before me Edited November 6, 2016 by evlncrn8 Link to comment
Etor Madiv Posted November 6, 2016 Share Posted November 6, 2016 Output of tasklist command: C:\Users\DBNull>tasklist Nom de l’image PID Nom de la sessio Numéro de s Utilisation ========================= ======== ================ =========== ============ System Idle Process 0 Services 0 24 Ko System 4 Services 0 676 Ko smss.exe 340 Services 0 68 Ko csrss.exe 448 Services 0 816 Ko wininit.exe 508 Services 0 172 Ko ... but an application can be started many times, and different processes will be created and assigned different and UNIQUE PID for each instance even if it is the same application. Link to comment
Teddy Rogers Posted November 7, 2016 Share Posted November 7, 2016 I think he may be referring to threads. @Amer, Microsofts own documentation on their MSDN website is very useful and a good read, it nicely explains process identifiers and thread identifiers... Quote Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads. A thread is the entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread's set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread's process. Threads can also have their own security context, which can be used for impersonating clients. https://msdn.microsoft.com/en-us/library/windows/desktop/ms681917(v=vs.85).aspx Ted. 1 Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 3 hours ago, kao said: Process ID is unique, each process has one and only one. http://materias.fi.uba.ar/7508/WI6/Windows Internals Part 1 (6th Edition).pdf - chapter 5. Kao and Etor Madiv, no there is more than one ID for every process running in windows and every PID can be used as unique PID. task manager shows only one of them. @Teddy Rogers No ted i don't referring to threads I'm talking about Main Process it self for example Notepad.exe or explorer.exe. believe me no search engine will find the correct answer and Microsoft did not mentioned about it before , you have to do a little research by coding to find it. Thank You Every One For Sharing. Regards Link to comment
evlncrn8 Posted November 7, 2016 Share Posted November 7, 2016 PID - UNIQUE - one per process TID - THREAD - also unique One PID can have multiple TID'S the 'only one' of them is - are you referring to the tebptr->RealClientId.UniqueProcess entry in the peb perhaps ? or tebptr->RealClientId.UniqueThread ? if so.. not undocumented - you just didnt know where to look Link to comment
Teddy Rogers Posted November 7, 2016 Share Posted November 7, 2016 26 minutes ago, Amer said: you have to do a little research by coding to find it. I'm happy to view some code to have a better understanding of what you are explaining... Ted. Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 @evlncrn8 Yes it is Undocumented. I didn't understand what did you mean by ( you just didnt know where to look ). Regards Link to comment
evlncrn8 Posted November 7, 2016 Share Posted November 7, 2016 @Amer undocumented you say... then explain how i documented it, and have it in structs i use ? Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 (edited) 14 minutes ago, Teddy Rogers said: I'm happy to view some code to have a better understanding of what you are explaining... Ted. @Teddy Rogers @evlncrn8 OK, launch notepad.exe launch task manager. for example (notepad.exe PID = 3692) you can use OpenProcess var,var,dwProcId = 3693 or 3694 or 3695 then EnumProcessModules. and tell me what you think Regards Edited November 7, 2016 by Amer Link to comment
evlncrn8 Posted November 7, 2016 Share Posted November 7, 2016 you're checking the return values from OpenProcess etc in your code ? Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 @Teddy Rogers this better after openprocess CreateToolhelp32Snapshot Module32First Module32Next Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 4 minutes ago, evlncrn8 said: you're checking the return values from OpenProcess etc in your code ? no I'm using it as real result and it is work of course with no doubt. Link to comment
evlncrn8 Posted November 7, 2016 Share Posted November 7, 2016 (edited) what happens if you're doing process id - 1 (as opposed to the +1, +2 , in your example, is it right then ? i suspect the enumeration you're using for the process id's is doing a range check on a value, and if its within it'll return success.. as opposed to an == and check the return value of openprocess..you might just be getting lucky Edited November 7, 2016 by evlncrn8 Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 @evlncrn8 no luck here it is real result every time you can try it with any different process. now you can think about the part tow of the puzzle: 2- Why windows task listing methods or enumerating methods deal with one PID (the first one of them) ? Link to comment
evlncrn8 Posted November 7, 2016 Share Posted November 7, 2016 does subtracting one from the pid work too ? (if not, im suspecting some range check or anding is going on) Link to comment
atom0s Posted November 7, 2016 Share Posted November 7, 2016 Here is a proof of concept to show that -/+ process ids from the real one are useless for purpose: (This will get the notepad.exe process id then loop -5/+5 pids around it trying to write to its window.) /** * Process Id Example * (c) 2016 atom0s [atom0s@live.com] */ #include <Windows.h> #include <string> #include <TlHelp32.h> /** * Obtains the process id of notepad.exe. * * @returns {uint32_t} The process id if successful, 0 otherwise. */ uint32_t getNotepadProcessId(void) { PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; // Obtain a snapshot of the current process list.. auto snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) return 0; // Ensure we can obtain the first process.. if (!::Process32First(snapshot, &pe32)) { ::CloseHandle(snapshot); return 0; } do { // Locate notepad.exe running.. if (_stricmp(pe32.szExeFile, "notepad.exe") == 0) { ::CloseHandle(snapshot); return pe32.th32ProcessID; } } while (::Process32Next(snapshot, &pe32)); ::CloseHandle(snapshot); return 0; } /** * Obtains a processes main thread id. * * @param {uint32_t} processId - The process id to obtain the thread id of. * @returns {uint32_t} The thread id if successful, 0 otherwise. */ uint32_t getProcessThreadId(uint32_t processId) { THREADENTRY32 te32 = { sizeof(THREADENTRY32) }; // Obtain a snapshot of the target processes threads.. auto snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, processId); if (snapshot == INVALID_HANDLE_VALUE) return 0; // Ensure we can obtain the first thread.. if (!::Thread32First(snapshot, &te32)) { ::CloseHandle(snapshot); return 0; } do { // Locate the first thread to match our process id as the parent.. if (te32.th32OwnerProcessID == processId) { ::CloseHandle(snapshot); return te32.th32ThreadID; } } while (::Thread32Next(snapshot, &te32)); ::CloseHandle(snapshot); return 0; } /** * Enumerates a threads windows. * * @param {HWND} hWnd - The current window handle. * @param {LPARAM} lParam - Custom parameter data passed from the EnumThreadWindows call. * @returns {BOOL} TRUE if continue enumeration, FALSE otherwise. */ BOOL CALLBACK EnumThreadWindowsCallback(HWND hWnd, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); // Obtain the window class.. char className[2048] = { 0 }; ::GetClassName(hWnd, className, 2048); // Locate the notepad window class.. if (_stricmp(className, "Notepad") == 0) { printf_s("[!] Found a notepad window! - Handle: %08X\r\n", hWnd); // Locate the editor control.. auto hWndEdit = ::FindWindowEx(hWnd, nullptr, "Edit", nullptr); if (hWndEdit != nullptr) { // Obtain the current text.. char buffer[4096] = { 0 }; ::SendMessage(hWndEdit, WM_GETTEXT, (WPARAM)4096, (LPARAM)&buffer); // Append a message from the current process id.. strcat_s(buffer, 4096, "Hello world from process id: "); strcat_s(buffer, 4096, std::to_string((uint32_t)lParam).c_str()); strcat_s(buffer, 4096, "\r\n"); ::SendMessage(hWndEdit, WM_SETTEXT, NULL, (LPARAM)buffer); } } return TRUE; } /** * Application entry point. * * @param {int} argc - The number of arguments passed to this application. * @param {char*[]} argv - The arguments passed to this application. * @returns {int} 0 on success, -1 otherwise. */ int __cdecl main(int argc, char* argv[]) { printf_s("[!] Process Id Accessibility Proof-of-Concept - by atom0s\r\n\r\n"); // Obtain the notepad.exe process id.. auto pid = getNotepadProcessId(); if (pid == 0) { printf_s("[!] Failed to locate notepad.exe, cannot continue.\r\n"); return -1; } // Loop -/+ 5 pids from the found one for testing.. auto minPid = pid - 5; auto maxPid = pid + 5; for (auto x = minPid; x <= maxPid; x++) { // Obtain the notepad.exe thread id.. auto tid = getProcessThreadId(x); if (tid == 0) printf_s("[!] Failed to obtain notepad.exe thread id for pid: %08X\r\n", x); else { // Enumerate the threads windows to find the main notepad window.. ::EnumThreadWindows(tid, EnumThreadWindowsCallback, (LPARAM)x); } } return 0; } 1 Link to comment
kao Posted November 7, 2016 Share Posted November 7, 2016 Second time I have to do. The fact that some Windows APIs accept not only actual ProcessID (which is always divisible by 4), but also values +1, +2, +3 and return information about the same process - it's a bug-feature in specific APIs. It doesn't mean that process has several ProcessIDs. Further reference: https://blogs.msdn.microsoft.com/oldnewthing/20080228-00/?p=23283 https://blogs.msdn.microsoft.com/oldnewthing/20050121-00/?p=36633 2 Link to comment
Extreme Coders Posted November 7, 2016 Share Posted November 7, 2016 (edited) I did some digging about this, and the reason for this seems to come from the function ExpLookupHandleTableEntry. Internally, PsLookupProcessByProcessId calls upon ExMapHandleToPointer -> ExpLookupHandleTableEntry to search for the process. Within ExpLookupHandleTableEntry a mask of ~3 (0xFFFFFFFC) is applied before searching in the handle table. This in binary turns to 1111 1111 1111 1111 1111 1111 1111 1100. The last two bits are zero. Hence there are 4 possible values. There is also a tweet on this: Edited November 7, 2016 by Extreme Coders EDIT: Added tweet 3 Link to comment
Amer Posted November 7, 2016 Author Share Posted November 7, 2016 4 hours ago, kao said: Second time I have to do. The fact that some Windows APIs accept not only actual ProcessID (which is always divisible by 4), but also values +1, +2, +3 and return information about the same process - it's a bug-feature in specific APIs. It doesn't mean that process has several ProcessIDs. Further reference: https://blogs.msdn.microsoft.com/oldnewthing/20080228-00/?p=23283 https://blogs.msdn.microsoft.com/oldnewthing/20050121-00/?p=36633 @kaoNo it is not a bug in API it is a bug in windows OS. Every Process has at list 4 IDs depends on how created and who created it. I'll post full info about it as soon as possible. Regards Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now