{
	"id": "ee17a1f7-ce8f-4b4d-bec3-07b8dd70ca6e",
	"created_at": "2026-04-06T00:14:53.537427Z",
	"updated_at": "2026-04-10T03:20:55.451769Z",
	"deleted_at": null,
	"sha1_hash": "0b3d2b10050ee14e5d29ed76122e4342c98efd50",
	"title": "Deobfuscating the Latest GuLoader: Automating Analysis with Ghidra Scripting",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 88767,
	"plain_text": "Deobfuscating the Latest GuLoader: Automating Analysis with\r\nGhidra Scripting\r\nBy Electron\r\nPublished: 2023-05-23 · Archived: 2026-04-05 23:15:04 UTC\r\nIn this article by ANY.RUN analysts, we’ll discuss the GuLoader malware and how to deobfuscate its code using\r\nthe Ghidra scripting engine.\r\nWe will:\r\nIdentify obfuscated code patterns\r\nDevelop an algorithm to deobfuscate and optimize these code patterns\r\nWrite a script to semi-automate the code deobfuscation process. \r\nWe also detailed the obfuscation techniques for junior analysts. And mid-level and senior analysts will find\r\nstrategies and tools for simplifying and deobfuscating GuLoader and other malware.\r\nWithout further ado, let’s get into the analysis.\r\nBrief Overview of GuLoader \r\nGuLoader is a widely used malware loader known for its complex obfuscation techniques that make it difficult to\r\nanalyze and detect. \r\nHere’s some general information about this threat:\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 1 of 15\n\nWe are going to examine a GuLoader sample with the first submission time 2023-03-28 and SHA256 hash: \r\n653519cb7879ba9389474ab6fb92ae69475ea3166167e3b9b1e4405e14506f5d \r\nYou can download the original sample from this link. \r\nFig. 1 – basic file information of the investigated Guloader sample \r\nClearing the way: Why Deobfuscating Code is Crucial Before Analysis? \r\nDeobfuscating code is an essential step in the process of malware analysis. When malware authors create their\r\nprograms, they often use various obfuscation techniques to make it more difficult to understand and analyze their\r\ncode.\r\nBy deobfuscating the code, analysts can gain a better understanding of the malware’s functionality, identify its\r\ncapabilities, and develop effective mitigation strategies. \r\nConsider this picture where Guloader’s sophisticated assembly code is decompiled into ugly pseudo-code: \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 2 of 15\n\nFig.2 — Guloader’s sophisticated assembly code along with the decompilation result \r\nObfuscation used in the code makes it almost impossible to understand what’s going on. That’s why today we will\r\nfocus on deobfuscation — it will help us gain a better understanding of Guloader’s behavior.\r\nBy the way, if you want to see more examples of analyzing obfuscated code, check out our deep dive into\r\nCryptBot.\r\nUnpacking Guloader’s Shellcode \r\n Unpacking GuLoader’s shellcode is rather straightforward.\r\nStart by reaching the entry point of the malware. Once identified, set a breakpoint at the VirtualAllocEx function.\r\nThis function is used to allocate memory for the GuLoader’s shellcode. The first break point should occur when\r\nthe function finishes executing and the memory has been allocated. \r\nFig. 3 — allocated memory for the shellcode \r\nNote that the return address in the stack the ‘System.dll’ module — not the executable itself. This means that the\r\nmalware brings this module with itself.\r\nAt this point, set a hardware execution breakpoint at the first byte of the memory address returned in the EAX\r\nregister. This will create a break at the first instruction of the shellcode.\r\nAfter setting this breakpoint, run the malware. When the breakpoint is hit, you will be at the first instruction of the\r\nshellcode. \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 3 of 15\n\nFig. 4 — shellcode’s entry point\r\nTo further analyze the shellcode, navigate to the memory map and create a dump of the memory region allocated\r\nby “VirtualAllocEx”. This dump can be loaded into a disassembler, allowing you to analyze the shellcode in more\r\ndetail. \r\nIt is worth noting that, we used Windows 7 (x32) as our unpacking environment. Keep in mind that the algorithm\r\nwill be slightly different for the other OS versions. If you don’t have time or a suitable environment to unpack\r\nGuLoader shellcode by yourself, you can download an archive with an already unpacked sample from our GitHub\r\nrepository (password: infected). \r\nIdentifying Obfuscated and Junk Code Patterns \r\nIn this section, we will search for junk and obfuscated code in GuLoader’s shellcode to use them as templates for\r\ndeobfuscating and optimization techniques. \r\nXMM instructions \r\nThere are many XMM instructions present in the code. They look chaotic and complicate the analysis process. We\r\nencountered them from the first byte of the unpacked shellcode: \r\nFig. 5 — XMM instructions at the start of the shellcode \r\nthese instructions are quite effective at obfuscating the code, as they can break many emulation engines. That’s\r\nBecause most of them are not supported by default. We have tested Angr, Triton as well as Ghidra embedded\r\nengines – all of them failed.\r\nUnconditional JMP instructions \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 4 of 15\n\nGuloader authors used lots of JMP instructions to divide the code into small blocks and connect them together.\r\nNot only does this technique make the code more difficult to analyze, but it also prevents detection by antivirus\r\nsoftware and other security tools. What’s more, jumping between these blocks can be quite tedious and annoying\r\nfor analysts, especially when dealing with a large amount of code. \r\nFig. 6 — an example of small blocks on the graph connected by JMP instructions \r\nJunk instructions \r\nThe GuLoader code contains junk assembly instructions, which are often incorporated as an extra layer of\r\nobfuscation to complicate its analysis. These instructions have no practical function, generally leaving the value of\r\nregisters, execution flow, or memory unchanged. Their purpose is to hinder analysis and obscure the genuine\r\nfunctionality of the code.\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 5 of 15\n\nFig.7 — an example of a junk instruction ‘OR’ \r\nWe may highlight instructions that perform no operation (“NOP”, “FNOP”), and instructions that shift or rotate a\r\nvalue by zero bits (“SHL reg, 0”; “ROL reg, 0”). Also, the code may contain instructions like “OR reg, 0”, “XOR\r\nreg, 0”, “CLD”, “WAIT” and others, which are equally useless, making no impact on the code’s behavior.\r\nFake comparison instructions \r\nGuLoader code frequently utilizes fake comparison instructions for obfuscation. These instructions usually\r\ninvolve comparing a register or memory location with a fixed value, like “CMP EAX, 0” or “TEST EDX, EDX”.\r\nYet, the outcome of these comparisons isn’t applied in following instructions, rendering the comparison pointless.\r\nFig. 8 — an example of a fake comparison instruction ‘TEST EDX, EDX’ \r\nFake PUSHAD instructions \r\nThe use of fake “PUSHAD” instructions, when paired with a corresponding “POPAD” instruction, is another\r\ncommon obfuscation technique used in the GuLoader code.\r\nThese instructions can be used to temporarily modify the values of registers between the “PUSHAD“ and\r\n“POPAD” instructions. However, the final “POPAD” instruction restores all registers to their original values,\r\neffectively nullifying any modifications made by the code.\r\nFig. 9 — an example of a useless ‘pushad’ instruction combined with a ‘popad’\r\nFake PUSH instructions\r\nThe use of fake “PUSH” instructions is yet another obfuscation method that is rather similar to the previous one.\r\nThese pairs of instructions involve pushing a value onto the stack and then immediately popping it off again.\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 6 of 15\n\nFor example, the code may include a “PUSH SS” instruction, followed by one or more instructions that modify\r\nthe value of a particular register or memory location. However, when the corresponding “POP SS” instruction is\r\nexecuted, the content of the stack pointer is restored to its original value.\r\nFig. 10 — an example of a fake ‘PUSH’ instruction \r\nOpaque predicates \r\nGuLoader code also incorporates opaque predicates to increase the difficulty in comprehending the code’s logic.\r\nThese predicates are essentially conditional statements that consistently evaluate to either true or false. However,\r\nthey are designed to be challenging to analyze or predict.\r\nFor example, the code may include a pair of instructions such as “MOV BL, 0xB6” and “CMP BL, 0xB6”,\r\nfollowed by a conditional jump instruction such as “JNZ ADDR”. However, since the value being compared is the\r\nsame as the value that was just moved into the register, the comparison will always evaluate to false, making the\r\nconditional jump unnecessary and confusing.\r\nFig. 11 — opaque predicate that is always evaluates to false \r\nArithmetic Expressions \r\nObfuscated arithmetic expressions are one of the most interesting obfuscation methods used in GuLoader to make\r\nthe actual arithmetic operations harder to understand. These expressions involve arithmetic instructions like\r\naddition, subtraction, and exclusive or, which are mixed with other obfuscation techniques such as fake\r\ncomparisons, opaque predicates, and junk instructions.\r\nOne example of arithmetic obfuscation in GuLoader code is to move a constant value into a register and perform\r\narithmetic operations on it: \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 7 of 15\n\nFig. 12 — an example of arithmetic obfuscation distributed between two small blocks\r\nAnother example is to push a constant value onto the stack and perform mathematical operations on the memory\r\nlocated on the stack: \r\nFig. 13 — an example of math operations on the top of the stack \r\nDeobfuscating and Optimizing: Techniques and Strategies\r\nIn the previous sections, we’ve identified and discussed various obfuscation techniques often found in GuLoader,\r\nincluding:\r\nOpaque predicates\r\nObfuscated arithmetic expressions\r\nAnd junk instructions.\r\nNow, let’s focus on developing techniques and strategies to overcome these obfuscation methods and make the\r\ncode easier to analyze. \r\nWhat’s more, we will show the state of the code before and after deobfuscation. You’ll see how using various\r\ndeobfuscation techniques can render the code more readable and simplified for analysis.\r\n“Nopping” all XMM instructions \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 8 of 15\n\nAs previously noted, XMM instructions can complicate the analysis process due to their obfuscating impact on the\r\ncode. Fortunately, our analysis shows that all of the XMM instructions used in GuLoader are extraneous and don’t\r\ninfluence the code’s intended behavior. These instructions are essentially pointless, as the outcome of their\r\nexecution is never utilized.\r\nThe result of “Nopping” all XMM instructions can be seen in the following table:\r\nFig. 14 — the expected result of “nopping” all XMM instructions \r\nAnd here’s the achieved result of “Nopping” all XMM instructions in Ghidra:\r\nFig. 15 — “nopped” XMM instructions in Ghidra \r\nLeaving Unconditional JMP Instructions Untouched \r\nWhen analyzing GuLoader, it can be tempting to remove unconditional JMP instructions to streamline the code\r\nand make it easier to read. But, it requires a lot of time and effort.\r\nAdditionally, the disassembler in decompiled code can often do a good job of concatenating blocks and making\r\nthe code more legible, even with the presence of these unconditional jumps. Thus we decided to leave small\r\nblocks and not concatenate them.\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 9 of 15\n\nFig. 16 — two deobfuscated blocks on the graph without concatenation\r\n“Nopping” Junk Instructions \r\nJunk instructions are those that do not affect the execution flow of the code and can be safely removed. One of the\r\nexpected results of “nopping” all junk instructions is represented it the following table: \r\nFig. 17 — an expected result of “nopping” junk instructions\r\nDefeating fake comparison instructions \r\nDealing with fake comparison instructions can be a bit more difficult than simply “nopping” junk instructions.\r\nUnlike junk instructions, we can’t just remove any comparison instruction we come across, because it may\r\nactually be needed for the code to function correctly. To handle this, we need to carefully identify which\r\ncomparisons are fake and can be removed. \r\nOne way to do this is to “mark” any comparison instruction we encounter, and then look for any subsequent\r\ninstructions that may use the result of the comparison. If no such instructions are found, we can safely replace the\r\ncomparison instruction with a NOP. If we encounter a conditional jump or another instruction that may use the\r\ncomparison result, we need to “unmark” the previous comparison so that it is not removed. \r\nAn example of properly “nopping” out junk comparison instructions is illustrated in the following table. As\r\nshown, all comparison instructions except for “CMP EDX,0x0” have been removed: \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 10 of 15\n\nFig. 18 — an example of “nopping” fake-comparison instructions\r\nDefeating fake PUSHAD instructions\r\nOur investigation revealed that all “PUSHAD” instructions used in the GuLoader code are useless. So, we simply\r\nnop the “PUSHAD” and “POPAD” instructions, and everything in between them: \r\nFig. 19 — an example of nopping everything between “PUSHAD” and “POPAD”\r\nNote that not all “POPAD” instructions found in the GuLoader code are junk. Some of them may not have a\r\ncorresponding “PUSHAD” instruction. In such cases, we leave the “POPAD” instruction untouched. \r\nDefeating fake PUSH instructions\r\nCleaning up fake PUSH instructions is akin to handling fake PUSHAD instructions, but we need to make sure that\r\nthe registers that are not pushed remain unaffected.\r\nFig. 20 —an example of nopping “PUSH” and “POP” instructions\r\nOpaque predicates\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 11 of 15\n\nOvercoming opaque predicates might appear challenging initially, as it requires “predicting” the jump condition.\r\nHowever, in our case, it’s relatively straightforward because all discovered opaque predicates are situated within\r\nthe “PUSHAD” and “POPAD” blocks. When processing “PUSHAD” blocks, we simply nullify all opaque\r\npredicates between the “PUSHAD” and the corresponding “POPAD” instruction.\r\nCalculating Arithmetic Expressions\r\nTo deobfuscate the arithmetic expressions in Guloader, we follow a similar approach to the fake comparison\r\ninstructions. We mark all “MOV” instructions where the second argument is a scalar value and all “PUSH”\r\ninstructions where the argument is a scalar too. When we encounter an arithmetic operation, we update the\r\nconstant value in the first instruction and nop the current instruction. In this way, the first met instruction will\r\nalways have the result value, and the rest of the arithmetic instructions will be “nopped”. \r\nSee the following example with the optimized “MOV” operation: \r\nFig. 21 — optimizing “MOV” arithmetic operations\r\nHere is another example where we optimize “PUSH” instructions:\r\nFig. 22 — optimizing “PUSH” math operations\r\nIt’s important to be careful when dealing with the size of the operands – we need to ensure that we preserve the\r\ncorrect size when performing the arithmetic operations.\r\nAutomating Malware Analysis with a Ghidra Script \r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 12 of 15\n\nIn the earlier sections, we identified typical obfuscation techniques in GuLoader’s code and discussed various\r\nstrategies to overcome them. In this section, we provide a brief description of a script designed to semi-automate\r\nthe deobfuscation process for GuLoader’s code.\r\nWe’ve developed a script that initiates from the chosen instruction, tracks calls and conditional jumps, simplifies,\r\ndeobfuscates, and disassembles the resulting code. The script avoids jumping over calls with a specific operand\r\nvalue because not all calls result in returns. This script employs all the approaches we’ve discussed in previous\r\nchapters.\r\nFig. 23 — part of the script to deobfuscate GuLoader’s code\r\nYou can download this script from our GitHub repository and put it in Ghidra’s script folder. We recommend\r\nsetting a hotkey for quick access. Simply place the cursor over an interesting position (you could start from the\r\n0x0 offset) and press the hotkey to see the deobfuscated code.\r\nFinally, let’s take a look at the pseudo-code of Guloader before and after using the deobfuscation script and\r\ncompare them:\r\nFig. 24 — the 1st\r\n example of the code before deobfuscating\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 13 of 15\n\nAnd here is the same code after deobfuscation:\r\nFig. 25 — the same 1st\r\n example of the code, but after applying script\r\nHere is another example of GuLoader’s code before and after applying our deobfuscation script. Here’s the before:\r\nAnd here it is after running the script:\r\nFig. 26 — the same 2nd\r\n example, but after applying the script\r\nAs you can see, the code is now significantly more readable. The obfuscated instructions have been eliminated,\r\nmaking the code flow easy to trace.\r\nThis greatly simplifies the task for malware analysts trying to understand the malware’s behavior, making the\r\nwhole analysis process considerably more efficient.\r\nLimitations of the approach \r\nWhile the semi-automated deobfuscation method with Ghidra scripting is effective, there are several limitations to\r\nbear in mind.\r\n1. It’s possible that not all obfuscated code patterns in GuLoader have been identified, and new techniques\r\nmay emerge in future versions of the malware.\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 14 of 15\n\n2. There is a chance of optimization errors, where some instructions might be wrongly identified as junk or\r\nobfuscated code, and are nulled or removed.\r\n3. The script may need adjustments or updates to handle different versions of GuLoader, as there might be\r\nchanges in the obfuscation techniques used.\r\n4. The script might not be able to identify all calls and jump destinations, particularly if they’re dynamically\r\ngenerated or encoded.\r\n5. Writing and testing the script can demand a significant amount of time and effort, as it necessitates a\r\nthorough understanding of GuLoader’s code structure and obfuscation techniques.\r\nDespite these limitations, this approach remains a helpful tool for automating GuLoader code analysis and\r\ndeobfuscation.\r\nWrapping up\r\nWe’ve explored one potential approach to deobfuscating GuLoader, which entails identifying common\r\nobfuscation patterns and neutralizing them using various techniques.\r\nIt’s important to note that while this approach was specifically tailored for deobfuscating GuLoader, the same\r\ngeneral techniques could be applied to other malware samples as well. However, bear in mind that each malware\r\nsample might have unique obfuscation techniques, necessitating the development of specific optimization\r\nstrategies.\r\nWant to read more content like this?\r\nLearn how we analyzed the encryption and decription algorithms of PrivateLoader\r\nOr learn how to extract LimeRat configuration\r\n[10:48] Ivan Skladchikov Electron is a malware analyst at ANY.RUN \r\nElectron\r\nI'm a malware analyst. I love CTF, reversing, and pwn. Off-screen, I enjoy the simplicity of biking, walking, and\r\nhiking.\r\nelectron\r\nElectron\r\nLeading malware analyst\r\nI'm a malware analyst. I love CTF, reversing, and pwn. Off-screen, I enjoy the simplicity of biking, walking, and\r\nhiking.\r\nSource: https://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nhttps://any.run/cybersecurity-blog/deobfuscating-guloader/\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://any.run/cybersecurity-blog/deobfuscating-guloader/"
	],
	"report_names": [
		"deobfuscating-guloader"
	],
	"threat_actors": [],
	"ts_created_at": 1775434493,
	"ts_updated_at": 1775791255,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/0b3d2b10050ee14e5d29ed76122e4342c98efd50.pdf",
		"text": "https://archive.orkl.eu/0b3d2b10050ee14e5d29ed76122e4342c98efd50.txt",
		"img": "https://archive.orkl.eu/0b3d2b10050ee14e5d29ed76122e4342c98efd50.jpg"
	}
}