{
	"id": "2cc16731-ae52-439d-b857-c2c159cf6ec6",
	"created_at": "2026-04-06T00:15:53.679591Z",
	"updated_at": "2026-04-10T03:20:49.370599Z",
	"deleted_at": null,
	"sha1_hash": "e7c249bf7689085e795578dfc00876bafdced6fb",
	"title": "Process Doppelgänging – a new way to impersonate a process",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 95909,
	"plain_text": "Process Doppelgänging – a new way to impersonate a process\r\nBy Posted on\r\nPublished: 2017-12-18 · Archived: 2026-04-05 17:58:42 UTC\r\nRecently at Black Hat Europe conference, Tal Liberman and Eugene Kogan form enSilo lab presented a new\r\ntechnique called Process Doppelgänging. The video from the talk is available here. (Also, it is worth mentioning\r\nthat Tal Liberman is an author of the AtomBombing injection).\r\nThis technique is a possible substituent of the well-known Process Hollowing (RunPE), that is commonly used in\r\nmalware. Both, Process Doppelgänging and Process Hollowing, gives an ability to run a malicious executable\r\nunder the cover of a legitimate one. Although they both serve the same goal of process impersonation, they differ\r\nin implementation and make use of different API functions. This is why, most of the current antivirus solutions\r\nstruggled in detecting Process Doppelgänging. In this post we will take a closer look on how the Process\r\nDoppelgänging works and compare it with the popular RunPE.\r\nWARNING: Running this PoC on Windows 10 may cause a BSOD – the reason is a bug in Windows 10. Details\r\nhere.\r\nProcess Doppelgänging vs Process Hollowing (aka RunPE)\r\nThe popular RunPE technique substitutes the PE content after the process is created (suspended), but before it is\r\nfully initialized. In order to implement this technique, we need to do by our own the step that WindowsLoader\r\ntook so far: converting the PE file from it’s raw form into a virtual form, relocating it to the base where it is going\r\nto be loaded, and pasting into the process’ memory. Then, we can awake the process from the suspended state, and\r\nthe WindowsLoader will continue loading our (potentially malicious) payload. You can find a commented\r\nimplementation here.\r\nThe Process Doppleganging, in contrary, substitutes the PE content before even the process is created. We\r\noverwrite the file image before the loading starts – so, WindowsLoader automatically takes care of the fore-mentioned steps. My sample implementation of this technique can be found here.\r\nNTFS transactions\r\nOn the way to it’s goal, Process Doppelgänging uses a very little known API for NTFS transactions.\r\nTransactions is a mechanism commonly used while operating on databases – however, in a similar way it exists in\r\nthe NTFS file system. It allows to encapsulate a series of operations into a single unit. Thanks to this, multiple\r\noperations can be treated as a whole: they can either succeed as a whole – and be committed, or fail as a whole –\r\nand be rolled back. Outside of our transaction, the result of the operations is not visible. It starts to be noticeable\r\nafter the transaction is closed.\r\nWindows API makes several functions available for the purpose of transactions:\r\nhttps://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nPage 1 of 5\n\nCreateTransaction\r\nCommitTransaction\r\nRollbackTransaction\r\nCreateFileTransacted\r\nMoveFileTransacted\r\nDeleteFileTransacted\r\nCreateDirectoryTransacted\r\nRemoveDirectoryTransacted\r\netc…\r\nBriefly speaking, we can create a file inside a transaction, and for no other process this file is visible, as long as\r\nour transaction is not committed. It can be used to drop and run malicious payloads in an unnoticed way. If we roll\r\nback the transaction in an appropriate moment, the operating system behaves like our file was never created.\r\nThe steps taken\r\nUsage of NTFS transactions\r\nFirstly, we need to create a new transaction, using the API CreateTransaction.\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L144\r\nThen, inside of this transaction we will create a dummy file to store our payload (using CreateFileTransacted).\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L149\r\nThis dummy file will be then used to create a section (a buffer in a special format), which makes a base for our\r\nnew process.\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L173\r\nAfter we created the section, we no longer need the dummy file – we can close it and roll back the transaction\r\n(using RollbackTransaction).\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L188\r\nUsage of undocumented process creation API\r\nSo far we created a section containing our payload, loaded from the dummy file. You may ask – how are we going\r\nto create a process out of this? The well known API functions for creating processes on Windows require file path\r\nto be given. However, if we look deeper inside those functions, we will find that they are just wrappers for other,\r\nundocumented functions. There is a function Zw / NtCreateProcessEx which, rather than the path to the raw PE\r\nfile, requires a section with a PE content to be given. If we use this function, we can create a new process in a\r\n“fileless” way.\r\nDefinition of the NtCreateProcessEx:\r\nhttps://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nPage 2 of 5\n\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L196\r\nCreation of process by this way requires more steps to be taken – there are some structures that we have to fill and\r\nsetup manually – such as process parameters ( RTL_USER_PROCESS_PARAMETERS ). After filling them and wring into\r\nthe space of the remote process, we need to link them to the PEB. Mistake in doing it will cause the process to not\r\nrun.\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L76\r\nAfter setting everything up, we can run the process by creating a new thread starting from it’s Entry Point.\r\nhttps://github.com/hasherezade/process_doppelganging/blob/master/main.cpp#L246\r\nDespite some inconveniences, creating the process by a low-level API gives also interesting advantages. For\r\nexample, we can set manually the file path – making an illusion, that this is the file that has been loaded, even if it\r\nwas not. By this way, we can impersonate any windows executable, but also we can make an illusion, that the PE\r\nfile runs from a non-existing file, or a file of a non-executable format.\r\nBelow you can see an example where the illusion was created, that the PE file runs from a TXT file:\r\nhttps://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nPage 3 of 5\n\nAn error occurred.\r\nUnable to execute JavaScript.\r\nHow to detect?\r\nAlthough this technique may look dangerous, it can be easily detected with the help of any tool that compares if\r\nthe image loaded in the memory matches the corresponding file on the disk. Example: detection with PE-sieve\r\n(former hook_finder):\r\nAn error occurred.\r\nUnable to execute JavaScript.\r\nThe process of injection is also not fully stealthy. It still requires writing into the memory (including PEB) of the\r\nnewly created process, as well as creating a remote thread. Such operations may trigger alerts.\r\nhttps://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nPage 4 of 5\n\nIn addition, the mechanism of NTFS  transactions is very rarely used – so, if any executable call the related APIs,\r\nit should become an object of a closer examination.\r\nSo far this technique is new, that’s why it is not broadly recognized by AV products – but once we are aware of it’s\r\nexistence, implementing detection should not be difficult.\r\nSource: https://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nhttps://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/"
	],
	"report_names": [
		"process-doppelganging-a-new-way-to-impersonate-a-process"
	],
	"threat_actors": [],
	"ts_created_at": 1775434553,
	"ts_updated_at": 1775791249,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/e7c249bf7689085e795578dfc00876bafdced6fb.pdf",
		"text": "https://archive.orkl.eu/e7c249bf7689085e795578dfc00876bafdced6fb.txt",
		"img": "https://archive.orkl.eu/e7c249bf7689085e795578dfc00876bafdced6fb.jpg"
	}
}