{
	"id": "851693be-a35f-4295-96b8-e54c5366ad21",
	"created_at": "2026-04-06T00:09:13.233432Z",
	"updated_at": "2026-04-10T03:22:07.772653Z",
	"deleted_at": null,
	"sha1_hash": "deb2a51e2bbada6c837b4c946fe12f80fd75e980",
	"title": "Taking a deep dive into SmokeLoader",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 770679,
	"plain_text": "Taking a deep dive into SmokeLoader\r\nBy Aziz Farghly\r\nPublished: 2024-03-01 · Archived: 2026-04-05 13:18:30 UTC\r\nSmoke Loader AnalysisPermalink\r\nSmoke Loader, software introduced in 2011, is primarily utilized for loading subsequent stages of malware onto\r\nsystems, particularly information stealers designed to extract credentials through various means.\r\nIts widespread acclaim can be attributed to its advanced Anti-Analysis and Anti-debugging techniques, along with\r\nits stealthy behavior, which poses challenges for detection. Notably, Smoke Loader employs consistent efforts to\r\nobfuscate its Command and Control (C2) operations by simulating communication requests that resemble\r\nlegitimate traffic patterns to well-known websites, including microsoft.com, bing.com, adobe.com, and others.\r\nOriginally marketed under the name SmokeLdr on dark-web platforms, Smoke Loader has been exclusively\r\navailable to threat actors based in Russia since 2014.\r\nSmoke Loader is typically disseminated through malicious documents, primarily Word or PDF files, often\r\ndistributed via spam emails or targeted spear-phishing campaigns. The malware is activated upon interaction with\r\nsuch malicious documents, initiating its deployment onto the system. Subsequently, Smoke Loader injects\r\nmalicious code into compromised system processes, such as explorer.exe, thereby initiating its malicious\r\noperations while masquerading as a normal process.\r\nFigure 1. File analysis on VMRay platform\r\nTechnical AnalysisPermalink\r\nThe sample we have today is compiled in May/2023 so not that old.\r\nsha1: C6BA6E91D40AA1507775077F9662ECB25C9F0943\r\nSmoke loader in this campaign comes packaged with Wextract which is a Win32 Cabinet Self-Extractor,\r\nunderstanding Cabinet structure is not hard we need to explore file resources and determine which file will be\r\nextracted by this extractor and then extract it statically without the need to run the extractor.\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 1 of 15\n\nFigure 2. Viewing file type on DIE tool\r\nnavigating the resource section, RCData path, and “CABINET” icon, we find a reference to exe files.\r\nthen going to “POSTRUNPROGRAM” I found a mention of 5IH0Dp8.exe\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 2 of 15\n\nExtracting the executables embedded in this file, especially my focus will go on the sample mentioned in\r\n“POSTRUNPROGRAM” element.\r\nStage 2Permalink\r\nthe sample is an x86 Pe file with high entropy that indicates a decryption or packing stream.\r\nsha1:B450EB89D7EA250547333228E6820A52F22BABB2\r\nFigure 3. Getting File Entropy and and compilation time\r\nthe sample also has no imports and strings and got flagged as smoke loader by 60 AV engine through VT API used\r\nin PE-Studio software which ensures our predication that this sample is the 2 Stage of Smoke loader campaign\r\nand the other one maybe acts as a decoy.\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 3 of 15\n\nFigure 4. Sample Flaged by VT, No Imports found\r\nI tried to execute the malware using some monitoring tools but found that the process was terminated Immediately\r\nthere is the basic usage of Windows APIs, which guides us to VM detection or Analysis detection mechanism, so\r\nin the next part, I will discuss how Smoke loaders work and how are modules works.\r\nCode AnalysisPermalink\r\nthe next phase of this article will involve static code analysis to get more info about smoke loader functionality.\r\nOpaque PredicatesPermalink\r\nSmoke Loader welcomed us with anti-analysis techniques called Opaque Predicates, which trick the disassembler\r\nengines into producing a wrong code, also the technique acts as control flow obfuscation that makes the analysis\r\nprocess harder and more confusing due to the high usage of garbage code and the use of jnz/jz instructions which\r\nare pointing for the same address, the figure below will demonstrate more.\r\nFigure 5. Tricking Disassembler using Opaque Predicates\r\nto make it easier we need to patch this code and fix this junk of jumps by replacing jz/jnz with unconditional jump\r\n**** using a simple Python code that uses IDA python to fix it\r\nthis code belongs to n1ght-w0lf, big Thanks to him.\r\nimport idc\r\nea = 0\r\nwhile True:\r\n ea = min(idc.find_binary(ea, idc.SEARCH_NEXT | idc.SEARCH_DOWN, \"74 ? 75 ?\"), # JZ / JNZ\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 4 of 15\n\nidc.find_binary(ea, idc.SEARCH_NEXT | idc.SEARCH_DOWN, \"75 ? 74 ?\")) # JNZ / JZ\r\n if ea == idc.BADADDR:\r\n break\r\n idc.patch_byte(ea, 0xEB) # JMP\r\n idc.patch_byte(ea+2, 0x90) # NOP\r\n idc.patch_byte(ea+3, 0x90) # NOP\r\nthe result was good enough to make the code more readable, the conditional jumps converted into non-conditional\r\njumps, and nopping the bytes of the original jumps\r\nFigure 6. After fixing JMPs using the above script\r\nsmoke loader code is so obfuscated that we need to go step by step in the code to identify where the 3 stages will\r\nbe dropped or downloaded by the Smoke loader, so we still need to fix all of this, by using Python code to fix it\r\nand convert all these junk bytes into a nop byte to be able to create a function in IDA pro.\r\nAnti-DebuggingPermalink\r\nafter trying to fix the code we finally got a regular function, smoke reads the PEB structure to obtain access to the\r\nelement placed at 0xA4 which points to OSMajorVersion which classifies Windows version, if it’s less than 6\r\nwhich means it’s running in an old windows version [XP or W server 2003]\r\nFigure 7. Getting Windows Version through PEB Structure\r\nTransferring Control FlowPermalink\r\nafter that, Smokeloader does not use normal calls or jumps, instead, it uses the [push-ret] or [mov [esp] , value ]\r\nmethod cause when the ret instruction is executed it pops the top of the stack into EIP or instruction pointer\r\nFigure 8. Transferring execution using [push ret]\r\nso the sample here will not provide us with the address to jump to, we need to identify it manually, the address is\r\nbeing saved into ecx, and using mul instruction the value is moved to eax and then adding the value in eax to the\r\nimage base (ebx value ) which in our case is 0x400000 so the next jump will point to 0x403159\r\nFigure 9. Moving 0x3159h to ecx register\r\nFigure 10. Multiplying by ecx will move part of the result to eax\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 5 of 15\n\nFigure 11. Constructing the final address by adding it to the base address in ebx\r\nDecrypt on-demandPermalink\r\nafter some reversing and following the malware jumps which were so confusing and made me stuck, I found that\r\nSmoke is decrypting the function that will be executed and after executing it re-encrypt it again to stay as stealthy\r\nand evasive as it can, the malware saves the offset of the address of the function to be decrypted for further\r\nexecution and then re-encryption on eax register and the length is saved on ecx register and the Xor decryption\r\nkey is saved on edx register before calling the decryption routine which also acts as encryption routine after\r\nexecuting the decrypted function\r\nFigure 12. saving the address of the function to be decrypted on eax\r\nFigure 13. The size of the function is saved on ecx\r\nThe Xor Key which is specified for this function is saved on edx, every function has its own decryption key.\r\nFigure 14. The Xor Key is saved on edx\r\nand here is the part responsible for applying Xoring.\r\nFigure 15. Xoring Blob\r\nthe decryption routine has been called many times and each time it encrypts the address after the call instruction\r\nwhich is the first call or first function to be decrypted and then executed and then re-encrypted is 0x4011CC\r\nFigure 16. First encrypted function\r\nso to fix this we need to simulate the decryption process and patch the bytes, and because there is not a static\r\npattern Smoke uses it to push arguments to the decryption function(offset,size,xor_key) so I found that there is a\r\n20 function call to mw_decrypt_code() which is responsible for decrypting the code, so I go through all of them\r\nmanually using a simple Python code to xor and patch the bytes using IDA python\r\ndef xor_chunk(offset, size,xor_key):\r\n ea = 0x400000 + offset\r\n for i in range(size):\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 6 of 15\n\nbyte = ord(idc.get_bytes(ea+i, 1))\r\n byte ^= xor_key\r\n idc.patch_byte(ea+i, byte)\r\nand here is how the code of 0x4011CC after decryption, looks normal and clean.\r\nFigure 17. After Decrypting the code at address 0x4011CC\r\nand here is how the function 0x4011CC will re-encrypt itself after executing its content\r\nFigure 18. The function re-encrypts itself again after execution\r\nusing the code above I went through all the encrypted functions and decrypted them one by one and commented in\r\nevery call to identify what address was being decrypted or encrypted, as you will see in the figure below.\r\nFigure 19. Decryption and Re-Encryption for every function\r\nAPI HashingPermalink\r\nAfter decrypting and patching All functions and trying to push comments in assembly view to make it easier to\r\ntrack function calls and control flow, the first decrypted function here is 0x4011CC this function decrypts a small\r\npunch of data, using a different XOR key [0x0x880BD3F6]\r\nFigure 20. Sub_4011CC applies decryption stuff\r\nfirst, this decrypted data did not make sense to me cause I found it useless but then after starting again from the\r\nstart function, after fixing some of the obfuscation, I found that the malware tried to get the address of ntdll.dll in\r\nmemory which absolutely will use it to resolve needed APIs via hashing\r\nFigure 21. Getting Ntdll.dll address using PEB\r\ngetting into mw_Build_IAT_0() function reveals some secrets about the hashing algorithm used by Smokeloader.\r\nEncrypted HashesPermalink\r\nthe below code decrypts hashes and patches them in IDA pro\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 7 of 15\n\ndef xor_chunk_API(offset, n, key, is_big_endian=False):\r\n ea = 0x400000 + offset\r\n for i in range(0, (n//4)*4, 4):\r\n \r\n chunk = idc.get_bytes(ea + i, 4)\r\n \r\n if is_big_endian:\r\n chunk = chunk[::-1]\r\n \r\n value = int.from_bytes(chunk, byteorder='little')\r\n \r\n xor_result = value ^ key\r\n \r\n xor_bytes = xor_result.to_bytes(4, byteorder='little')\r\n \r\n idc.patch_bytes(ea + i, xor_bytes)\r\nhere is the hashing routine which is called djb2\r\nFigure 22. API hashing routine\r\ndef hash_djb2(API_Name):\r\nhash = 0x1505\r\nfor x in API_Name:\r\nhash = (( hash \u003c\u003c 5) + hash) + x\r\nreturn hash \u0026 0xFFFFFFFF\r\nusing HashDb to resolve these APIs\r\nFigure 23. Replacing Hashs with names using HashDB\r\nso after resolving All APIs, which is more than 40 APIs Now we need to go through the malware to identify its\r\nbehavior.\r\nSkip infectionPermalink\r\nafter API building it will check the location of the current machine via keyboard language, which will be used to\r\navoid infecting some countries (Russia, Ukraine), It will get the keyboard language list and then compare it to\r\nconstants that refer to the language of Russia and Ukraine\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 8 of 15\n\nFigure 24. Skip infecting Russia and Ukraine\r\nCheck PrivilegePermalink\r\nafter that, it will get the process token via OpenProcessToken API and then try to query [TokenIntegrityLevel]\r\nand check if it is less than 0x2000 which means that the malware with a Low integrity level\r\nFigure 25. Getting Process Privalage\r\nand if its integrity is under 0x2000 it will execute a command using ShellExecuteExW to run malware again under\r\nthe Windows Management Instrumentation Command-line (WMIC)\r\nFigure 26. Executing Malware under WMIC\r\nAnti-DebuggingPermalink\r\nthen Smoke will use native APIs to check if it’s being debugged but this time it will not do it through PEB or\r\nusing APIs like check Isdebuggerpresent(), instead it will execute a call to NtQueryInformationProcess() using\r\nProcessDebugPort =7 as an information class that Retrieves a DWORD_PTR value that is the port number of\r\nthe debugger for the process. A nonzero value indicates that the process is being run under the control of a ring 3\r\ndebugger.\r\nFigure 27. Checking Debugger existence using native API\r\nif it finds that the malware is being debugged it will terminate the process.\r\nnote* as I said before the malware decrypts the code and then re-encrypts it again, but sometimes it\r\nembeds some strings inside the decrypted code which prevents IDA from identifying this code as a\r\nseparate function, imagine that instructions then strings then instructions in the same blob, to\r\nsummarize that the strings exist in the text section inside the encrypted code and Smoke got access to it\r\nby calling the next instruction below the strings which places the address of the string in the top of the\r\nstack.\r\nCheck AVs \u0026 VirtualizationPermalink\r\nSmoke will go through all loaded modules in the victim machine and and for every module it will compare its\r\nname against some of the modules used by famous Anti-virus solutions\r\nsbiedll → Sandboxie Environment\r\naswhook → Avast Anti-virus\r\nsnxhk → Avast Anti-virus\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 9 of 15\n\nFigure 28. Comparing Modules Names to check AVs Existence\r\nthen it will enumerate all subkeys under these two keys which are related to disk drivers in a virtual environment\r\nComputer\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\SCSI\r\nComputer\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\IDE\r\nit will search for some strings inside its subkeys.\r\nvalues to look for → [qemu , virtio, vmware , vbox , xen ]\r\nThese strings are related to the emulation of drivers in sandboxes and virtualization environment\r\nFigure 30. embedded Disk Driver names related to VM emulation\r\nFigure 31. keys to search within\r\nusing NtQuerySystemInformation() API and placing SystemProcessInformation as a class information type it\r\nwill Return an array of SYSTEM_PROCESS_INFORMATION structures, one for each process running in the\r\nsystem.\r\nFigure 32. Retrieving process name using NtQuerySystemInformation\r\nthen it will compare process names against some of the background processes used by Qemu, Vmware, and\r\nVirtualbox environments\r\nqemu-ga.exe → Qemu\r\nqga.exe → Qemu\r\nwindanr.exe\r\nvboxservice.exe →Vbox\r\nvboxtray.exe →Vbox\r\nvmtoolsd.exe →Vmware\r\nprl_tools.exe →System Explorer\r\nthen it will give a call to the same API but with SystemModuleInformation as an information class which\r\nreturns RTL_PROCESS_MODULES structure that stores information about loaded drivers, so it compares\r\ndriver name against some embedded drivers names that exist in virtual environments\r\nFigure 31. embedded drivers names\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 10 of 15\n\nvmci.s vmmemc vboxvi\r\nvmusbm vboxgu vboxdi\r\nvmmous vboxsf viose\r\nvm3dmp vboxmo vmrawd\r\nStage 3 DecryptionPermalink\r\nAfter passing all checks, Smoke will start loading the third stage.\r\nit first will check the Architecture of the victim machine to determine the appropriate payload, there are 2\r\npayloads one for x86 and the other for x64, so it checks the value of GS or Segment Register which will be 0 if\r\nthe process is running in x86 pc but in x64 system it will contain a positive value.\r\nFigure 34. Checking windows Architecture\r\nthen it will decrypt the payload at the chosen address using the same decryption routine used for hashes\r\ndecryption but with simple additions this time because it is using the Dword value as Xor key, he needs to\r\ndecrypt the payload dword by dword, but what if the payload size is not a multiple of 4 (Dword size = 4 bytes) so\r\nit will result in a wrong decrypted value at the last (3 or 2 or 1) bytes, to fix this it will get the reminder value after\r\ndecrypting with a dword value as xor key and then decrypt the reminder bytes with 1 byte as a xor key\r\nFigure 35. Decrypting the payload with attention to its size\r\nwe do it statically by writing a script to decrypt this payload u can check it here\r\ndef xor_chunk_s3( data, dword_key, b_key):\r\n decrypted=b''\r\n \r\n for i in range(0,(len(data)//4)*4,4):\r\n \r\n _4_bytes= struct.unpack(\"\u003cI\",data[i:i+4])[0]\r\n \r\n xor_result = _4_bytes ^ dword_key\r\n \r\n decrypted+=struct.pack(\"\u003cI\",xor_result)\r\n \r\n last_bytes_len = len(data)%4\r\n \r\n if last_bytes_len \u003e 0:\r\n \r\n last_decrypted=[]\r\n \r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 11 of 15\n\nfor byte in data[-last_bytes_len:]:\r\n \r\n last_decrypted.append(byte ^ b_key)\r\n \r\n print(last_decrypted)\r\n \r\n decrypted+=bytes(last_decrypted)\r\n return decrypted\r\nStage 3 DecompressionPermalink\r\nafter decrypting the payload it will use the first 4 bytes as size that is used on NtAllocateVirtualMemory() API\r\nwith read_write permission, then the pointer to the allocated memory and the decrypted payload are pushed to\r\nanother anonymous function which after some research for this function using some const assembly instruction to\r\nidentify it because it was not a decryption routine or whatever and also something that proves that this function is\r\nresponsible for decompression is that the allocated size is larger than the decrypted data size which paves the way\r\nfor a decompression operation that will happen in the allocated region\r\nFigure 36. Code Chunk for Decompression routine\r\nthese assembly instructions give me a hint about the used algorithm which is LZSA2, an old compression\r\nalgorithm used for old CPUs according to this Blog\r\nFigure 37. The function responsible for LZSA2 decompression\r\nso from another GitHub repo, we found a C implementation for this algorithm, cloned it, and then built the\r\nproject\r\nFigure 38. LZSA repo, Big Thanks to him\r\nand here is the used command to decompress the decrypted payload\r\nlzsa_debug.exe -d -r -f 2 decrypted_payload.bin decrypted_decompress.bin\r\nStage 3 Injection:Permalink\r\nthen after decompression, Smokeloader will start injecting this destroyed stage cause we got a PE file without\r\nheaders, so to do it in Regular steps\r\n1- It gets a handle for Explorer.exe by executing a call to GetShellWindow()Retrieves a handle to Shell’s desktop\r\nwindow, in our case it’s Explorer.exe, and then it gets a handle to this process using\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 12 of 15\n\nGetWindowThreadProcessId()\r\nwindow_handle =GetShellWindow)();\r\n if ( window_handle )\r\n break;\r\n (a2-\u003eptr_Sleep)(0x3E8u);\r\n \r\ndwProcessId[1] = window_handle;\r\n v6 = dwProcessId;\r\n dwProcessId[0] = 0;\r\n (GetWindowThreadProcessId)(window_handle, dwProcessId);\r\n2- it then gets a token handle to explorer.exe using NtOpenProcess() and duplicates this handle to use it later\r\n3-It then creates a section with PAGE_READWRITE permission and then maps this section to the current\r\nmalware process and Explorer.exe process using NtCreateSection() and NtMapViewOfSection() APIs\r\nFigure 39. Creating and Mapping sections\r\n4- Create another section but this time with a different permission PAGE_EXECUTE_READWRITE, and map\r\nthis section to the current process and explorer.exe.\r\nFigure 40. Mapping sections to explorer.exe\r\n5- it then hashes the encrypted payload not the decompressed only to check integrity but it is worth mentioning.\r\nencrypted_payload = \u0026byte_40563A;\r\n payload_size = 0x2E46;\r\n hash_value = 0x2260;\r\n do\r\n {\r\n v11 = *encrypted_payload++;\r\n hash_value = v11 + 33 * hash_value;\r\n --payload_size;\r\n }\r\n while ( payload_size );\r\n6- it next copies the decompressed payload into the mapped section and then builds IAT for this payload, then it\r\ncreates a new thread into Explorer.exe using RtlCreateUserThread() and pushes the address of payload in\r\nexplorer.exe memory as a StartAddress argument for this API call.\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 13 of 15\n\nFigure 41. Creating a threat into explorer.exe with payload address as its entry point\r\nStage 3 configuration:Permalink\r\nAfter extracting the third stage file which is a destroyed PE file without headers, this time I have 2 options\r\n1. fixing the file, I found a good walkthrough to do in this blog, or\r\n2. analyzing the binary inside explorer process which was very annoying cause explorer.exe handles many\r\nthings and debugging it may force something to crash\r\nso I decompressed the file as I said before and found that, malware configuration is saved in a string table,\r\nencrypted using RC4\r\nand smoke is saving it like a key and then the length of the next string and then the length of the next string, etc…\r\nuntil the end of the encrypted data,\r\nso I have written a simple script that can handle this and give us the decrypted config\r\ndump= binascii.unhexlify(dump)\r\nindex = 0\r\nkey =0x246FC425\r\nwhile index \u003c len(dump):\r\n enc_length = str_data[index]\r\n x = rc4crypt(dump[index+1:index+1+enc_length], struct.pack('\u003cI',key))\r\n print(x.replace(b'\\x00',b''))\r\n index = index+1+enc_length\r\nand here is a list of the encrypted strings in my GitHub\r\nC\u0026CPermalink\r\nMalware Command and control hosts are also RC4 encrypted so it decrypts in a similar way as the configuration,\r\nstruct Command_n_control\r\n{\r\n Byte Data_length;\r\n DWORD XOR_Key;\r\n char Data[Data_length];\r\n};\r\nand here is the decrypted C2\r\nFigure 42. decrypted C2 address\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 14 of 15\n\nthe C2 is down so we don’t know the next stage.\r\nIOCs:Permalink\r\nFile:\r\nWextract file: C6BA6E91D40AA1507775077F9662ECB25C9F0943\r\ndropped sample :B450EB89D7EA250547333228E6820A52F22BABB2\r\n \r\nOther Hashes :\r\n4cd9af3b630e3e06728b335c2a3a5c48297a4f36fb52b765209e12421a620fc8\r\ndaa69519885c0f9f4947c4e6f82a0375656630e0abf55a345a536361f986252e\r\n8ecd99368b83efde6f0d0d538e135394c5aec47faf430e86c5d9449eb0c9f770\r\nab2c8fb5e140567a6e8e55c89138d5faa0ef5e6f2731be3c30561a8ce9e43d29\r\n60c65307f80b12d2a8d8820756e900214ad19a1fcfcda18cdbee3a25974235ac\r\n \r\nCnC:\r\nhxxp://185.215.113.68/fks/index.php\r\nhxxp://rixoxeu9.top/game.exe\r\nhxxp://planilhasvbap.com.br/wp-admin/js/k/index.php\r\nhxxp://telegatt.top/agrybirdsgamerept\r\nhxxp://95.217.43.206/\r\nyou can find the full repo that contains all scripts here\r\nReferencesPermalink\r\nDeep Analysis of SmokeLoader\r\n_SmokeLoader is a well known bot that is been around since 2011. It’s mainly used to drop other malware\r\nfamilies…_n1ght-w0lf.github.io\r\nWindows Process Injection: PROPagate\r\n_Introduction In October 2017, Adam at Hexacorn published details of a process injection technique called\r\nPROPagate. In…_modexp.wordpress.com\r\nSmokeLoader Triage\r\n_Taking a look how Smoke Loader works_research.openanalysis.net\r\nSmokeLoader | dcd883af6eb9\r\n_This feature requires an online-connection to the VMRay backend. An offline version with limited functionality\r\nis also…_www.vmray.com\r\nSource: https://farghlymal.github.io/SmokeLoader-Analysis/\r\nhttps://farghlymal.github.io/SmokeLoader-Analysis/\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://farghlymal.github.io/SmokeLoader-Analysis/"
	],
	"report_names": [
		"SmokeLoader-Analysis"
	],
	"threat_actors": [],
	"ts_created_at": 1775434153,
	"ts_updated_at": 1775791327,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/deb2a51e2bbada6c837b4c946fe12f80fd75e980.pdf",
		"text": "https://archive.orkl.eu/deb2a51e2bbada6c837b4c946fe12f80fd75e980.txt",
		"img": "https://archive.orkl.eu/deb2a51e2bbada6c837b4c946fe12f80fd75e980.jpg"
	}
}