{
	"id": "b5ec2ce3-c696-406e-b8b9-117a1c354aaf",
	"created_at": "2026-04-10T03:21:07.035796Z",
	"updated_at": "2026-04-10T13:11:47.715572Z",
	"deleted_at": null,
	"sha1_hash": "e7fac77fff3da0e257517823e51500232580ff6a",
	"title": "Qakbot Series: API Hashing",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 367869,
	"plain_text": "Qakbot Series: API Hashing\r\nPublished: 2022-04-16 · Archived: 2026-04-10 02:09:02 UTC\r\nIn late March 2022, I was requested to analyze a software artifact. It was an instance of Qakbot, a modular\r\ninformation stealer known since 2007. Differently to other analyses I do as part of my daily job, in this particular\r\ncase I can disclose wide parts of it with you readers. I’m addressing them in a post series. Here, I’ll discuss about\r\nthe Qakbot API hashing techinque based on this specific sample.\r\nFigure 1\r\n-\r\nExample of protected API call in Qakbot\r\nAPI hashing is an anti-analysis technique aimed at hiding a potential source of information about the malware\r\ncapabilities. Analysts are used to rely on the API calls to form an hypothesis of what a given piece of code tries to\r\ndo because much of the malware behavior can be inferred by looking at how it interacts with the operating system.\r\nAs an example, Figure 1 shows a call to CreateThread (kernel32.dll) located at 0xb2348b. You cannot see any\r\nreference to CreateRemote thread into the code, besides the comment I placed to slightly improve the code\r\nreadability. To understand what is happening here, I need to describe the API hashing technique implemented in\r\nthe sample object of analysis. Luckly, this section is all around this topic.\r\nhttps://www.malwarology.com/2022/04/qakbot-series-api-hashing/\r\nPage 1 of 3\n\nFigure 2\r\n-\r\nQakbot API de-hashing main function\r\nQakbot attempts to invoke functions exported by 11 dynamic-link libraries: kernel32.dll, ntdll.dll, advapi32.dll,\r\nnetapi32.dll, shell32.dll, shlwapi.dll, user32.dll, wininet.dll, urlmon.dll, crypt32.dll, and wtsapi32.dll. I know that\r\nbecause I found tracks of those libraries into the strings. Don’t panic if you won’t find those strings into the\r\nsample because they are obfuscated. If you’are interested in knowing how Qakbot obfuscates the strings, I address\r\nthe topic in this post. From those strings, I was able to discover the function responsible for the API de-hashing.\r\nFor API de-hashing I mean the process allowing to retrieve API addresses starting from rather anonymous\r\nnumbers called hashes. That function is located at 0xb3050a and it is showed in Figure 2.\r\nThat function expects three arguments. The very first argument is an hash table, namely a vector of 32 bits hashes.\r\nA very important point to make clear here is that there is a dedicated and hardcoded hash table for every DLL\r\nmentioned above. The second argument is the size of the hash table. The last argument is the offset used by the\r\nfunction deobfuscate_string_1 to de-obfuscate the name of the DLL. The goal of the de-hashing function consists\r\nin allocating a new table containing the memory address of all the required APIs for the given DLL. Once such an\r\naddress table is allocated, invocations for an API may occur by just pointing at the corresponding entry in the\r\ntable. Figure 1 shows an example of this type of invocation where the offset 0x1c2 is aligned with the memory\r\naddress of CreateThread into the kernel32.dll table (actually, the offset for CreateThread is 0x70, as it is possible\r\nto observe into the assembly listing at 0xb2348b. For some reason, Ghidra decompiler reconstructed a different\r\noffset).\r\nAs a side note, 0x6e2 is the offset for kernel32.dll therefore the first condition in the listing of Figure 2 checks if\r\nthe caller has requested an API exported by kernel32.dll. Indeed, if that is the case then it is sufficient to invoke\r\nGetModuleHandleA to obtain an handle to the DLL because kernel32.dll is mapped in the memory space of every\r\nprocess at loading time. Otherwise, if the requested module isn’t kernel32.dll, LoadLibraryA is invoked to obtain\r\nthe same result. Notice that in the latter case the API invocation occurs via the kernel32 address table where\r\nLoadLibraryA lies at offset 0.\r\nFigure 3\r\n-\r\nHash checking to identify the requested export name\r\nhttps://www.malwarology.com/2022/04/qakbot-series-api-hashing/\r\nPage 2 of 3\n\nThe actual de-hashing occurs in a sub-function of resolve_api_address located at 0xb303ca. This function is\r\nresponsible for resolving the address of a specific API of a given module starting from an hash. The code snippet\r\nshowed in Figure 3 highlights the hash check. That loop enumerates all the export names of a module and ends in\r\ntwo cases:\r\nWhen the hash provided to resolve_api_address is equal to the hash of an export name xor-ed with an\r\nhardcoded constant (0x218fe95b). In this case there is a hit and the export name is later provided to\r\nGetProcAddress to obtain the corresponding API address.\r\nThe provided hash doesn’t correspond to any export name of the module. In this case the function returns\r\nNULL.\r\nI close this post by sharing the mapping between hashes and all the API functions requested by this Qakbot\r\nsample. You will find the mapping here. Each row in this file contains the library exporting the API function, the\r\noffset into the address table, the hash, and finally the API function name. The offset may turn useful for analysis\r\npurposes because it is often hardcoded as showed in Figure 1.\r\nAs always, if you want to share comments or feedbacks (rigorously in broken Italian or broken English) do not\r\nesitate to drop me a message at admin[@]malwarology.com.\r\nSource: https://www.malwarology.com/2022/04/qakbot-series-api-hashing/\r\nhttps://www.malwarology.com/2022/04/qakbot-series-api-hashing/\r\nPage 3 of 3",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.malwarology.com/2022/04/qakbot-series-api-hashing/"
	],
	"report_names": [
		"qakbot-series-api-hashing"
	],
	"threat_actors": [],
	"ts_created_at": 1775791267,
	"ts_updated_at": 1775826707,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/e7fac77fff3da0e257517823e51500232580ff6a.pdf",
		"text": "https://archive.orkl.eu/e7fac77fff3da0e257517823e51500232580ff6a.txt",
		"img": "https://archive.orkl.eu/e7fac77fff3da0e257517823e51500232580ff6a.jpg"
	}
}