{
	"id": "7eca2ae8-3524-4378-89eb-ecf3f31870cf",
	"created_at": "2026-04-06T00:15:50.7845Z",
	"updated_at": "2026-04-10T13:11:42.763685Z",
	"deleted_at": null,
	"sha1_hash": "9b7d264b77e93665024b52aa74826e948e623f8d",
	"title": "Analyzing Modern Malware Techniques - Part 1",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 75799,
	"plain_text": "Analyzing Modern Malware Techniques - Part 1\r\nBy Danus\r\nPublished: 2020-01-18 · Archived: 2026-04-05 20:12:28 UTC\r\nAnalyzing Modern Malware Techniques\r\nFileless malware - Self Loading Technique\r\nFileless malware is nothing new, but is very much used today. The idea is to load a payload into memory and to\r\nleave as much as little evidence as possible on the hard drive of the computer. This can be achieve by various\r\ntechniques such as:\r\n1. Using PowerShell to further infection in the machine.\r\n2. Using the Registry to save malicious payloads without dropping them on disk.\r\n3. Using WMI(Windows Management Instrumentation) to collect data about the computer.\r\nThese techniques go under a category called “Living Off the Land” which means the malware authors utilize\r\nWindows tools to exploit and manipulate them for malicious activities.\r\nToday we’re gonna look at Kovter, a click-fraud malware, it’s file-less payload is a bit different from the\r\ntechniques mentioned above. I will be looking at its unique way of loading its payload without dropping a single\r\nfile on disk, I’ll be exploring a sample to show how it actually achieves this.\r\nRecommended background required:\r\n1. Knowledge in C and WIN API\r\n2. Knowledge in x86 Assembly and basic usage of IDA PRO\r\n3. Basic understanding of the PE File format\r\nTools used for the article:\r\n1. IDA PRO 7.0\r\n2. x64dbg\r\n3. PEBear\r\n4. Resource Hacker\r\n5. VMWare Workstation 14.0\r\nSamples used:\r\n4160d0e5938b2ff29347476788f3810e\r\nSetting up some goals:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 1 of 14\n\nI found this sample in a malwarebytes blog post, Where the author goes into a brief mentioning that the sample\r\nloads an encrypted PE file from the resource section. It maps the file inside its own memory and dynamically\r\nresolves it completely, without dropping it on disk. It is then mentioned that the mapped payload lives off the\r\nloader host, it depends on it and without it, it cannot work.\r\nSo we’re gonna be looking for:\r\n1. Resource section handling API(ResourceSize, ResourceLock, ResourceLoad).\r\n2. Any memory allocating API(HeapAlloc, VirtualAlloc).\r\n3. Reference to any PE File format structures.\r\n4. API Resolving API’s(LoadLibrary, GetProcAddress).\r\nWe know the payload is encrypted so we don’t want to dig in looking into how the file is decrypted, we want to\r\nfind it decrypted.\r\nStatic Analysis:\r\nI decided to first load the file in IDA and scan for strings or valuable imports:\r\nThis is incredible - we find everything we need off the spot. Calls to HeapAlloc, VirtualAlloc, LoadLibrary,\r\nGetProcAddress and resource related functions.\r\nLet’s look at the entry point of the binary:\r\nWe’re presented with a long list of functions being called in a linear order… not really helpful.\r\nimage\r\nBefore I dissect the malware further I decide to look into the resource section using Resource Hacker:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 2 of 14\n\nA resource, it’s called DATA and its encrypted. So let’s be on the lookup for any reference to the string “DATA”\r\nin memory.\r\nBack in IDA, it’s really hard to realize what’s going on if we go free diving in the binary. It’s better off to start at\r\nthe bottom so first let’s explore the areas that are of value.\r\nWe’ll start off with the Resource API calls:\r\nA call to FindResourceW is referenced at 00402B0E:\r\nWe can easily map out the local Variables var_8 and var_C and ESI, We know that by stdcall convention, the\r\nreturn value is passed into eax from each function.\r\nFindResourceW returns a handle of type of HRSR(Handle to a resource information block) is passed inside esi.\r\nSizeOfResource returns a DWORD which represents the size of the resource in bytes, this goes into var_C\r\nLoadResource returns a handle of type HGLOBAL which represents a handle to the source, it is directly passed\r\ninto LockResource\r\nLoackResource returns a pointer to the first byte in the resource, this goes into var_8.\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 3 of 14\n\nLet’s rename everything in IDA so we’ll have a more clear view of things:\r\nCool, now lets rename the function to something more valuable for us, so we can find it later(sub_00402AD0 -\u003e\r\nLoadResourceFromMemory)\r\nNext let’s look at VirtualAlloc, we’ll use the xrefs from the Import view in IDA to look up the VirtualAlloc API\r\nCall(can be found at 0x4029F0):\r\nWe can map var_34, which will point to the first byte of the allocated space, it is used a lot during the program so\r\nlets rename it right now to lpvoidPointerToAllocatedSpace\r\nthe instruction sequence:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 4 of 14\n\nis this an entry inside a structure or an array? I cannot tell for sure at this point.\r\nIf we scroll down, we can see LoadLibrary and GetProcAddress are being called in a loop fashion:\r\nLet’s start from the top(code block 0x4029C2): If EDI is not empty, a DLLs base address will be resolved using\r\nLoadLibraryA. That address will be saved in EBX, which we can clearly see is being passed to GetProcAddress\r\nto get a base address of an API(code block 0x40299C). When resolved, it’s then saved inside [EDX].\r\nthen at location loc_4029AE two local variables are incremented by four which can be represented as an indexers\r\ninside an array of pointers.\r\nAt first glance, I instantly thought about one thing, the binary is attempting to resolve the Import Address Table of\r\nanother binary. but it’s really too early to make such assumptions.\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 5 of 14\n\nLets give this function a name(sub_40274C -\u003e ExecuteNewResolvedPEinResources)\r\nNow let’s check who called ExecuteNewResolvedPEinResources, it’s sub_402C58. Hmm… Interesting this\r\nfunction also calls LoadResourceFromMemory.\r\nThe caller of this function(sub_402C58) is the start function which is the entry point of the program. In addition\r\nsub_402C58 is also the last function being called before the loader binary shuts itself down. Great! We know\r\nwhere to stop and what to look out for!\r\nDynamic Analysis:\r\nBreakpoints to set before execution:\r\n1. LoadResourceFromMemory(00402CA5)\r\n2. ExecuteNewResolvedPEinResources(00402D7F)\r\n3. VirtualAlloc(00402807)\r\n4. LoadLibraryA(00402941)\r\n5. sub_402C58(00402C58)\r\nRight so upon execution we should directly land at sub_402C58.\r\nbefore entering LoadResourceFromMemory(0x402CA5), we can see “DATA” is being passed into EAX which\r\nis the name of the resource we saw before.\r\nThen we can see that the pointer to the first byte in the loaded resource is being passed into var_8(ebp-8).\r\nbut as we exit the function, we lose all reference to it, we just know its located at 0x00407064(the resource is still\r\nencrypted.)\r\nLooking at the code following that function, we just see a huge linear code block - calling various functions. We\r\ncould go scanning these functions, but this might go into a rabbit hole I wish not enter. I’m working on the\r\nassumption that as soon as the file is going to be mapped into memory, it’s going to be mapped in its decrypted\r\nform. I decide to step over most of these calls.\r\nimage\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 6 of 14\n\nAnd what do you know - if we continue skipping these functions we’ll start seeing the string MZP being shown in\r\nthe debugger. first its referenced as “M8Z” and finally before entering ExecuteNewResolvedPEinResources\r\n(0x402D7E) We get a valid PE file header!\r\nEDX contains a pointer to the decrypted file, EAX contains the path string to the location of the loader binary and\r\nECX contains value 0x00066A00.\r\nSo let’s go into ExecuteNewResolvedPEinResources in IDA and see if we can map this data out(yes we can!)\r\nIf we keep on going, nothing really happens until we hit the code block at loc_4027BB:\r\nvar_38 passed by EBX is now a pointer to a newly allocated PE File, after calling the function(0x4027BE) in the\r\nblock it returns that pointer into EAX.\r\nIf we do decide to enter that function(0x4027BE), it leads to a rabbit hole of more functions. I decided not to get\r\ninto it(If we resolve the location of the calls to HeapAlloc, this function might eventually call it. I speculate that\r\nthis function has something to do with either confusing the analyst or it attempts to map out different sections of\r\nthe PE, either way it has not much value to us anyway).\r\nEAX assigns this new pointer into var_10 and var_18 and then something interesting happens - the binary\r\nattempts to check if [EAX] contains the string “ZM”(0x5A4D). I input the data I collected inside IDA:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 7 of 14\n\nI decide to conclude that var_18 is actually a pointer to IMAGE_DOS_HEADER, well see if this assumption is\r\ncorrect.\r\nAt the next code block, the code loads the address of the IMAGE_DOS_HEADER and adds 0x3C to it and\r\nattempts to compare it to “EP”( 0x4550).\r\ne_lfanew is the last field in the IMAGE_DOS_HEADER and contains a the offset of the\r\nIMAGE_NT_HEADERS structure in the file, “PE” is the the value of the first field located inside\r\nIMAGE_NT_HEADERS, Signature:\r\nThe next code block calls VirtualAlloc. I decide to map my assumptions into IDA:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 8 of 14\n\nSizeOfImage field located inside the OptionalHeader represents the size of the binary in bytes. EAX plus EAX\r\nwill contain double that size. so its for two binaries.\r\nAt this point, there is too much evidence to conclude that the loader binary is loading and mapping out the file\r\nlocated in the resource section “DATA”.\r\nThe next code block contains the following instructions:\r\nif we look through the entire block var_14 is almost always passed in EDX, and looking inside the function\r\nsub_4022B4 we can see that both EAX and EDX are being used. EAX when passed to this function will point\r\npast the entire size of the PE file. while EDX will contain random data. If we’ll dig even deeper inside\r\nsub_4022B4. we can see the data contained in EDX is being written on the boundary allocated previously for the\r\nsecond PE file! so let’s rename everything:\r\nIf we keep reversing this entire code block, the main conclusion is the code block is copying the first resource\r\nbinary we found to lpvoidPointedToNewAllocatedAreaForImage+SizeOfImage+4. then at 0x0040287D, the\r\nresource binary is being copied again to lpvoidPointedToNewAllocatedAreaForImage.\r\nThese two binaries are separated by a boundary contained in the variable lpvoidDataToPopulate( contains the\r\nvalue 0x66A00)\r\nWe rename sub_4022B4 to MapMemoryData, and var_14 will be renamed to lpvoidDataToPopulate.\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 9 of 14\n\nRe-mapped view of IDA:\r\nBoundary value:\r\nwe move on to the code block located at 0x00402891:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 10 of 14\n\nThis loop goes through all the sections located within the resource and maps them into the newly allocated\r\nmemory.\r\nThis can be observed in the debugger if we access and view the dump of EAX before call to MapMemoryData\r\nand after the call. it should be noted that the sections are being mapped into the first memory area allocated for the\r\nPE from the resource sections and not the second.\r\nAt 0x4028EC, we can see that the ImageBase of the resource binary in memory is being changed, this field\r\nlocated in IMAGE_OPTIONAL_HEADER is usually set for 0x400000 for binaries but it’s being changed, to\r\npoint to the memory pointed by the new allocated memory for the binary.\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 11 of 14\n\nIn the next block it gets really interesting(0x4029B6):\r\nA loop begins to resolve the IAT, of the second area allocated for the binary mapped into memory. I will not\r\nbother explaining this in depth but this entire thing occurs in this loop which is described in this diagram:\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 12 of 14\n\nAnd now finally, after iterating resolving the IAT we jump into loc_4029D0.\r\nThe address of the entry point of the binary is passed into var_8, and then it is called. the two loaded binaries\r\ndepending on each other to execute, one is going to execute its code and the other contains resolved IAT\r\naddresses.\r\nLets create a diagram detailing how this loader operates so it would be more clear what just happened and it would\r\nalso be easier for us to understand the loading of payload.\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 13 of 14\n\nConclusion:\r\nIn this article, I demonstrated how a malware might hide itself in memory by loading its encrypted payload into\r\nitself, thus attempting to stay undetectable and to avoid dropping files on disk.\r\nIn the next part of this series we’ll be exploring how malware might use PowerShell and the Registry to execute a\r\nFile-less attack.\r\nResources used:\r\nPE File Format\r\nUntangling Kovter’s persistence methods\r\nSource: https://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nhttps://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://0x00sec.org/t/analyzing-modern-malware-techniques-part-1/18663"
	],
	"report_names": [
		"18663"
	],
	"threat_actors": [],
	"ts_created_at": 1775434550,
	"ts_updated_at": 1775826702,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/9b7d264b77e93665024b52aa74826e948e623f8d.pdf",
		"text": "https://archive.orkl.eu/9b7d264b77e93665024b52aa74826e948e623f8d.txt",
		"img": "https://archive.orkl.eu/9b7d264b77e93665024b52aa74826e948e623f8d.jpg"
	}
}