Last active
January 23, 2020 11:51
-
-
Save ssfang/7aa049d317b4f31c2e03acfc1aedf7a0 to your computer and use it in GitHub Desktop.
Get N level parent process id
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#include <stdio.h> | |
#include <io.h> | |
#include <fcntl.h> | |
//#include <windows.h> | |
//typedef LONG (__stdcall *FPTR_NtQueryInformationProcess) (HANDLE, INT, PVOID, ULONG, PULONG); | |
//FPTR_NtQueryInformationProcess NtQueryInformationProcess; | |
// Retrieve function address from DLL | |
//NtQueryInformationProcess = (FPTR_NtQueryInformationProcess) GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess"); | |
//if (NtQueryInformationProcess == NULL) { | |
// return 1; | |
//} | |
LONG(WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle, ULONG ProcessInformationClass, | |
PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); | |
typedef union _PROCESS_BASIC_INFORMATION { | |
struct{ | |
LONG ExitStatus; | |
PVOID PebBaseAddress; | |
ULONG_PTR AffinityMask; | |
LONG BasePriority; | |
ULONG_PTR UniqueProcessId; | |
ULONG_PTR InheritedFromUniqueProcessId; | |
}; | |
struct{ | |
PVOID Reserved1; | |
PVOID PebBaseAddress; //PPEB PebBaseAddress; //https://msdn.microsoft.com/en-us/library/windows/desktop/aa813706(v=vs.85).aspx | |
PVOID Reserved2[2]; | |
ULONG_PTR UniqueProcessId; | |
PVOID Reserved3; | |
}; | |
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; | |
BOOL EnsureLibProcAddr(FARPROC *addr, LPCTSTR libname, LPCSTR procname){ | |
if (NULL != addr) | |
{ | |
return TRUE; | |
} | |
HMODULE hDll = LoadLibrary(libname); | |
if (NULL != hDll) | |
{ | |
*addr = GetProcAddress(hDll, procname); | |
if (NULL != *addr) | |
{ | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} | |
//[NtQueryInformationProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx) | |
//[NtQueryInformationProcess may be altered or unavailable in future versions of Windows. Applications should use the alternate functions listed in this topic.] | |
//Header: Winternl.h, DLL: Ntdll.dll | |
//NTSTATUS WINAPI NtQueryInformationProcess( | |
//_In_ HANDLE ProcessHandle, | |
//_In_ PROCESSINFOCLASS ProcessInformationClass, | |
//_Out_ PVOID ProcessInformation, | |
//_In_ ULONG ProcessInformationLength, | |
//_Out_opt_ PULONG ReturnLength | |
//); | |
ULONG_PTR GetParentProcessId(HANDLE hProcess) // By Napalm @ NetCore2K | |
{ | |
#ifdef _DEBUG | |
ULONG_PTR pbi[6]; | |
ULONG ulSize = 0; | |
if(EnsureLibProcAddr((FARPROC *) & NtQueryInformationProcess, _T("NTDLL.DLL"), "NtQueryInformationProcess")){ | |
if (NULL == hProcess) | |
hProcess = GetCurrentProcess(); | |
if (NtQueryInformationProcess){ | |
//PROCESS_BASIC_INFORMATION = 0 | |
if (NtQueryInformationProcess(hProcess, 0, &pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi)) | |
return pbi[5]; | |
} | |
} | |
#endif | |
return (ULONG_PTR)-1; | |
} | |
// https://justcheckingonall.wordpress.com/2008/08/29/console-window-win32-app/ | |
void EnableConsole(){ | |
//Get a pointer to the forground window. The idea here is that | |
//IF the user is starting our application from an existing console | |
//shell, that shell will be the uppermost window. We'll get it | |
//and attach to it | |
//HWND hForegroundWnd = GetForegroundWindow(); | |
//DWORD dwProcessId; | |
//GetWindowThreadProcessId(hForegroundWnd, &dwProcessId); | |
if (FALSE) | |
{ | |
//AttachConsole(dwProcessId); | |
}else | |
{ | |
AllocConsole(); | |
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); | |
int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT); | |
FILE* hf_out = _fdopen(hCrt, "w"); | |
setvbuf(hf_out, NULL, _IONBF, 1); | |
*stdout = *hf_out; | |
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); | |
hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT); | |
FILE* hf_in = _fdopen(hCrt, "r"); | |
setvbuf(hf_in, NULL, _IONBF, 128); | |
*stdin = *hf_in; | |
} | |
// use the console just like a normal one - printf(), getchar(), ... | |
printf("hello world"); | |
FreeConsole(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Created on 2016-4-5 | |
@author: fangss | |
''' | |
import os | |
if os.name == 'nt': | |
# Based on http://code.activestate.com/recipes/576362-list-system-process-and-process-information-on-win/ | |
# License: MIT | |
from ctypes import c_long, c_int, c_uint, c_void_p, c_char, c_wchar | |
from ctypes import windll, wintypes | |
from ctypes import Structure | |
from ctypes import sizeof, POINTER, pointer | |
import ctypes | |
# Constants | |
TH32CS_SNAPPROCESS = 2 | |
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1) | |
# Struct for PROCESSENTRY32 | |
class PROCESSENTRY32(Structure): | |
_fields_ = [ ('dwSize' , wintypes.DWORD) , | |
('cntUsage' , wintypes.DWORD) , | |
('th32ProcessID' , wintypes.DWORD) , | |
('th32DefaultHeapID' , wintypes.ULONG) , # ULONG_PTR | |
('th32ModuleID' , wintypes.DWORD) , | |
('cntThreads' , wintypes.DWORD) , | |
('th32ParentProcessID' , wintypes.DWORD) , | |
('pcPriClassBase' , wintypes.ULONG) , | |
('dwFlags' , wintypes.DWORD) , | |
('szExeFile' , c_char * 260) , | |
('th32MemoryBase' , c_long) , | |
('th32AccessKey' , c_long) ] | |
# Foreign functions | |
# # CreateToolhelp32Snapshot | |
CreateToolhelp32Snapshot = windll.kernel32.CreateToolhelp32Snapshot | |
CreateToolhelp32Snapshot.restype = wintypes.HANDLE | |
CreateToolhelp32Snapshot.argtypes = [ wintypes.DWORD , wintypes.DWORD ] | |
# # Process32First | |
Process32First = windll.kernel32.Process32First | |
Process32First.argtypes = [ wintypes.HANDLE , POINTER(PROCESSENTRY32) ] | |
Process32First.restype = wintypes.BOOL | |
# # Process32Next | |
Process32Next = windll.kernel32.Process32Next | |
Process32Next.argtypes = [ wintypes.HANDLE , POINTER(PROCESSENTRY32) ] | |
Process32Next.restype = wintypes.BOOL | |
# # CloseHandle | |
CloseHandle = windll.kernel32.CloseHandle | |
CloseHandle.argtypes = [ wintypes.HANDLE ] | |
CloseHandle.restype = wintypes.BOOL | |
def wingetpnid(pid=None, N=1): | |
''' Get get parent process pid for process `pid` | |
''' | |
hProcessSnap = c_void_p(0) | |
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS , 0) | |
if INVALID_HANDLE_VALUE == hProcessSnap: | |
return None | |
if not pid: | |
pid = os.getpid() | |
pe32 = PROCESSENTRY32() | |
pe32.dwSize = sizeof(PROCESSENTRY32) | |
ret = Process32First(hProcessSnap , ctypes.byref(pe32)) | |
while ret: | |
if pe32.th32ProcessID == pid: | |
pid = pe32.th32ParentProcessID | |
print 'ppid = {}, szExeFile = {}'.format(pid, pe32.szExeFile) | |
N -= 1 | |
if N > 0: | |
ret = Process32First(hProcessSnap , ctypes.byref(pe32)) | |
else: | |
CloseHandle(hProcessSnap) | |
return pid | |
ret = Process32Next(hProcessSnap, ctypes.byref(pe32)) | |
CloseHandle(hProcessSnap) | |
return None | |
def wingetpndTest(): | |
# pid: 5644 | |
# ppid = 6596, szExeFile = python.exe | |
# ppid = 2820, szExeFile = eclipse.exe | |
# ppid: 2820 | |
print ' pid:', os.getpid() | |
print 'ppid: %d' % wingetpnid(N=2) | |
if __name__ == '__main__': | |
wingetpndTest() | |
# If you deleted the system ones by accident, bring up the Registry / | |
# Editor, then go to HKLM\ControlSet002\Control\Session Manager\Environment | |
# (assuming your current control set is not ControlSet002) | |
# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment | |
# print '\n'.join(os.environ.get('PATH', '').split(os.pathsep)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment