1.支持抽取壳的修复(请在设置里切换)

pull/16/head
kai-city 4 years ago
parent 556f37b1c9
commit c8fcba483f
  1. 2
      Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java
  2. 6
      app/build.gradle
  3. 12
      app/src/main/java/top/niunaijun/blackdex/app/BlackDexLoader.kt
  4. 13
      app/src/main/java/top/niunaijun/blackdex/data/DexDumpRepository.kt
  5. 30
      app/src/main/java/top/niunaijun/blackdex/util/LoadingUtil.kt
  6. 27
      app/src/main/java/top/niunaijun/blackdex/view/main/MainActivity.kt
  7. 27
      app/src/main/java/top/niunaijun/blackdex/view/setting/SettingFragment.kt
  8. 53
      app/src/main/java/top/niunaijun/blackdex/view/widget/ProgressDialog.kt
  9. 24
      app/src/main/res/layout/dialog_progress.xml
  10. 10
      app/src/main/res/values-zh/string.xml
  11. 9
      app/src/main/res/values/strings.xml
  12. 8
      app/src/main/res/xml/setting.xml

@ -212,7 +212,7 @@ public class BActivityThread extends IBActivityThread.Stub {
private void handleDumpDex(String packageName, DumpResult result, ClassLoader classLoader) {
new Thread(() -> {
try {
Thread.sleep(500);
Thread.sleep(20*1000);
} catch (InterruptedException ignored) {
}
try {

@ -11,8 +11,8 @@ android {
applicationId "top.niunaijun.blackdex"
minSdkVersion 21
targetSdkVersion 30
versionCode 2
versionName "1.1.0"
versionCode 3
versionName "2.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -91,8 +91,6 @@ dependencies {
//dialog
implementation 'com.github.nukc.stateview:kotlin:2.2.0'
//
implementation 'com.roger.catloadinglibrary:catloadinglibrary:1.0.9'
//dialog
implementation 'com.github.Ferfalk:SimpleSearchView:0.2.0'
//searchView

@ -21,6 +21,8 @@ class BlackDexLoader {
private var mSaveEnable by AppSharedPreferenceDelegate(App.getContext(), true)
private var mFixCodeItem by AppSharedPreferenceDelegate(App.getContext(),false)
private var mDir = if (mSaveEnable) {
getDexDumpDir(App.getContext())
} else {
@ -42,7 +44,7 @@ class BlackDexLoader {
}
override fun isFixCodeItem(): Boolean {
return false
return mFixCodeItem
}
})
}
@ -67,6 +69,14 @@ class BlackDexLoader {
this.mSavePath = path
}
fun setFixCodeItem(enable:Boolean){
this.mFixCodeItem = enable
}
fun isFixCodeItem():Boolean{
return this.mFixCodeItem
}
companion object {

@ -12,6 +12,9 @@ import top.niunaijun.blackbox.BlackBoxCore.getPackageManager
import top.niunaijun.blackbox.BlackDexCore
import top.niunaijun.blackbox.utils.AbiUtils
import top.niunaijun.blackbox.utils.FileUtils
import top.niunaijun.blackdex.app.App
import top.niunaijun.blackdex.app.AppManager
import top.niunaijun.blackdex.app.BlackDexLoader
import top.niunaijun.blackdex.data.entity.AppInfo
import top.niunaijun.blackdex.data.entity.DumpInfo
import java.io.File
@ -80,7 +83,17 @@ class DexDumpRepository {
private fun startCountdown(dexDumpLiveData: MutableLiveData<DumpInfo>) {
GlobalScope.launch {
val tempId = dumpTaskId
while (BlackDexCore.get().isRunning){
delay(10000)
//10s
if(!AppManager.mBlackBoxLoader.isFixCodeItem()){
break
}
//fixCodeItem 需要长时间运行,普通内存dump不需要
}
if (tempId == dumpTaskId) {
dexDumpLiveData.postValue(DumpInfo(DumpInfo.TIMEOUT))

@ -1,30 +0,0 @@
package top.niunaijun.blackdex.util
import android.view.KeyEvent
import androidx.fragment.app.FragmentManager
import com.roger.catloadinglibrary.CatLoadingView
import top.niunaijun.blackdex.R
/**
*
* @Description:
* @Author: wukaicheng
* @CreateDate: 2021/4/30 23:04
*/
object LoadingUtil {
fun showLoading(loadingView: CatLoadingView, fragmentManager: FragmentManager) {
if (!loadingView.isAdded) {
loadingView.setBackgroundColor(R.color.primary)
loadingView.show(fragmentManager, "")
fragmentManager.executePendingTransactions()
loadingView.setClickCancelAble(false)
loadingView.dialog?.setOnKeyListener { _, keyCode, _ ->
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
return@setOnKeyListener true
}
false
}
}
}
}

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.files.fileChooser
import com.ferfalk.simplesearchview.SimpleSearchView
import com.roger.catloadinglibrary.CatLoadingView
import com.umeng.analytics.MobclickAgent
import top.niunaijun.blackbox.BlackDexCore
import top.niunaijun.blackbox.core.system.dump.IBDumpMonitor
@ -24,10 +23,10 @@ import top.niunaijun.blackdex.data.entity.DumpInfo
import top.niunaijun.blackdex.databinding.ActivityMainBinding
import top.niunaijun.blackdex.util.FileUtil
import top.niunaijun.blackdex.util.InjectionUtil
import top.niunaijun.blackdex.util.LoadingUtil
import top.niunaijun.blackdex.util.inflate
import top.niunaijun.blackdex.view.base.PermissionActivity
import top.niunaijun.blackdex.view.setting.SettingActivity
import top.niunaijun.blackdex.view.widget.ProgressDialog
import java.io.File
@ -39,7 +38,7 @@ class MainActivity : PermissionActivity() {
private lateinit var mAdapter: MainAdapter
private lateinit var loadingView: CatLoadingView
private var loadingView: ProgressDialog? = null
private var initialDir: File? = null
@ -124,11 +123,6 @@ class MainActivity : PermissionActivity() {
showLoading()
}
DumpInfo.TIMEOUT -> {
// 判断是否running
Log.e("Tag", "isRunning ${BlackDexCore.get().isRunning}")
if (BlackDexCore.get().isRunning) {
return@let
}
hideLoading()
MaterialDialog(this).show {
title(R.string.unpack_fail)
@ -167,14 +161,13 @@ class MainActivity : PermissionActivity() {
private val mMonitor = object : IBDumpMonitor.Stub() {
override fun onDump(result: DumpResult?) {
result?.let {
Log.e("mMonitor", "onDump: ${result.toString()}")
// 此处做进度条
if (result.isRunning) {
val totalProcess = result.totalProcess
val currProcess = result.currProcess
loadingView?.setProgress(result.currProcess, result.totalProcess)
return
}
if (result.isSuccess) {
viewModel.mDexDumpLiveData.postValue(
DumpInfo(
@ -223,17 +216,15 @@ class MainActivity : PermissionActivity() {
}
private fun showLoading() {
if (!this::loadingView.isInitialized) {
loadingView = CatLoadingView()
if (this.loadingView == null) {
loadingView = ProgressDialog()
}
LoadingUtil.showLoading(loadingView, supportFragmentManager)
loadingView?.show(supportFragmentManager, "")
}
private fun hideLoading() {
if (this::loadingView.isInitialized) {
loadingView.dismiss()
}
loadingView?.dismiss()
loadingView = null
}
private fun hideKeyboard() {

@ -26,6 +26,8 @@ class SettingFragment : PreferenceFragmentCompat() {
private lateinit var saveEnablePreference: SwitchPreferenceCompat
private lateinit var fixCodeItemPreference: SwitchPreferenceCompat
private val initialDirectory = AppManager.mBlackBoxLoader.getSavePath()
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@ -38,6 +40,10 @@ class SettingFragment : PreferenceFragmentCompat() {
saveEnablePreference.onPreferenceChangeListener = mSaveEnableChange
saveEnablePreference.isChecked = AppManager.mBlackBoxLoader.saveEnable()
fixCodeItemPreference = findPreference("fix_code_item")!!
fixCodeItemPreference.onPreferenceChangeListener = mFixCodeItemChange
fixCodeItemPreference.isChecked = AppManager.mBlackBoxLoader.isFixCodeItem()
}
private val mSavedPathClick = Preference.OnPreferenceClickListener {
@ -73,6 +79,27 @@ class SettingFragment : PreferenceFragmentCompat() {
return@OnPreferenceChangeListener true
}
private val mFixCodeItemChange = Preference.OnPreferenceChangeListener { _, newValue ->
if (newValue as Boolean) {
MaterialDialog(requireContext()).show {
title(R.string.warn)
message(R.string.fix_code_item_message)
positiveButton(R.string.confirm) {
AppManager.mBlackBoxLoader.setFixCodeItem(true)
}
negativeButton(R.string.cancel) {
fixCodeItemPreference.isChecked = false
AppManager.mBlackBoxLoader.setFixCodeItem(false)
}
}
} else {
AppManager.mBlackBoxLoader.setFixCodeItem(newValue)
}
return@OnPreferenceChangeListener true
}
private val requestResult = { hasPermission: Boolean ->
AppManager.mBlackBoxLoader.saveEnable(!hasPermission)

@ -0,0 +1,53 @@
package top.niunaijun.blackdex.view.widget
import android.app.Dialog
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import top.niunaijun.blackdex.R
import top.niunaijun.blackdex.databinding.DialogProgressBinding
import top.niunaijun.blackdex.util.inflate
/**
*
* @Description: progress dialog
* @Author: wukaicheng
* @CreateDate: 2021/6/7 21:16
*/
class ProgressDialog : DialogFragment() {
private val TAG = "ProgressDialog"
private val viewBinding: DialogProgressBinding by inflate()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = AlertDialog.Builder(requireContext())
.setView(viewBinding.root)
.setTitle(getString(R.string.classes_progress,1,1))
.setCancelable(false)
.show()
dialog.setCanceledOnTouchOutside(false)
dialog.setOnKeyListener { _, keyCode, _ ->
return@setOnKeyListener keyCode == KeyEvent.KEYCODE_BACK
}
return dialog
}
fun setProgress(progress: Int, maxProgress: Int) {
requireActivity().runOnUiThread {
if (progress == 0) {
viewBinding.progress.max = maxProgress
}
viewBinding.progress.progress = progress
dialog?.setTitle(getString(R.string.classes_progress,progress,maxProgress))
}
}
}

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:text="@string/dumping"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"/>
</LinearLayout>

@ -23,4 +23,14 @@
<string name="file_save">文件储存</string>
<string name="use_default_file">使用默认储存路径</string>
<string name="rewrite_file_path">自定义储存路径</string>
<string name="warn">警告</string>
<string name="advanced_setting">高级设置</string>
<string name="fix_code_item">深度脱壳</string>
<string name="fix_code_item_desc">自主修复抽取指令,还原Dex文件</string>
<string name="fix_code_item_message">开启后将进行深度脱壳,深度脱壳会自主修复被抽取的指令,开启后请注意以下变化。\n\n1.脱壳时间会大幅度上升,预计几分钟都十几分钟不等\n2.脱壳期间有可能会出现应用闪退(遇到反检测等)\n3.会增加脱壳失败几率\n4.不一定能够100%还原
</string>
<string name="dumping">正在脱壳…</string>
</resources>

@ -23,4 +23,13 @@
<string name="file_save">File</string>
<string name="use_default_file">Use Default Path</string>
<string name="rewrite_file_path">Customize the storage path</string>
<string name="warn">Warning</string>
<string name="advanced_setting">Advanced Settings</string>
<string name="fix_code_item">FixCodeItem</string>
<string name="fix_code_item_desc">Self-repair extraction instructions and restore Dex files</string>
<string name="fix_code_item_message">After opening, deep shelling will be carried out. Deep shelling will automatically repair the extracted commands. Please pay attention to the following changes after opening. \n\n1. The shelling time will increase significantly, and it is expected to take a few minutes to ten minutes. \n2. During the shelling, there may be application crashes (in case of anti-detection, etc.) \n3. It will increase the chance of shelling failure \n4. Not necessarily 100% reduction
</string>
<string name="classes_progress" translatable="false">classes.dex (%1d/%1d)</string>
<string name="dumping">dumping…</string>
</resources>

@ -12,4 +12,12 @@
android:key="save_path"
android:title="@string/rewrite_file_path" />
</PreferenceCategory>
<PreferenceCategory android:title="高级选项">
<SwitchPreferenceCompat
android:key="fix_code_item"
android:summary="@string/fix_code_item_desc"
android:title="@string/fix_code_item" />
</PreferenceCategory>
</PreferenceScreen>
Loading…
Cancel
Save