{
	"id": "718b68e0-c8b7-4663-a3ee-cc62c12b35b2",
	"created_at": "2026-04-06T00:12:53.551201Z",
	"updated_at": "2026-04-10T03:21:43.358553Z",
	"deleted_at": null,
	"sha1_hash": "dd7caea78c4fa610ef997c5f13845b5855ec77ac",
	"title": "Windows Registry Persistence, Part 2: The Run Keys and Search-Order",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 78024,
	"plain_text": "Windows Registry Persistence, Part 2: The Run Keys and Search-Order\r\nBy Cylance, Inc.\r\nArchived: 2026-04-05 23:39:09 UTC\r\n\"It is only prudent never to place complete confidence in that by which we have even once been\r\ndeceived.\" ― René Descartes\r\nAnother method of persistence that has been around for a very long time is the use of what are collectively known\r\nas the \"run keys\" in the Windows registry.\r\nAs stated in Part 1 of this blog series, the most common method up until this year has been the use of hosted\r\nservices configured in the registry. The intention of this article is to present a list of registry keys that are used to\r\npersist services or applications in the order they are loaded by the operating system and then discuss some\r\nimportant ones.\r\nRegistry Keys to Launch Persistent Services or Applications (in Load Order)\r\nThe registry is accessed even before the NT kernel is loaded, so it is very important to understand what the\r\ncomputer is configured to load at startup. The following list of registry keys are accessed during system start in\r\norder of their use by the different windows components:\r\n1) HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\BootExecute\r\n2) HKLM\\System\\CurrentControlSet\\Services (start value of 0 indicates kernel drivers, which load be\r\n3) HKLM\\System\\CurrentControlSet\\Services (start value of 2, auto-start and 3, manual start via SCM\r\n4) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce\r\n5) HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce\r\n6) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices\r\n7) HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices\r\n8) HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\r\n9) HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Userinit\r\n10) HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\\\Shell\r\n11) HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\\\Shell\r\n12) HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad\r\n13) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\r\n14) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\r\n15) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\r\n16) HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\r\n17) HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\r\n18) HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 1 of 6\n\n19) HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\r\n20) HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\load\r\n21) HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\r\n22) HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SharedTaskScheduler (XP, NT, W2k only)\r\n23) HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\\\AppInit_DLLs\r\nNote: Some of these keys are also reflected under HKLM\\Software\\wow6432node on systems running on a 64bit\r\narchitecture and with a 64bit version of Windows. I won’t be covering each of these in this post.\r\nBefore getting started, Microsoft has a great utility available to inspect all (and more) of these registry keys. The\r\nutility, called Autoruns, is freely available here. (live.sysinternals.com).\r\nFigure 1: Sysinternals Autoruns Utility\r\nCompromise Assessment\r\nAs I discuss each registry location, I will occasionally demonstrate native windows commands that can be scripted\r\nto gather information related to these registry persistence locations. We do this at Cylance as part of our\r\ncompromise assessment collection script. Our assessment is designed to be very low impact on the thousands of\r\ncomputers in your enterprise on which it runs. It is also designed to run on a regular basis (perhaps quarterly) as a\r\nmeans of quickly identifying abnormal behavior. We take this data and analyze it in SQL and Excel which gives us\r\nthe ability to identify the \"low frequency\" outliers. For example, below we see the DLLs loaded by svchost.exe,\r\nthe shared service host. We routinely see unusual DLLs that are part of a targeted attack and that endpoint AV is\r\ncompletely blind to. Other tools that rely on \"known indicators\" will miss them too. We do this same process for\r\nfiles, network IPs, prefetch files, services, scheduled tasks, etc. We look for the \"few\" by leveraging the \"many\".\r\nBootExecute Key (1)\r\nAs a Windows computer powers up, the Session Manager (smss.exe) starts as the first user-mode process. Since it\r\nloads before the Windows Subsystem has loaded, it can't use standard Windows API functions and uses native API\r\ncalls instead. It calls the configuration manager subsystem to load the hives listed in the following registry\r\nkey: HKLM\\SYSTEM\\CurrentControlSet\\Control\\hivelist\r\nAs far as locations in the registry where malicious processes or modules can be configured to launch from, the\r\nBootExecute key is the earliest. Smss.exe will load any programs it finds listed here. By default the only entry in\r\nthis string array is autocheck autochk * which runs Autochk during boot.\r\nIf instead you see an entry such as the following in your BootExecute key, there are problems. The oddly named\r\nfile will be sitting in your system32 folder, unless it has been removed by AV.\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 2 of 6\n\nYou might see this presented this way in various online malware sandbox analyzers:\r\nIf you decode the HEX string to text, it becomes autocheck autochk * aHdqEPamx which causes the malicious\r\nprogram to launch during startup. Search the web for other samples of this technique by using this as your search\r\nterm: site:threatexpert.com bootexecute\r\nAs an Incident Responder I collect the output from Autoruns (Figure 1) from Microsoft Sysinternals\r\n(live.sysinternals.com), which can be used to view all of the registry keys being covered in this blog and is an\r\nawesome way to audit registry settings. I use this utility from the command line on machines where some\r\nbehavioral or configuration anomaly has been observed.\r\nThis technique is true for all registry settings covered in this article so I'll just use this first one as an example.\r\nServices Keys (2 and 3)\r\nThe first process to launch during startup is winload.exe and this process reads the system registry hive to\r\ndetermine what drivers need to be loaded. Every device driver has a registry subkey\r\nunderHKLM\\SYSTEM\\CurrentControlSet\\Services. Winload.exe is the process that shows the progress bar under\r\nthe \"Starting Windows…\" you see during startup.\r\nUse the following command (as Administrator) to view the drivers configured to load during startup:\r\nreg query hklm\\system\\currentcontrolset\\services /s | findstr ImagePath 2\u003enul | findstr /Ri \".*\\.sys$\r\nReview of the entries under this subkey for any drivers running out of a user profile location or a temp directory.\r\nFor example:\r\nC:\\WINDOWS\\TEMP\\INSTB64.SYS\r\nC:\\Users\\USERNA~1\\AppData\\Local\\Temp\\cpuz135\\cpuz135_x64.sys\r\nC:\\Windows\\TEMP\\009947~1.EXE\r\nC:\\Users\\username\\AppData\\Local\\Temp\\ALSysIO64.sys\r\nDuring our compromise health assessments, we gather all of these registry locations into a database and with SQL\r\nare able to inspect the entire enterprise for unusual driver locations in the same manner as shown above. We gather\r\nthese ImagePath locations into Excel and look at the outliers – those systems where only one or a few machines\r\nhave drivers running from odd locations. By using the power of collective comparison, the anomalous registry\r\nsettings can be quickly identified because they don't occur with high frequency like the normal settings do and\r\ntherefore stand out. Even if a company deploys in-house developed code, we can determine that is the case by\r\nlooking at the frequency of occurrence. In this way we are able to discover rootkits (because a rootkit hides itself\r\nby lying to the OS during DIR and TASKLIST commands but not from REG QUERY) and other tools configured\r\nto load as system drivers very early in the boot sequence. We then gather additional data in order to get a more\r\ncomplete picture of the purpose for these drivers.\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 3 of 6\n\nRun Services Keys (4 through 7)\r\nThese keys are referenced both early in the boot process to identify driver files (typically *.sys) that are to be\r\nloaded and later by the service controller (SC.EXE) when starting those services that are configured as services\r\n(daemons). I will discuss the use of these keys in more depth below.\r\nWinlogon Keys (8 through 11)\r\nWinlogon.exe is another user-mode executable that is loaded very early during startup by wininit.exe and handles\r\ninteractive user logons and logoffs. This process handles the Secure Attention Sequence (SAS) known to us all as\r\nCtrl-Alt-Delete which is designed to protect against password-capture user-mode applications since the SAS can\r\nonly be processed by the kernel, which notifies winlogon.exe.\r\nWinlogon\\notify\r\nThe notify subkeys are used to configure event handlers that are to be notified whenever certain events happen,\r\nrelated to SAS. Events are things like logon, logoff, shutdown, lock, etc. This can be used maliciously to launch a\r\nDLL whenever the event occurs.\r\nWinlogon\\userinit\r\nThe Userinit string array (REG_SZ) contains by default just C:\\Windows\\system32\\userinit.exe but can have other\r\nentries as well and should be monitored. Administrator-level rights are needed to modify this key.\r\nAn example of how this could be used to launch malicious code. The second entry is part of a password stealing\r\nTrojan.\r\nC:\\WINDOWS\\system32\\userinit.exe,C:\\WINDOWS\\system32\\sovhst.exe\r\nWinlogon\\Shell\r\nThis should be set to \"explorer.exe\" since that is the Windows interface we all know and use. The value should be\r\njust the name, spelled correctly. Since no path is given, the process launches from the windows storage location,\r\nthe \\Windows directory. There should not be a path listed, just the name.\r\nThere is a configuration for this in the machine hive and the user hive (HKLM and HKCU) and another entry\r\ndetermines which is to be used. Check HKLM\\ \\Software\\Microsoft\\Windows\r\nNT\\CurrentVersion\\IniFileMapping\\system.ini\\boot\\Shell. The value by default is pointing to the machine hive\r\nvalue SYS:Microsoft\\Windows NT\\CurrentVersion\\Winlogon and the user hive value isn't used.\r\nShellServiceObjectDelayLoad (12)\r\nThis key is undocumented and there it cannot be said with certainty the support and behavior of the use of this key\r\nsince it could change at any time. On my Windows 7 Ultimate laptop, this key has a single subkey called\r\n\"WebCheck\" and a GUID of {E6FB5E20-DE35-11CF-9C87-00AA005127ED} but there is no dll configured\r\nunder the CLSID key.\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 4 of 6\n\nRun Keys (13 through 19)\r\nThe run keys have been the method typically used by run-of-the-mill viruses and worms and not tools used in\r\ntargeted attacks. Because the attack team is located some distance away on the internet, they need to ensure that\r\ntheir code will launch again if the computer they compromise gets rebooted. The run keys are the easiest way to\r\ndo this and offer different levels of privilege depending on their exploit and what level it achieves for them. If\r\ntheir exploit fails to obtain NT AUTHORITY\\SYSTEM or administrator-level rights they can always create a key\r\nunder the \"user\" run keys and persist their access. From there they can work on elevating privilege levels and\r\nmove to create less obvious persistence hooks and then clean up the run keys because they are heavily scrutinized\r\nand monitored by all sorts of host-based controls. Attackers are also concerned about taking risks and moving\r\nfrom run keys as soon as possible is one way of lowering their risk profile.\r\nHowever, with the proliferation of botnet and noisy commodity malware providing cover (like chaff on a RADAR\r\nscreen), the use of these keys can be tolerated in some environments for some time (perhaps permanently) and\r\nprovides the following objectives:\r\nObtain and maintain some level of remote access\r\nReconnaissance from a single machine (What rights does this user have? What other accounts are on this\r\nmachine? What software is installed that I have the ability to exploit?)\r\nWork to elevate to a machine service and remove the run keys\r\nContinue reconnaissance and look to move laterally with the goal of getting: Windows Domain Controller\r\naccess; locate network file shares and who has access to them; obtain specialty credentials (database, code\r\nrepositories, web application logins, etc.); obtain the ability to utilize the same remote-access infrastructure\r\nthat is provided to employees.\r\nIf, as the attacker, my phish is launched by Norman on his laptop and his account, nsmith, is not in the\r\nAdministrators local group, then I have to persist by using the HKCU run key or adding my tool\r\ntoC:\\Users\\nsmith\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startupdirectory because this is\r\nthe only place nsmith has rights to create entries. After doing this I will inventory installed and running software\r\nin order to find some software that I can exploit (assuming Windows 7+ as the OS).\r\nDetecting recent activity in the HKCU run keys is indicative of Stage 1 dropper/downloaders or Stage 2 efforts to\r\nharvest other access points inside the enterprise. Close inspection of the targeted computer for signs of activity can\r\nyield a wealth of information that then leads you down the path of your investigation and removing the attacker's\r\naccess to your computers and intellectual property.\r\nPersistence Location Privilege Level\r\nHKCU run keys useraccount: FC\r\nHKLM run keys Users:R, Administrators: FC\r\nLegacy Windows Load (20 and 21)\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 5 of 6\n\nWhen Microsoft transitioned from 3.x to NT, they added this key to replace the win.ini file load= and run= values.\r\nOn Windows 7 this key doesn't exist by default under either the \"machine\" (HKLM) or the \"user\" (HKCU) hives\r\nbut if present can be used to launch programs during startup. The \"machine\" key launches at computer startup and\r\nthe \"user\" key runs at user login.\r\nAppInit_DLLs (23)\r\nEven though I'm listing this as number 23, every time User32.dll is linked (loaded by an executable), this registry\r\nstring array is read and any modules listed are also loaded by the executable. This happens at various times while\r\nwindows is starting up so I can't really place it where it first occurs. As you can guess, this is a great way to hoist\r\ncode into a great number of running processes. It is worth keeping an eye on this registry location as well.\r\nAppInit gets its own tab in Autoruns, but you can script the following to read just the string array from your\r\nsystems:\r\nreg query \"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\" /v appinit_dlls\r\nActive Registry\r\nIt's worth mentioning that CurrentControlSet is just a symbolic link to indicate the hive that is active, meaning it is\r\nin-use by the running OS. Almost all the time this will be ControlSet001, but you can see which is active by\r\nlooking at the \"Current\" value under HKLM\\System\\Select. The number indicates which ControlSet is loaded,\r\nwhere the number corresponds to the two ControlSets.\r\nIt is always good to also pay attention to the \"previously run\" version of the registry, which is usually\r\nControlSet002, since transient entries could still be present there. For example, if a dropper set itself to run at\r\nstartup, then once a different persistence is achieved, it removes itself, that old persistence entry could still be\r\npresent in the LastKnownGood registry.\r\nNext Time\r\nThere are of course other methods of persistence with certain file and file system locations being the major ones.\r\nI'll cover those in part 3. Until then, keep 'er safe!\r\nTags: Technical Blog, Windows\r\nSource: https://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-or\r\nder\r\nhttps://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://web.archive.org/web/20160214140250/http://blog.cylance.com/windows-registry-persistence-part-2-the-run-keys-and-search-order"
	],
	"report_names": [
		"windows-registry-persistence-part-2-the-run-keys-and-search-order"
	],
	"threat_actors": [],
	"ts_created_at": 1775434373,
	"ts_updated_at": 1775791303,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/dd7caea78c4fa610ef997c5f13845b5855ec77ac.pdf",
		"text": "https://archive.orkl.eu/dd7caea78c4fa610ef997c5f13845b5855ec77ac.txt",
		"img": "https://archive.orkl.eu/dd7caea78c4fa610ef997c5f13845b5855ec77ac.jpg"
	}
}