{
	"id": "f73b2f00-0dfc-4fa9-907b-a2512557abe3",
	"created_at": "2026-05-06T02:03:17.499164Z",
	"updated_at": "2026-05-06T02:03:52.72638Z",
	"deleted_at": null,
	"sha1_hash": "506701ad25230c9459a8efb530a03f6df640e082",
	"title": "HijackLoader: Free Games, Costly Consequences, and Loads of Malware",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1109540,
	"plain_text": "HijackLoader: Free Games, Costly Consequences, and Loads of\r\nMalware\r\nBy G DATA Security Center\r\nPublished: 2026-03-17 · Archived: 2026-05-06 02:01:52 UTC\r\nPiviGames, a popular Spanish gaming platform is well-known in the gaming community for providing download\r\nlinks to pirated PC games. Such a platform offers attractive content and it has built a reputation within the gaming\r\ncommunity over the years. However, PiviGames has become more than just a source of free entertainment; it has\r\nevolved into a full-blown malware distribution hub, allowing malicious actors to compromise unsuspecting users.\r\nWritten by Karsten Hahn and John Dador\r\nIn this article, we’ll dive into how this pirate gaming platform turns fun and “free” entertainment into an\r\nopportunity for cybercriminals and why a single download of a pirated game can cost you more than a few hours\r\nof gameplay. \r\nThis blog series consists of two parts. This article is part one and discusses the initial infection\r\nand HijackLoader in detail. The second part describes the ACRStealer payload. \r\nInitial infection\r\nIn November of 2025, we discovered a Reddit post (figure 1) about malicious activity. The redditor claimed to\r\nhave been hacked by an unknown infostealer after they had downloaded a game. The\r\ninitially reported file was masquerading as a Python-based setup\r\nfile but upon investigation, the downloaded file had been changed into a different one. This signaled to us\r\nthat the URL is still live and actively infecting. \r\nWe asked the affected user for the download URL. This led us to PiviGames, a pirate gaming site.\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 1 of 14\n\nFigure 1: Reddit post of the suspicious Python setup\r\nPiviGames redirection as malvertising\r\nAnalysis of the website shows that it employs Cloudflare’s challenge and telemetry scripts to appear legitimate.\r\nHowever, upon closer inspection at the start of the code, it loads\r\na JavaScript file named pgedshop.js. This JavaScript file is the one responsible for\r\nredirecting users to malicious sites. This script contains two defined URLs and uses browser cookies to\r\ncontrol the site's redirection behavior. On the user’s first visit, the\r\nscript redirects it to hxxps://adbuho[.]shop/HIx0J which appears to be an advertising network. It then marks the\r\ncookies used so that the following visits will redirect to hxxps://pulseadnetwork[.]com/jump/next.php?\r\nr=2558259, which is also a benign advertising network (not hosting a malicious file).\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 2 of 14\n\nFigure 2. Redirection of pgeshop.js\r\nThe URL hxxps://adbuho[.]shop/HIx0J redirects to a domain consisting of randomized characters followed by\r\na top-level domain \".pro/\" and an additional randomized path. This redirection chain ultimately leads to a\r\nMediaFire download link. \r\nThe MediaFire link hosts a ZIP archive file named \"Full Version Setup 6419 Open.zip\". Notably, the\r\npassword is directly embedded in its filename (“6419”).   \r\nUpon extracting the ZIP file, multiple resource files are present along with a single executable file\r\nnamed Setup.exe[2].  \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 3 of 14\n\nFigure 3. Full Version Setup 6419 Open.zip folder directory\r\nHijackLoader\r\nThe Setup.exe[2] is a clean game launcher, but it executes malicious code via DLL sideloading, when the\r\ngame loads Conduit.Broker.dll[3].  \r\nConduit.Broker.dll[3] belongs to the HijackLoader family. Notable analysis and descriptions of this loader family\r\nhave been done before by Nikolaos Pantazopoulos in [zscaler23] and [zscaler25] and by Ryan Weil in\r\n[trellix25]. Given the malware’s complexity, we believe our analysis adds a few undocumented details.\r\nFurthermore, we provide tooling for HijackLoader.\r\nStage 1: ConduitBroker.dll\r\nThe DLL exports 50 functions and mainly consists of clean code. However, the\r\nfunction BrokerManagerClient_AddPathMapping is patched with malicious code and extends over other\r\nimport functions such as BrokerManagerClient_MapPath. Whoever inserted that patch, did so without\r\nconsideration whether the size fits into that function. This also causes odd behavior in\r\nIDA Pro because some of these functions start in the middle of patched instructions (see figure 4), and IDA insists\r\non keeping function definitions from exports. \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 4 of 14\n\nFigure 4: BrokerManagerClient_MapPath starts one byte after the actual start of the instruction mov\r\nedx, cs:dword_1800748D7\r\nConduit.Broker.dll uses inlined API resolving, which means there is no dedicated function that the malware uses\r\nto dynamically resolve APIs. Instead, the full PEB walking code is inlined whenever a function call should be\r\ndone. We have seen inlined API resolving in various samples in the past two years, for example in RisePro, just\r\nwith a different hashing algorithm.  \r\nThe API hashing algorithm is similar to djb2; however, instead of initializing the seed with 5381 and the multiplier\r\nwith 33, the malware uses 0x8798338 for the seed and 2 for the multiplier. The exact hashing algorithm is as\r\nfollows (Python 3 implementation):\r\ndef calc_hash(apiname):\r\n hash = 0x8798338\r\n for c in apiname:\r\n hash = (ord(c) + 2 * hash) \u0026 0xFFFFFFFF\r\n return hash \u0026 0xFFFFFFFF\r\nThe malware decrypts parts of the file Groumcumgag.ic[4], which resides in the same folder as the DLL. The\r\nheader for the encrypted data blob starts at offset 0x4A19, where the first dword is the size of the encrypted data\r\n(0x2080), and the second dword is an XOR key, in this case 0x1CAB3515. Right after that follows\r\nthe XOR encrypted data iself (see figure 5).\r\nFigure 5: The encrypted blob of the file Groumcumgag.ic starts with size and key at offset 0x4A19\r\nWe created a decryption script for Groumcumgag.ic that you can download here. The decrypted\r\nblob contains shellcode for the next stage and the name of a DLL, which is in this case “evr.dll”, the Enhanced\r\nVideo Renderer. \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 5 of 14\n\nConduit.Broker.dll then loads the next stage via module stomping: First,\r\nit loads the legitimate system32 library “evr.dll” and injects the decrypted shellcode into the BaseOfCode of\r\n“evr.dll”. Then, it calls a function of the shellcode with a struct as argument that, among\r\nothers, contains the filename “Zootkumbak.uhp”. This file is the configuration for the malware.\r\nStage 2: evr.dll shellcode and module table\r\nThe shellcode in evr.dll has the main purpose of concatenating and decrypting the main configuration from\r\nthe file Zootkumbak.uhp[5].  \r\nBut first it resolves imports and determines if certain processes are present by calculating hashes for the process\r\nnames. If it finds any of the targeted processes, it delays execution for five seconds.  \r\nThe hash calculation function for both imports and process names, relies on a constant multiplier from\r\nthe previous stage, so we expect this value to change for other variants of HijackLoader.  \r\nFigure 6: The import and process hashing function for stage two uses a multiplier from the previous\r\nstage\r\nNext, the second stage shellcode parses the Zootkumbak.uhp[5] file. The encrypted data for the configuration is\r\nfragmented into 90 pieces that are scattered across the file. \r\nTo figure out where each of the pieces is located, HijackLoader performs a pattern search. It uses the search\r\npattern ‘?????@IDAT’, which HijackLoader interprets as a wildcarded 4-byte value that is directly followed by\r\nthe string ‘IDAT’. The wildcarded value is the size of the current chunk. Our sample has a total of 90 chunks. \r\nAfter the first ‘IDAT’ pattern starts the header for our encrypted configuration. The full header including the\r\nsearch pattern looks as follows:  \r\nchunk_size | ‘IDAT’ | magic | xor_key | compressed_size | uncompressed_size \r\nEach of these values is four bytes long. The XOR key decrypts all chunks of the configuration. The compressed\r\nsize is the total size of all chunks before decompression and the uncompressed size equivalently is the total size\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 6 of 14\n\nafter decompression. After this header starts the encrypted data of the first chunk. \r\nFor each of the remaining ‘IDAT’ chunks the encrypted data starts directly after the ‘IDAT’ pattern. \r\nTo deobfuscate the configuration file Zootkumbak.uhp, we decrypt each chunk with the XOR key from the header,\r\nconcatenate the chunks in the order they were found, and finally decompress them with LZNT1. \r\nAmong others, the configuration file contains the encrypted payload, various settings and a module table with\r\nnames and offsets to even more configuration data. \r\nWe created a configuration extractor that deobfuscates Zootkumbak.uhp, extracts settings from\r\nit, dumps the payload and all entries of the module table.  \r\nWe use the term “module table” here to be consistent with the terminology of previous articles [zcaler23,\r\nzscaler25, trellix25]. However, the contents are not strictly limited to modules. The table may, in\r\nfact, contain any type of data. In some cases, namely\r\nthe MUTEX, COPYLIST, SM and CUSTOMINJECTPATH, the module table entries are strings-based settings or string lists. In other cases, the entries are configuration settings, shellcode or full PE images. \r\nThe present sample has the following module table entries and values for string entries, you will find\r\na description for each of these entries is in [zcaler23, zscaler25]: \r\nModule Value\r\nAVDATA\r\ncustom structured data containing CRC hashes of AV process names and flags,\r\ncan be decoded with avdata_decoder.py\r\nESAL shellcode, assists with injection\r\nESAL64 shellcode, assists with injection\r\nESLDR shellcode, assists with injection\r\nESLDR64 shellcode, assists with injection\r\nESWR shellcode, assists with injection\r\nESWR64 shellcode, assists with injection\r\nFIXED\r\nPE file, here zip.exe signed by “VMWare Inc”, used a host\r\nfor Process Doppelgänging\r\nLauncherLdr64 PE file for loading the payload\r\nmodCreateProcess shellcode, helps with process creation\r\nmodCreateProcess64 shellcode, helps with process creation\r\nmodTask shellcode, used for persistence\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 7 of 14\n\nModule Value\r\nmodTask64 shellcode, used for persistence\r\nmodUAC shellcode, UAC bypass\r\nmodUAC64 shellcode, UAC bypass\r\nmodWD shellcode, defender evasion\r\nmodWD64 shellcode, defender evasion\r\nmodWriteFile shellcode\r\nmodWriteFile64 shellcode\r\nrshell shellcode, loads the payload via module stomping\r\nrshell64 shellcode, loads the payload via module stomping\r\nti shellcode, main module, 32 bit\r\nti64 shellcode. main module, 64 bit\r\ntinycallProxy shellcode, executes API calls\r\ntinycallProxy64 shellcode, executes API calls\r\ntinystub PE file stub\r\ntinystub64 PE file stub\r\ntinyutilitymodule.dll PE file\r\ntinyutilitymodule64.dll PE file\r\nSM \"mpr.dll\" string, name of clean target dll for module stomping\r\nCOPYLIST\r\nstring list with the following filenames:\r\nConduit.Broker.dll \r\nD_C.exe \r\nGroumcumgag.ic \r\nTE.Common.dll \r\nTE.Host.dll \r\nTE.Loaders.dll \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 8 of 14\n\nModule Value\r\nTE.WinRT.dll \r\nWex.Common.dll \r\nWex.Communication.dll \r\nWex.Logger.dll \r\nZootkumbak.uhp \r\n!D_C.exe \r\n~TE.Loaders.dll \r\nMUTEX  \"RXRCJOIAVDWOEK\" string, used as mutex name\r\nCUSTOMINJECT PE file, MicrosoftEdgeUpdate, used as injection host\r\nCUSTOMINJECTPATH \r\n\"%TEMP%\\d0eccdb9\\MicrosoftEdgeUpdate.exe\" string, path to\r\ndrop CUSTOMINJECT\r\nX64L shellcode\r\nThe second stage shellcode loads the main module from that module table, which is the\r\nshellcode ti64. The configuration file also contains the target DLL path for the next stage in its main header (not\r\nin the module table): %windir%\\SysWOW64\\rasapi32.dll. \r\nJust like the stage before, HijackLoader’s second stage stomps the module: It loads the target rasapi32.dll, then\r\ninjects the next stage’s shellcode into the target’s BaseOfCode and runs it.  \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 9 of 14\n\nFigure 7: HijackLoader extracts the ti64 shellcode and injects it into rasapi32.dll via module\r\nstomping\r\nThe evr.dll shellcode forwards the deobfuscated configuration data and module table to stage three as arguments.\r\nStage 3: ti64 module in rasapi32.dll\r\nThe code of this shellcode is extensive because it handles all the possible settings of the configuration and the\r\nmodule table entries that might be used by HijackLoader. Because it contains most of the interesting code of\r\nthis loader family, it is commonly referred to as the main module of HijackLoader.  \r\nThe ti64 shellcode starts by resolving import functions via API hashing. This time it uses\r\nCRC32 as hashing algorithm.  \r\nNext, it obtains the SM entry from the module table, which is ‘mpr.dll’ in this case, and saves it as target DLL for\r\nmodule stomping. \r\nThe sample then checks NTDLL for inline hooks and, if found, removes them. \r\nIf the ANTIVM module table entry is present, it performs various anti-VM checks. However, the present sample\r\ndoes not have this entry. \r\nIf a specific flag is set in the config, HijackLoader will copy all files, which are listed in the\r\nmodule table entry COPYLIST, to a subdirectory in %ALLUSERSPROFILE% and restart itself there. The\r\nconfiguration defines this subdirectory at offset 0x13 and for our sample this is “d0eccdb9”.\r\nThe ti64 shellcode also loads the encrypted payload from the configuration. To do so, it obtains three values:\r\nrelative data offset, key size, and encrypted data size. \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 10 of 14\n\nAt offset 0xeec starting from the module table is the relative offset to the encrypted data. This offset is relative to\r\nthe module count field at 0xee4, so the actual offset is: module table offset + 0xee4 + relative offset \r\nAt offset module table + 0xca4 is the key size in dwords.  \r\nAt offset module table + 0xca8 is the size of the encrypted data.  \r\nThe encrypted data starts with the XOR key, which decrypts the payload in the remaining data. Our tool decrypts\r\nand dumps the payload to a file named PAYLOAD into the same folder as the module table entries.\r\nTo sum it up, the ti64 shellcode is an orchestrator for most of the modules in the module table and responsible for\r\nthe following features of HijackLoader:\r\nAV product detection and adjustable behavior based on AVDATA flags, process CRC hashes and detected\r\nproducts\r\nPersistence modules\r\nAnti-VM modules\r\nUAC bypass modules\r\nChoosing one of six payload injection or loading techniques\r\nAdjustable injection host files via FIXED and CUSTOMINJECT\r\nInterprocess communication\r\nNTDLL hook detection and removal\r\nProcess injection in ti64 and post stage 3\r\nHijackLoader implements several ways to load and inject the payload in ti64. Several injection_flag bitmasks and\r\nthe presence of a relocation directory determine which injection function it chooses. It is not possible\r\nto determine the meaning of all of these flags based on the sample alone because some are merely read from the\r\nconfiguration. \r\nFurthermore, there is a lot of duplicated code and the parts of ti64 which choose the appropriate\r\ninjection function are scattered between the huge entry point function and various decision trees in subfunctions.\r\nThat makes it overall challenging to determine the exact conditions when Hijackloader chooses which injection\r\nfunction. \r\nGenerally, we found at least six distinct payload loading and injection methods if we do not count miniscule\r\ndifferences of otherwise duplicated functions. These are:  \r\n1.  Two variants of Process Hollowing \r\n2. Two variants of Process Doppelgänging and Mapped Section Injection hybrid \r\n3. Mapped Section injection \r\n4. Run payload via ESWR module \r\n5. Run payload via Process Doppelgänging and ESWR module \r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 11 of 14\n\n6. Run payload via LauncherLdr/LauncherLdr64 module  \r\nWe describe two representative techniques, 1 and 2, below. \r\nFor the Process Hollowing method, HijackLoader copies the PE image saved in CUSTOMINJECT to the path\r\nin CUSTOMINJECTPATH. For this sample the path is %TEMP%\\d0eccdb9\\MicrosoftEdgeUpdate.exe and\r\nthe CUSTOMINJECT executable is indeed a legitimate 32-bit MicrosoftEdgeUpdate.exe.  \r\nThe ti64 module then loads and runs the modCreateProcess64 module to create a\r\nsuspended MicrosoftEdgeUpdate.exe process, it injects the 32-bit rshell module shellcode into the 32-bit\r\nMicrosoftEdgeUpdate.exe and runs it. The injected rshell then uses Heaven’s Gate with a call-add-retf trampoline\r\nto transition to 64-bit code and module stomping for loading the payload. \r\nFor the Process Doppelgänging hybrid the ti64 shellcode dumps the clean PE from the FIXED module table entry\r\nto disk and names it “com_web_filter_v4_0” (this name is part of the configuration outside of the module table).  \r\nIn our sample the FIXED module is a clean zip.exe signed by “VMWare Inc”. The module ti64 then uses\r\nthis clean file as host for Process Doppelgänging by adding a new .dat section to the file and writing\r\nthe rshell module into it via transactional write and rollback operations. \r\nAfterwards it performs Mapped Section injection to load the .dat section into the remote\r\nprocess of MicrosoftEdgeUpdate.exe. That process, again, runs rshell to load the payload via module stomping. \r\nHijackLoader’s interprocess communication\r\nHijackLoader uses two means for interprocess communication. \r\nFirstly, it saves encrypted data, including the module table and injection information, in temporary files. \r\nSecondly, it saves data in environmental variables, including the file names of the aforementioned temporary files.\r\nThe variable names of these environmental variables are encoded. The generator for the variable names receives a\r\nhash which represents what the variable means. At first HijackLoader generates a system specific seed by\r\ncalculating the CRC32 hash of the result of GetComputerNameW. Next, it xors the seed with the hash value. Then\r\nit passes the value into srand(). Subsequent calls to rand() generate an uppercase string of variable length.\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 12 of 14\n\nFigure 10: Generation of environmental variable names for interprocess communication\r\nThe meaning of some of these hashes is listed in the table below and can be used for logging inter process\r\ncommunication. \r\nInitial hash Meaning\r\n0xe1abd1c2 temporary file name, contains injection information\r\n0xf1e5a323 command line string\r\n0xaabbccdd injection flags 1\r\n0xaaeecedb injection flags 2\r\n0xccbbccdd injection size\r\n0xbbaaccdd injection address\r\n0xaebecede injection meta data\r\n0xdabecede image base of inject PE\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 13 of 14\n\nInitial hash Meaning\r\n0xa5b5c41a \"cmd.exe /start\" command line string\r\nLovecraftian malware: an exercise in patience\r\nThis HijackLoader analysis is by no means complete; we focused on the details that matter most for the present\r\nsample.  \r\nIn previous articles about HijackLoader there were several small but notable mentions about the code quality, and\r\nafter working through this code ourselves we understand why.  \r\nThe ti64 module is a big piece of spaghetti software in the form of pure shellcode. In the decompiler, it takes\r\nseveral seconds to scroll through local variable declarations in the entry point function although this code is not\r\nobfuscated apart from hash resolving of APIs, modules and process names. Renaming one variable in\r\nthe decompiler freezes the application for three seconds. The multiple structs we created to make the code\r\nunderstandable have sizes of 0x100 to 0x500 bytes. These structs are re-used in other modules of the code. \r\nCompared to other in-depth analysis work that we have done before, this one is not an experience we would like\r\nto repeat very soon. \r\n Our next article will describe the payload of this HijackLoader sample in detail, which is ACRStealer.\r\nSample hashes\r\n[1] FuII Verslon Setup 6419 σρєи Download.zip (sic!), archive with all files \r\n418a1a6b08456c06f2f4cc9ad49ee7c63e642cce1fa7984ad70fc214602b3b1 \r\n[2] Setup.exe, loads Conduit.Broker.dll  \r\n5d11218f67cfe78347280b0e1a06ade63c890ac78f970f57b0200ff5be8aa77c \r\n[3] Conduit.Broker.dll, sideloaded DLL with malicious patch \r\n772fde719a53147 6740db34df6bdb530f4e96acfd9a92e30ec0476fe65f588f5  \r\n[4] Groumcumgag.ic, encrypted stage 2 shellcode \r\nfed719608185e516c70a1e801b5c568406ef6e1c292e381ba32825c6add93995 \r\n[5] Zootkumbak.uhp, encrypted configuration \r\naf2ade19542dde58b424618b928e715ebf61dffb6d8ca9d4b299e532dfa3b763 \r\n[6] ACRStealer, payload\r\n59202cb766c3034c308728c2e5770a0d074faa110ea981aa88f570eb402540d2\r\nSource: https://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nhttps://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://blog.gdatasoftware.com/2026/02/38373-pivigames-spreads-hijackloader"
	],
	"report_names": [
		"38373-pivigames-spreads-hijackloader"
	],
	"threat_actors": [],
	"ts_created_at": 1778032997,
	"ts_updated_at": 1778033032,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/506701ad25230c9459a8efb530a03f6df640e082.pdf",
		"text": "https://archive.orkl.eu/506701ad25230c9459a8efb530a03f6df640e082.txt",
		"img": "https://archive.orkl.eu/506701ad25230c9459a8efb530a03f6df640e082.jpg"
	}
}