{
	"id": "7cbba2e0-e9b6-4ed5-b20b-40fd7a25de11",
	"created_at": "2026-04-06T00:09:11.829515Z",
	"updated_at": "2026-04-10T13:12:37.299985Z",
	"deleted_at": null,
	"sha1_hash": "440a419ae2fefb1fcc399aee801119980729918e",
	"title": "MassLogger v3: a .NET stealer with serious obfuscation",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3340220,
	"plain_text": "MassLogger v3: a .NET stealer with serious obfuscation\r\nBy Threat Research TeamThreat Research Team\r\nArchived: 2026-04-05 15:38:26 UTC\r\nForum Advertisement\r\nMassLogger is an information stealer, first sold in hacking forums around April 2020. The malware author claims\r\nit to be the “most powerful logger and recovery tool” which costs $99 USD worth of Bitcoin for a lifetime license.\r\nMassLogger is highly configurable and gives its malicious users many options for delivery, anti-detection and\r\nanti-analysis, and capabilities such as keylogging and password stealing from a wide variety of browsers and\r\napplications.\r\nAvast researchers have found that it is most commonly found in Turkey, Spain, Ukraine, Chile, the United States,\r\nBrazil, the United Kingdom, Germany and Poland.  Avast AV is detecting this malware under\r\n“MSIL:MassLogger-*”. In addition, the latest variant of MassLogger will not run if it finds Avast or AVG AV\r\npresent in the system.\r\nMap illustrating the countries MassLogger has targeted from October 2020 to February 2021\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 1 of 9\n\nAdvertised Features\r\nThe malware author has an active Github directory where he shares the source code of multiple malware features\r\nand packers for educational purposes. We are able to find many similarities between what is being used in the\r\nmalware and some of his Github projects.\r\nIn August 2020, FireEye wrote an article explaining how to get past the anti-analysis tricks used by MassLogger\r\nversion 1.3. Recently Talos wrote on MassLogger version 3. In their post, they focus on the campaign and delivery\r\nof the malware. In this blog, we will provide the last missing piece, a detailed analysis of the final payload’s\r\nobfuscation which includes operation codes and an interpreter as well as indirect calls to unassigned fields.\r\nAnalysis\r\nOur analysis is demonstrated with sample\r\nSHA256: 2487B12F52B803F5D38B3BB9388B039BF4F58C4B5D192D50DA5FA047E9DB828B\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 2 of 9\n\nPopulate fields with methods at run-time\r\nScanning through the decompiled code, the majority of function calls are performed in an indirect manner where it\r\ntries to call uninitialized field values. As a result, the control flow of the malware are totally hidden from static\r\nanalysis\r\nPE Entry Point\r\nIndirect call definition\r\nMo() is a wrapper function whose purpose is to call the 4th argument, in this case, vZ.kj. Interestingly, vZ.kj is of\r\nfield type instead of method type, and there is no trace of it being assigned. Revisiting the vZ declaration, we find\r\nout that it is just one of the many internal sealed classes whose structure consists of field values with no assigned\r\nreferences, a caller function similar to Mo(), and an external “Invoke” function. In addition, they all call a function\r\nwith token 0x060004D8 in the module initialization phase.\r\n \r\n0x060004D8 is in charge of decrypting the 2KB embedded resource to build a dictionary between field tokens and\r\nmethod tokens. The field vZ.kj mentioned above has token 0x040001E2 which is mapped with method token\r\n0x060001E0\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 3 of 9\n\nField-Method Dictionary\r\nOnce the dictionary is constructed, the function looks through all the fields with Static, NonPublic, or GetField\r\nflag in the module to find the corresponding method tokens. If the token belongs to a static method, it will be\r\nassigned directly to the field using fieldInfo.SetValue()\r\nIf the specified method is not declared as static, a wrapper for the intended method is constructed then assigned to\r\nthe field. This dynamically created method has an additional parameter of type\r\nSystem.Drawing.Imaging.ImageCodecInfo. The call to the intended function will be made through\r\nOpCodes.Callvirt or OpCodes.Call based on whether the first byte of the token is modified or not. For example,\r\nif the token is 0x46000361 in the dictionary, it will be converted back to the standard token 0x06000361, and\r\nOpCodes.Callvirt will be used instead of OpCodes.Call.\r\nAssigning dynamic method to field\r\nThese dynamic wrapper methods may cause additional overheads when debugging due to the transfer to\r\nDynamicResolver.GetCodeInfo() method before the intended function is reached.\r\nString Decryption\r\nAll strings used in the malware are encrypted and stored in the 23KB embedded resource. The method token\r\n0x060004DB acts as the string provider where it decrypts and stores the string table upon its first run. This method\r\nreceives the offset of the required string, the first DWORD is read to determine the string length, then the string\r\nfollowing after is returned.\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 4 of 9\n\nExample of how MassLogger decrypts its strings\r\nRetrieving Operation Codes from Resource\r\nAfter the string decryption, the malware leads us to function 0x060001DF where the malware reveals its secretive\r\nflow control in the form of operation codes. First, an array of objects are deserialized from the 3rd 3KB embedded\r\nresource. These objects contain a list of operation codes and additional data that will be fed into an interpreter to\r\nperform tasks such as invoking a function, creating a new object, or modifying a List.\r\nEmbedded resource contains reading instructions and operation codes\r\nIn order for the object array to be deserialized, the malware first starts with initializing the following structures:\r\nAn array of 255 bytes. The first byte in the resource indicates the next number of words used to assign\r\nvalues to this array. The first byte in each word, ie 0x23 or 0x1B in the capsules, represent the index; while\r\nthe second byte, ie 0x1 in the capsules, represents what read operations to use:\r\n0x1 = Custom Binary Reader\r\n0x2 = ReadInt64\r\n0x3 = ReadSingle\r\n0x4 = ReadDouble\r\n0x5 = Read an array of data\r\nList of strings. The following byte, 0x0 in the square, determines the size of the list. In this case, no string\r\nwill be needed\r\n An array of objects to be deserialized. The next byte, 0x9 in the square, tells us the size of the array. Each\r\nmember of the array will be initialized to null and reconstructed on the later step.\r\nAn array of offsets. This array has the same size as the object array and represents where the data\r\nassociated with each object locates in the resource. Each entry of this array will be filled in using\r\nCustomBinaryReader starting at the position after the 0x9 byte.\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 5 of 9\n\nWhen the above structures are in place, a lengthy routine that resides in 0x060001DF will start reconstructing a\r\nspecified object from the array by reading the proper resource data. The main purpose of this object is to form a\r\nlist of operation codes and the needed parameters to perform them.\r\nOperation codes stored inside deserialized object\r\nThe first part is the operation code which ranges from 1 to 173, while the second part represents the operand. The\r\ninterpreter for these operations locates inside method 0x06000499 and consists of 157 unique handlers. This\r\nmassive implementation is indicative of a commercial code protection tool, but we aren’t unable to find any\r\nfurther information at the moment.\r\nOperation code Interpreter\r\nThe meaning of important operation codes from the above example:\r\n154 : \u003cmethod token\u003e: invoke the specified method after reconstructing the needed arguments and the\r\nreceiver of the returned value. \r\n127 : \u003cconstructor method token\u003e: create a new object after reconstructing the needed arguments for the\r\nconstructor and where the new object will be assigned to\r\n21 : \u003cfield Token\u003e: get the value of the specified field, usually an encrypted config which is used by\r\noperation “166 : 0x60001C3” for decryption\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 6 of 9\n\nConfig Decryption\r\nA block of Base64 encoded strings can be found in the middle of the decrypted string table:\r\nDecrypted String Table\r\nThese are MassLogger encrypted config. First, each encrypted config is assigned to the corresponding field in\r\nModule 0x02000044. Note that the module token is consistent across all MassLogger v3 samples that we looked\r\nat.\r\nNext, the config.Key is base64 decoded and used as the PBKDF2 password to derive a 32bytes _key (decryption)\r\nand a 64 bytes _authKey (encryption). When the malware is ready to read the config for usage, function\r\n0x060001C4 from module 0x02000045 decrypts each config field with the following steps:\r\nBase64 decoded\r\nThe first 32 bytes are SHA256 checksum which is used to verify the integrity of the string\r\nThe next 16 bytes are used as IV\r\nThe config is decrypted using AES with _key and IV from the previous step\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 7 of 9\n\nThe full config of this sample: https://github.com/avast/ioc/blob/master/MassLogger/config.txt\r\nFunctionality\r\nDespite the variation of obfuscation technique in each version, MassLogger makes little change in its\r\nfunctionality. Compared to the analysis in June 2020, a check for Avast and AVG AV ( looking for AvastGUI and\r\nAVGUI processes) is added at the beginning of execution. In addition, the malware has minimized the amount of\r\nfingerprints left on the system. The log data is no longer write to disk, and the “MassLogger” keyword has been\r\nremoved:\r\nComparison between version 1.3 and version 3.0 log data\r\nConclusion\r\nMassLogger is a versatile .NET information stealer with a complete list of features. The malware employs heavy\r\nobfuscation techniques which we intend to describe in this article. At the moment, we can’t confirm whether the\r\nmalware is packed with a commercial crypter, but its complexity may indicate so. We also illustrate how the\r\nconfiguration can be extracted which can help with identifying IOCs for a particular sample.\r\nIndicators of Compromise\r\nThe full list of IoCs is available at:\r\nhttps://github.com/avast/ioc/tree/master/MassLogger\r\nA group of elite researchers who like to stay under the radar.\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 8 of 9\n\nSource: https://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nhttps://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://decoded.avast.io/anhho/masslogger-v3-a-net-stealer-with-serious-obfuscation/"
	],
	"report_names": [
		"masslogger-v3-a-net-stealer-with-serious-obfuscation"
	],
	"threat_actors": [],
	"ts_created_at": 1775434151,
	"ts_updated_at": 1775826757,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/440a419ae2fefb1fcc399aee801119980729918e.pdf",
		"text": "https://archive.orkl.eu/440a419ae2fefb1fcc399aee801119980729918e.txt",
		"img": "https://archive.orkl.eu/440a419ae2fefb1fcc399aee801119980729918e.jpg"
	}
}