Files
verify/inject/android/HookApplication.java
T

357 lines
14 KiB
Java

package com.example.shell;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
public class HookApplication extends Application {
public static boolean showDialog = true;
public static boolean showFullscreen = true; // ✅ 全屏弹窗开关
private AlertDialog dialog = null;
private Dialog fullscreenDialog = null; // ✅ 全屏弹窗引用
public static boolean showImageFullscreen = true; // ✅ 控制图片弹窗
private Dialog imageDialog = null;
private WeakReference<Activity> currentActivityRef = null;
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getApplicationContext(), "HookApplication 已启动", Toast.LENGTH_SHORT).show();
//Hook弹窗
new Handler(Looper.getMainLooper()).postDelayed(() -> {
showPopupLoop();
}, 3000);
//全屏欢迎弹窗
new Handler(Looper.getMainLooper()).postDelayed(() -> { // ✅ 全屏弹窗监听
showFullscreenLoop();
}, 3000);
//全屏广告弹窗
new Handler(Looper.getMainLooper()).postDelayed(() -> {
showImageFullscreenLoop(
"https://i11.hoopchina.com.cn/editor/3037dc8d3081ab92b16a80b36ef1b332_w_1242_h_1242_.png",
() -> Toast.makeText(getApplicationContext(), "你点击了图片", Toast.LENGTH_SHORT).show(),
5
);
}, 3000);
}
private void showPopupLoop() {
Handler handler = new Handler(Looper.getMainLooper());
Runnable popupTask = new Runnable() {
@Override
public void run() {
if (!showDialog) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
return;
}
Activity activity = getCurrentActivity();
if (activity == null) {
handler.postDelayed(this, 1000);
return;
}
boolean needShow = (dialog == null || !dialog.isShowing());
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
if (needShow || activityChanged) {
currentActivityRef = new WeakReference<>(activity);
dialog = new AlertDialog.Builder(activity)
.setTitle("Hook 弹窗")
.setMessage("当前 Activity: " + activity.getClass().getSimpleName())
.setCancelable(false)
.setPositiveButton("关闭弹窗", (d, w) -> {
if (dialog != null) {
showDialog = false;
dialog.dismiss();
}
})
.show();
}
handler.postDelayed(this, 1000);
}
};
handler.post(popupTask);
}
// ✅ 全屏弹窗监听器
private void showFullscreenLoop() {
Handler handler = new Handler(Looper.getMainLooper());
Runnable fullscreenTask = new Runnable() {
@Override
public void run() {
if (!showFullscreen) {
if (fullscreenDialog != null && fullscreenDialog.isShowing()) {
fullscreenDialog.dismiss();
}
return;
}
Activity activity = getCurrentActivity();
if (activity == null) {
handler.postDelayed(this, 1000);
return;
}
boolean needShow = (fullscreenDialog == null || !fullscreenDialog.isShowing());
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
if (needShow || activityChanged) {
currentActivityRef = new WeakReference<>(activity);
fullscreenDialog = new Dialog(activity, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundColor(Color.WHITE);
layout.setGravity(Gravity.CENTER);
layout.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
TextView title = new TextView(activity);
title.setText("欢迎使用菜鸟安卓弹窗注入器");
title.setTextSize(24);
title.setTextColor(Color.BLACK);
title.setGravity(Gravity.CENTER);
title.setPadding(0, 0, 0, 50);
layout.addView(title);
Button close = new Button(activity);
close.setText("进入");
layout.addView(close);
close.setOnClickListener(v -> {
showFullscreen = false;
if (fullscreenDialog != null) {
fullscreenDialog.dismiss();
}
});
fullscreenDialog.setContentView(layout);
fullscreenDialog.setCancelable(false);
fullscreenDialog.show();
}
handler.postDelayed(this, 1000);
}
};
handler.post(fullscreenTask);
}
private void showImageFullscreenLoop(String imageUrl, Runnable onImageClick, int countdownSeconds) {
Handler handler = new Handler(Looper.getMainLooper());
Runnable imageTask = new Runnable() {
int remaining = countdownSeconds;
@Override
public void run() {
if (!showImageFullscreen) {
if (imageDialog != null && imageDialog.isShowing()) {
imageDialog.dismiss();
}
return;
}
Activity activity = getCurrentActivity();
if (activity == null) {
handler.postDelayed(this, 1000);
return;
}
boolean needShow = (imageDialog == null || !imageDialog.isShowing());
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
if (needShow || activityChanged) {
currentActivityRef = new WeakReference<>(activity);
imageDialog = new Dialog(activity, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
// 主容器
FrameLayout rootLayout = new FrameLayout(activity);
rootLayout.setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
// 图片控件
android.widget.ImageView imageView = new android.widget.ImageView(activity);
imageView.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
// 标签按钮
// 标签按钮(带圆角背景)
Button closeBtn = new Button(activity);
closeBtn.setText("倒计时 " + remaining + " 秒");
closeBtn.setTextColor(Color.WHITE);
closeBtn.setTextSize(14f);
closeBtn.setPadding(30, 10, 30, 10);
closeBtn.setEnabled(false);
// 创建圆角背景
android.graphics.drawable.GradientDrawable bg = new android.graphics.drawable.GradientDrawable();
bg.setColor(Color.parseColor("#AA000000")); // 半透明黑
bg.setCornerRadius(50); // 圆角
closeBtn.setBackground(bg);
// 圆角布局参数
FrameLayout.LayoutParams btnParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
btnParams.gravity = Gravity.TOP | Gravity.END;
btnParams.setMargins(30, 60, 30, 0);
closeBtn.setLayoutParams(btnParams);
closeBtn.setEnabled(false); // 初始不可点击
rootLayout.addView(imageView);
rootLayout.addView(closeBtn);
// 设置点击事件
imageView.setOnClickListener(v -> {
if (onImageClick != null) onImageClick.run();
});
closeBtn.setOnClickListener(v -> {
if (remaining <= 0) {
showImageFullscreen = false;
imageDialog.dismiss();
}
});
imageDialog.setContentView(rootLayout);
imageDialog.setCancelable(false);
imageDialog.show();
if (imageDialog.getWindow() != null) {
imageDialog.getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
imageDialog.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
// 倒计时逻辑
Handler countdownHandler = new Handler(Looper.getMainLooper());
Runnable countdown = new Runnable() {
@Override
public void run() {
if (!showImageFullscreen || imageDialog == null || !imageDialog.isShowing()) {
return;
}
if (remaining > 0) {
closeBtn.setText("倒计时 " + remaining + " 秒");
remaining--;
countdownHandler.postDelayed(this, 1000);
} else {
closeBtn.setText("关闭");
closeBtn.setEnabled(true);
}
}
};
countdownHandler.post(countdown);
// 加载网络图片
new Thread(() -> {
try {
java.net.URL url = new java.net.URL(imageUrl);
java.io.InputStream input = url.openStream();
android.graphics.Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(input);
input.close();
new Handler(Looper.getMainLooper()).post(() -> {
imageView.setImageBitmap(bitmap);
});
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
handler.postDelayed(this, 1000);
}
};
handler.post(imageTask);
}
private Activity getCurrentActivity() {
try {
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
Method currentActivityThreadMethod = activityThreadClass.getMethod("currentActivityThread");
Object activityThread = currentActivityThreadMethod.invoke(null);
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
activitiesField.setAccessible(true);
Map<?, ?> activities = (Map<?, ?>) activitiesField.get(activityThread);
for (Object record : activities.values()) {
Class<?> recordClass = record.getClass();
Field pausedField = recordClass.getDeclaredField("paused");
pausedField.setAccessible(true);
boolean paused = pausedField.getBoolean(record);
if (!paused) {
Field activityField = recordClass.getDeclaredField("activity");
activityField.setAccessible(true);
return (Activity) activityField.get(record);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
}