Skip to content

Instantly share code, notes, and snippets.

@ssfang
Last active January 23, 2020 11:51
Show Gist options
  • Save ssfang/7aa049d317b4f31c2e03acfc1aedf7a0 to your computer and use it in GitHub Desktop.
Save ssfang/7aa049d317b4f31c2e03acfc1aedf7a0 to your computer and use it in GitHub Desktop.
Get N level parent process id
//#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();
}
'''
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