应用安全 --- apk加固 之 防止截屏
package com.iran.SmaliHelper; import android.app.Activity; import android.app.Application; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Window; import java.util.Objects; public class com.gklbb extends ContentProvider implements Application.ActivityLifecycleCallbacks { public com.gklbb() { super(); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Window window = activity.getWindow(); window.setFlags(0x2000, 0x2000); // FLAG_SECURE } @Override public void onActivityDestroyed(Activity activity) { // Empty implementation } @Override public void onActivityPaused(Activity activity) { // Empty implementation } @Override public void onActivityResumed(Activity activity) { // Empty implementation } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { // Empty implementation } @Override public void onActivityStarted(Activity activity) { Window window = activity.getWindow(); window.setFlags(0x2000, 0x2000); // FLAG_SECURE } @Override public void onActivityStopped(Activity activity) { // Empty implementation } @Override public boolean onCreate() { Context context = Objects.requireNonNull(getContext()); Application application = (Application) context.getApplicationContext(); application.registerActivityLifecycleCallbacks(this); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
对抗 (const(.*) ([pv]\d+), 0x.*)\s*(invoke-*.* \{([pv]\d+), ([pv]\d+), ([pv]\d+)\}, Landroid/view/Window;->setFlags\(II\)V) 替换 const$2 $3, 0x0 $4
逐个部分解释
1. (const(.*) ([pv]\d+), 0x.*)
作用:匹配const指令行
-
const- 匹配字面量"const" -
(.*)- 组2:匹配const操作符的后缀-
如:
/16,/high16,/4,/wide等 -
示例:
const/16,const/high16
-
-
([pv]\d+)- 组3:匹配寄存器名-
[pv]- 匹配p或v -
\d+- 匹配一个或多个数字 -
示例:
v0,p1,v15
-
-
, 0x.*- 匹配十六进制数值-
0x- 十六进制前缀 -
.*- 匹配任意十六进制数字 -
示例:
, 0x1000,, 0x80000
-
2. \s*
作用:匹配空白字符
-
匹配零个或多个空白字符(空格、制表符、换行符等)
-
用于连接const指令和invoke指令
3. (invoke-*.* \{([pv]\d+), ([pv]\d+), ([pv]\d+)\}, Landroid/view/Window;->setFlags\(II\)V)
作用:匹配invoke指令行
-
invoke-- 匹配字面量"invoke-" -
*.*- 匹配方法调用类型-
如:
virtual,direct,static,interface -
示例:
invoke-virtual,invoke-direct
-
-
\{([pv]\d+), ([pv]\d+), ([pv]\d+)\}- 匹配寄存器列表-
组5:第一个寄存器 - Window对象实例
-
组6:第二个寄存器 - flags参数
-
组7:第三个寄存器 - mask参数
-
-
, Landroid/view/Window;->setFlags\(II\)V- 匹配方法签名-
Landroid/view/Window;- Window类的完整路径 -
->setFlags- 方法名 -
(II)V- 方法参数和返回类型(两个int参数,void返回)
-
完整匹配示例
匹配的代码:
const/16 v0, 0x1000
invoke-virtual {v1, v0, v2}, Landroid/view/Window;->setFlags(II)V
各组捕获的内容:
-
组1:
const/16 v0, 0x1000(整个const指令) -
组2:
/16(const操作符后缀) -
组3:
v0(寄存器名) -
组4:
invoke-virtual {v1, v0, v2}, Landroid/view/Window;->setFlags(II)V(整个invoke指令) -
组5:
v1(Window对象实例) -
组6:
v0(flags参数) -
组7:
v2(mask参数)
替换操作
const$2 $3, 0x0 会将const指令的值改为0,从而在setFlags调用时传入0作为flags参数,达到清除所有窗口标志的效果。
使用场景
-
用第一个操作:当你想要清除所有窗口标志时
-
用第二个操作:当你想要阻止添加特定标志时
两者可以结合使用,实现完全禁用窗口特殊效果的目的。
浙公网安备 33010602011771号