{
	"id": "d17e6649-7d7b-4670-aa2d-cf296372e7b4",
	"created_at": "2026-04-10T03:20:01.525427Z",
	"updated_at": "2026-04-10T03:22:17.786681Z",
	"deleted_at": null,
	"sha1_hash": "4cf2aab6efdec8d6b16cb087411f4b38b49dfd25",
	"title": "Android malware analysis with Radare: Dissecting the Triada Trojan",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1052341,
	"plain_text": "Android malware analysis with Radare: Dissecting the Triada\r\nTrojan\r\nPublished: 2017-11-21 · Archived: 2026-04-10 03:04:45 UTC\r\nI periodically assess suspicious mobile apps in order to identify malicious behavior, get ideas for new product\r\nfunctionality, or implement preflight checks to make sure apps submitted to our automated mobile app security\r\ntesting solution can be properly assessed. As part of my work as a mobile security analyst at NowSecure, I\r\nrecently performed Android malware analysis with Radare on a sample of the Triada Trojan.\r\nRadare2 is known to disassemble Linux, Windows, and OSX binaries, but what about Android? Well, it can load\r\nDalvik DEX (odex, multidex), ELF (.so, ART, executables, etc.), Java CLASS files and more!\r\nI wrote this blog post to provide an introduction on how to use Radare for Android malware analysis. After\r\nreading this post, you’ll understand how to use Radare2 to disassemble Android binaries, how to identify\r\nsuspicious or malicious app behavior, and some of the benefits and limitations of using Radare2 for this use case.\r\nIdentifying a suspicious Android app\r\nFinding a sample of Android malware isn’t difficult, but I wanted to dissect something interesting. I\r\nsearched Koodous, a platform for Android malware research,  for “free download” and found an app named “Free\r\nYoutube Video Download.” The app struck me as suspicious because screenshots were taken from another app,\r\nand the official icon was altered. So I clicked the download button and began my analysis.\r\nIntent: Deciding whether a suspicious Android app is malware\r\nA good first step in evaluating a suspicious file is understanding what other people already know about the file by\r\nscanning it with an anti-virus solution such as VirusTotal. I uploaded the sample, and VirusTotal reported a\r\ndetection ratio of 34/55 and identified it as the Triada Android Trojan. So the app was infected.\r\nKeep in mind that anti-virus technology can sometimes fail or return false-positive results because malware\r\nevolves faster than anti-virus vendors can develop good heuristics or signatures to filter them out.\r\nTo gather more information beyond that provided by anti-virus engines, I examined a YARA rule that detects the\r\nsample and uses the Androguard YARA module written by some peeps from the Koodous team.\r\nThe sample was discovered in March 2016, and there’s still no publicly available technical analysis. At the\r\ntime, Kaspersky Lab called Triada the most advanced Android malware to date and compared it to Windows\r\nmalware in terms of complexity. To read more detailed information about the infection techniques used by this\r\nparticular malware sample, see the blog post “Attack on Zygote: a new twist in the evolution of mobile threats.”\r\nAs I prepared to dig deeper, I collected more samples that matched the same YARA rule by pasting the rule in the\r\nKoodous search box, which resulted in three more .apks. While I had gathered multiple samples that matched the\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 1 of 13\n\nYARA rule, I couldn’t be sure whether or not they were variants of the same family.\r\nExploring the functionality of Android malware\r\nWhen analyzing a suspicious Android app, you’ll evaluate the following factors:\r\nObfuscation techniques – Obfuscation may be used to legitimately protect intellectual property or to hide\r\nmalicious code.\r\nExcessive permissions – If the app requests excessive permissions, it may simply be a mistake made by\r\nthe developer or deliberate and for nefarious purposes.\r\nStrange files on the device – Trash files, binary resources or encrypted payloads.\r\nEmulator checks – Requiring a patch for the app or using an actual device for analysis.\r\nARM-only libraries – Making it so the app can’t be executed on an x86 emulator, for example.\r\nStrings pointing to system binaries – This may be a legitimate root detection mechanism or part of an\r\nescalation of privileges exploit.\r\nHardcoded IPs in the binaries – These may be IP addresses for testing servers forgotten by developers or\r\nfor command-and-control servers (botnets).\r\nLinks to APKs – Developers may have forgotten to remove these links used for testing purposes or\r\nthe links may point to second-stage payloads.\r\nAccess to the SMS/messaging functionality – This may be legitimate and used for two-factor\r\nauthentication or for malicious purposes such as unauthorized subscription payment services scams or\r\nstealing authentication codes for bank payments, etc.\r\nModified legitimate apps – Bad actors regularly modify legitimate apps to include/hide a malware\r\npayload within them.\r\nApp source or reliability of hosting/connectivity channel – If the source of an .apk is an alternative\r\nAndroid marketplace or unknown, you can’t be sure what review process the app went through.\r\nIf the app comes from a suspicious source, you should trust it less than an app that comes from an official\r\nmarketplace (which will typically document its review process), and it warrants deeper analysis to check for\r\nmalicious intent. In the same way, if an app asks for more permissions than seems appropriate, avoid installing it\r\nand do more analysis. Manually analyzing the files within the .apk is a good place to start and will help you select\r\nsome metrics to help understand the app’s intent and capabilities.\r\nWhen you analyze a malware sample, determining what code is part of the original app as opposed to the malware\r\nitself, the protector, ads, or a tracking system can be a challenge. It’s common to find numerous statistics SDKs\r\nwithin the same app collecting data about the device and user behavior. You’ll also find boot-time services that\r\nlaunch them after reboot.\r\nIn this case, I found the sample generating a JSON file enumerating all the installed apps containing permissions\r\nfor doing host card emulation (HCE) for NFC. The sample also dynamically loads two encrypted blobs and\r\nreferences another .apk protected with APK Protect. Extracting those pieces requires dynamic analysis, which I\r\nplan to cover in a future article.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 2 of 13\n\nPerforming a full analysis goes beyond the scope of this blog post, but I will walk through the introductory steps\r\nthat readers can then use as a starting place for more in-depth analysis. The steps I will cover include the\r\nfollowing:\r\n1. Extracting details about the malware like lists of permissions, types of binaries, function names, imported\r\nsymbols, classes, strings contained in the binaries, etc.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 3 of 13\n\n2. Performing static analysis on the suspicious binaries within the app in order to understand what the code is\r\ndoing with the resources identified in the first step.\r\n3. Emulating the sample in a QEMO-based Android environment in order to trace program execution and\r\nidentify system events and behaviors.\r\nMost mobile malware will not execute on non-ARM or emulated environments, and so I analyzed the sample  on\r\nan actual hardware device with clean, reflashed firmware.\r\nAndroidManifest.xml\r\nWhile its extension is .xml, AndroidManifest.xml is not plain text. It is a binary XML format used only in\r\nAndroid, and you can convert it to a readable format with the Axml2xml.rb Ruby script (also available via r2pm -i\r\naxml2xml).\r\nYou can also use the rafind2 program within Radare to extract strings of interest from the file (note that strings\r\nwill not work at all):\r\n$ rafind2 -ZS android AndroidManifest.xml\r\n$ rafind2 -ZS permissions AndroidManifest.xml\r\n$ rafind2 -ZS intent AndroidManifest.xml\r\nSome common permissions used by malware include the following:\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 4 of 13\n\npermission.CHANGE_WIFI_STATE\r\npermission.CHANGE_NETWORK_STATE\r\npermission.INSTALL_PACKAGES\r\npermission.INSTALL_SHORTCUT\r\npermission.SYSTEM_OVERLAY_WINDOW\r\npermission.ACCESS_DOWNLOAD_MANAGER\r\npermission.MOUNT_UNMOUNT_FILESYSTEMS\r\npermission.RECORD_AUDIO\r\npermission.RECEIVE_BOOT_COMPLETED\r\npermission.KILL_BACKGROUND_PROCESSES\r\npermission.ACCESS_MTK_MMHW\r\npermission.DISABLE_KEYGUARD\r\npermission.SYSTEM_ALERT_WINDOW/\r\npermission.GET_TASKS\r\n...\r\nClasses.dex\r\nThis file contains the Dalvik code of the application.  All of an app’s original Java code is transpiled into Dalvik\r\nand assembled in the DEX file, which runs on a stack-less, register-based virtual machine. Some versions of\r\nAndroid will emulate the code directly from the .dex file, others will translate it to real machine code via JIT (just-in-time) techniques, and most modern versions of Android will precompile most of that code into an AOT (ahead-of-time) executable targeting the ART (Android runtime).\r\nYou can use Radare2 to extract information from the .dex file using the following commands:\r\n\u003e icq # enumerate classnames\r\n\u003e iiq # imports (external methods)\r\n\u003e ic # enumerate classes and their methods\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 5 of 13\n\n\u003e izq # list all strings contained in the program\r\nOne important hint is to compare the permissions requested by the manifest and the ones used by the app itself. In\r\nthis case, as long as the application can dynamically load new code we will not see the true purpose unless we\r\nperform a dynamic analysis.\r\nChecking out the imports of the classes.dex will give us some hints about which kind of system APIs the\r\napplication is using.\r\n$ rabin2 -qi classes.dex | grep -i -e sms -e bluetooth -e install -e PackageManager -e Datagram -e Te\r\nIn addition we can use dexdump to enumerate all the intents used in the main dex:\r\n$ dexdump -d | grep ‘“android.’ | cut -d , -f 2- | sort -u\r\nOnce we have a complete disassembly from dexdump, you can use your favorite editor or even plain grep to find\r\nstring-const calls. But in Radare2 you can also use the /r command to find references to strings or methods in\r\norder to identify who is using those suspicious strings and for what purpose.\r\nFiltering Strings\r\nTo filter the output of commands, you can use the ~ operator in the Radare2 shell. The ~ operator is similar to the\r\nUNIX grep utility, but it runs internally and doesn’t require any separate system process to run.\r\nUsing the following string filters you can identify some interesting findings in the classes.dex file:\r\n/system /data /bin/su …\r\nhttp://\r\nhttps://\r\n.apk\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 6 of 13\n\n%d.%d.%d.%d\r\nInstall\r\nSMS\r\nDexClassLoader InjectCall (used for Dalvik code injection)\r\napplication/vnd.android  (mimetype used to spawn .apk installations)\r\n==    (embedded base64 resources)\r\nAfter executing the string filters on the malware sample, I found some hard-coded IPs, paths to system binaries\r\nlike su for device root checks, Dalvik code injection calls, the strings commonly used for installing .apks and\r\nfinally the URL to another file named 300010.apk.\r\nWhen an anti-virus vendor or a researcher discovers URLs linking to malware, they typically send a take-down\r\nnotice to the appropriate ISP. The ISP will then contact the owner of the server hosting the malware or directly\r\nblock those servers. So I was sure to grab the 300010.apk before it was removed so that I could perform further\r\nanalysis.\r\nBecause the .apk is protected with APK Protect, we need to decrypt the dynamically loaded code in order to\r\nunderstand what the app is doing exactly. This Android unpacker tool can be used for that purpose.\r\nIn this .dex file, I might also find strings encoded in base64, which can be decoded automatically by setting up the\r\nRABIN2_DEBASE64 environment variable or using the command rax2 -D on every single string. It turns out that\r\nsome base64 encoded strings contain binary data and others show interesting locations inside the binary, like\r\nloadLibrary().\r\n$ RABIN2_DEBASE64=1 rabin2 -qzz classes.dex\r\nFiltering methods\r\nRadare2’s visual mode also supports an interactive heads-up display that will filter out all string, method, and\r\nclass names from the .dex file. To enter the visual  mode, run the “V_” command, then type ‘_’ in visual mode.\r\nNext, type text that you want to highlight. When you press \u003center\u003e,  the UI will jump to that place in the\r\ndisassembler so that you can view the text in context.\r\nSome relevant text you may want to search for include:\r\nonReceive (used by event handlers)\r\nInit (all classes have one of them)\r\nPassword\r\nInstall\r\nDex\r\nSMS\r\nMost of the time, malware is protected with ProGuard or other obfuscation tools that will make the\r\nclass/method/field names completely useless. In that case, you need to dig into the disassembly or perform\r\ndynamic analysis to recover the original strings and understand the purpose of each method.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 7 of 13\n\nDisassembling\r\nRadare2 provides a visual mode (V command) and web user interface (via the =H command) that allows you to\r\nuse the mouse and get a more interactive view than the just a static prompt.\r\nAt this point, for analysis purposes, you may want to compare the output of Radare2 with other tools like\r\n`dexdump -d`, which is available in the Android SDK. Radare2 is known to be more reliable when tweaking .dex\r\nbinaries, making it a good alternative when decompilers and transpilers can’t be used.\r\n$ r2pm -i dex2jar\r\n$ r2pm -r dex2jar classes.dex\r\nOnce the .dex file  is transpiled into Java Classes, we can use Radare2 to disassemble the contents of the JAR.\r\nBecause having multiple views of the same code and reading assembly is not always the fastest way to understand\r\nsome parts of a program, you may want to use a decompiler like `jd-gui` which is freely available and can load all\r\nthe classes into the JAR file simultaneously.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 8 of 13\n\nUnfortunately, transpiling from Dalvik to Java bytecode or decompiling Java methods does not always work. Any\r\nnumber of different tools can fail at automated disassembly So an analyst needs to know and understand the risks\r\nand weak points of disassembly capabilities within each tool and be able to resolve those problems by hand.\r\nFor example, if we try to disassemble the 300010.apk with dexdump we will get a fancy segmentation fault\r\n(which has since been fixed in the Android 7 SDK):\r\n$ dexdump -d classes.dex \u003e /dev/null\r\nGLITCH: zero-width instruction at idx=0x0000\r\nGLITCH: zero-width instruction at idx=0x0000\r\nGLITCH: zero-width instruction at idx=0x0000\r\nSegmentation fault: 11\r\nTranspiling to Java will partially fail:\r\n$ r2pm -r dex2jar classes.dex 2\u003e\u00261 |grep Error | wc -l\r\n 40\r\nAndroguard will stop analyzing after an exception:\r\n$ androgui.py -i classes.dex\r\nTraceback (most recent call last):\r\n File \"/Library/Python/2.7/site-packages/androguard/core/bytecodes/dvm.py\", line 7014, in ge\r\n off = self.__manage_item[ \"TYPE_STRING_ID_ITEM\" ][idx].get_string_data_off()\r\nIndexError: list index out of range\r\nIn one case, trying to open the .apk in IDA Pro resulted in 9,382 error messages. In cases such as this, a low level\r\ndisassembler like Radare2 can help.\r\nLibraries\r\nNative libraries are usually interfaced with Java using JNI symbols, which are exposed in the shared library found\r\nin the lib/ subdirectory inside the .apk. Those libraries are usually split into different subdirectories depending on\r\nthe target architecture that is supposed to run (e.g., ARM, x86, ARM64, MIPS, etc.)\r\nIn this case we have only ARM binaries, which are typically compiled in Thumb2 mode. Radare2 will load those\r\nbinaries just fine, but you may be interested in switching between ARM and Thumb modes:\r\n\u003e e asm.bits=16 # set thumb2 mode\r\n\u003e e asm.bits=32 # set ARM mode\r\nThere are other variables like asm.cpu that can be useful to get the correct disassembly in some cases, but this will\r\nbe enough for most situations.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 9 of 13\n\nIn visual mode we can also use the HUD mode (use the ‘_’ key as explained before) to collect information from\r\nthe binary, such as symbols (isq), imports (iiq), or strings (izq).\r\nAfter running those commands, you can make an educated guess about the libraries’ purposes:\r\nlib/armeabi/libbspatch.so # bzip2 + binary patch API, used by umeng API to update stuff\r\nlib//armeabi/libcore.so # upay cryptography (Java_com_lem_sdk_util_CoreEnct_decrypt\r\nlib//armeabi/libmagic.so # java code injection by using reflection methods\r\nAt the least, none of them seem related to downloading YouTube videos.\r\nIn order to disassemble and understand what the code is doing, you will want to  emulate and analyze the code.\r\nYou can also do this with Radare2. Radare2’s emulation capability is implemented on top of ESIL (Evaluable\r\nStrings Intermediate Language), which is a completely  safe virtual machine that has nothing to do with Dalvik or\r\nreal hardware at all, so you can consider it as safe as static analysis.\r\nThe reason why emulation is necessary to disassemble ARM binaries is because some pointers are computed by\r\nmore than one instruction. This requires tracking the state changes and resolving the correct strings and method\r\nreferences.\r\n\u003e e asm.describe = true # show description of each ARM instruction\r\n\u003e e asm.pseudo = true # show pseudo instruction instead of assembly\r\n\u003e e asm.emu = true # emulate code using ESIL\r\n\u003e e asm.emustr = true # show string and method referenced in the emu comments\r\n\u003e e anal.hasnext=true # assume a new function is found after the last one\r\nSome commands that help with malware analysis include:\r\n\u003e aa - analyze all public symbols (use aaa or aaaa for more!)\r\n\u003e afr - analyze functions recursively\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 10 of 13\n\n\u003e aae - analyze all code references computed with ESIL emulation\r\n\u003e aac - analyze all call destinations as functions\r\nIn case you’re interested in a higher level version of the code, you can use the Retargetable Decompiler package in\r\nRadare2 to take advantage of the online decompilation service available at www.retdec.com.\r\nRadial graph of target’s full classes.dex references\r\nAssets\r\nAn .apk file contains several companion files that are loaded by the app at runtime. Some assets are images, others\r\nare XML files describing the user interface. During malware analysis, you may find suspicious companion files\r\nthat you want to take a closer look at.\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 11 of 13\n\nYou can use the `pm` command in Radare2 or the file tool to guess the filetype with the magic header information\r\non every file:\r\n$ find . -type f -exec r2 -qnci~^file -cpm ‘{}’ ‘;’\r\n$ file assets/*\r\nThe reason to use the internal magic implementation of Radare2 instead of GNU is mainly because there are\r\nknown vulnerabilities for libmagic file which may be used to run code or invalidate the analysis. RedHat patched\r\nthe issue this summer, but some other distributions and Docker images remain vulnerable.  Radare2’s\r\nimplementation of libmagic has been taken from OpenBSD, fuzzed, and enhanced. In my experience, Radare2 is\r\nalso more reliable and easier to modify if needed.\r\nIn addition to the print magic (`pm`) command we can use the /m command which will run `pm` on every offset to\r\nfind known magic signatures on raw files. This is useful for carving files from memory dumps, core images, and\r\nmore.\r\nWhen I examined the files contained within this sample of malware, I found some files with the .png extension\r\nthat seemed to contain encrypted data.\r\nConclusion: The Triada Android Trojan’s capabilities\r\nAfter using Google to see what other researchers have published about the Tirada Android Trojan, I began to\r\nunderstand the real risks brought about by this malware and how it can harm users:\r\nRoots the device and modifies the Zygote\r\nFactory Reset will not remove the malware\r\nSeems to target pre-KitKat devices but affects all versions\r\nMay ship some modular exploits to raise privileges\r\nAt this point, I’ve explained how to perform some very basic static analysis on a couple targets. As part of my\r\nanalysis, I’ve confirmed that this is in fact a modular virus capable of downloading more binaries and applications\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 12 of 13\n\nat runtime. But, we’re still far from understanding the malware in its entirety due to encrypted components, code\r\nloaded at runtime, installation of additional applications, networking communications, and more.\r\nSource: https://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nhttps://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/\r\nPage 13 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.nowsecure.com/blog/2016/11/21/android-malware-analysis-radare-triada-trojan/"
	],
	"report_names": [
		"android-malware-analysis-radare-triada-trojan"
	],
	"threat_actors": [],
	"ts_created_at": 1775791201,
	"ts_updated_at": 1775791337,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/4cf2aab6efdec8d6b16cb087411f4b38b49dfd25.pdf",
		"text": "https://archive.orkl.eu/4cf2aab6efdec8d6b16cb087411f4b38b49dfd25.txt",
		"img": "https://archive.orkl.eu/4cf2aab6efdec8d6b16cb087411f4b38b49dfd25.jpg"
	}
}