{
	"id": "f4b85af7-248f-4aa5-82ea-20d8e3dae47e",
	"created_at": "2026-04-06T00:10:37.412875Z",
	"updated_at": "2026-04-10T03:21:50.031849Z",
	"deleted_at": null,
	"sha1_hash": "475ec04b662cabd857a4ee2e933de7165a34fddf",
	"title": "An old enemy – Diving into QBot part 1",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 287954,
	"plain_text": "An old enemy – Diving into QBot part 1\r\nPublished: 2020-03-30 · Archived: 2026-04-05 13:31:26 UTC\r\nWhile checking out the Triage Sandbox[1] I stumbled across upon QBot which I’ve seen already plenty of times\r\nat work at GData Cyberdefense AG[2]. This time I wanted to take a closer look at the sample myself.\r\nThe first part of this blog article dives deep into how the packer works.\r\nTriage sandbox overview of the analysed sample\r\nQuick summary\r\nThe packer used by this sample first allocates virtual memory and fills it with chunks of bytes from its .text\r\nsection.\r\nAfter jumping into this allocated area, the address of GetProcAddress [3] is determined by looping over the\r\nexport table of KernelBase.dll . This function is then used to load further dependencies.\r\nNext another temporary memory is allocated, filled with decrypted code and replaces the code we started with.\r\nFinally the sample jumps back to the now decrypted payload and executes it.\r\n1 – Allocating VirtualAlloc\r\nVirtualAlloc routine captured in IDA\r\nThe first step itself does not decrypt any code, however it writes bytes in 0x64 chunks into virtual memory\r\n2304 times (0x38400 / 0x64) . The position of these chunks are calculated loop after loop and do not lie linear\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 1 of 6\n\nin the memory.\r\n2 – Loading dependencies\r\nOnce the virtual memory is allocated we can dump the code and load it into IDA to analyse it.\r\nAfter returning the base address of the KernelBase.dll , the offset to the GetProcAddress function is\r\ndetermined by iterating over the export table.\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 2 of 6\n\nSome exported functions of KernelBase.dll\r\nExplaining this behaviour in pseudo code makes it clearer:\r\nfunc = \"GetProcAddress\";\r\nsymbols = getSymbols()\r\nfor symbol in symbol:\r\n if symbol == func:\r\n return getOffsetToFunc(symbol)\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 3 of 6\n\nSearching for GetProcAddress in the debugger\r\nWith GetProcAddress the location of LoadLibrary is returned. By using these two functions the packer is now\r\nable to write offsets of needed library functions into memory.\r\n3 – Decrypt the code\r\nIn the third step the actual payload is being prepared. VirtualAlloc [4] sets up another memory area which is\r\nused to hold decrypted code temporarily. After the decryption is finished a fully unpacked PE file lies now in\r\nmemory. The PE sections we started with are zero’ed and replaced with the new decrypted sections.\r\nSome exported functions are still missing. In order to determine their position the same trick is used which I\r\nalready explained in the second step. This time though, different libraries are used.\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 4 of 6\n\nDetermining position of final dependencies\r\n4 – Returning to the payload\r\nAll that is left now is to return to the unpacked sample via return instruction because the return address is still\r\nwritten onto the stack.\r\nReturn back to where we started at\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 5 of 6\n\n5 – IoCs\r\nSample SHA256 c23c9580f06fdc862df3d80fb8dc398b666e01a523f06ffa8935a95dce4ff8f4\r\nSource: https://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nhttps://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://malwareandstuff.com/an-old-enemy-diving-into-qbot-part-1/"
	],
	"report_names": [
		"an-old-enemy-diving-into-qbot-part-1"
	],
	"threat_actors": [],
	"ts_created_at": 1775434237,
	"ts_updated_at": 1775791310,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/475ec04b662cabd857a4ee2e933de7165a34fddf.pdf",
		"text": "https://archive.orkl.eu/475ec04b662cabd857a4ee2e933de7165a34fddf.txt",
		"img": "https://archive.orkl.eu/475ec04b662cabd857a4ee2e933de7165a34fddf.jpg"
	}
}