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. 15
      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) { private void handleDumpDex(String packageName, DumpResult result, ClassLoader classLoader) {
new Thread(() -> { new Thread(() -> {
try { try {
Thread.sleep(500); Thread.sleep(20*1000);
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
} }
try { try {

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

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

@ -12,6 +12,9 @@ import top.niunaijun.blackbox.BlackBoxCore.getPackageManager
import top.niunaijun.blackbox.BlackDexCore import top.niunaijun.blackbox.BlackDexCore
import top.niunaijun.blackbox.utils.AbiUtils import top.niunaijun.blackbox.utils.AbiUtils
import top.niunaijun.blackbox.utils.FileUtils 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.AppInfo
import top.niunaijun.blackdex.data.entity.DumpInfo import top.niunaijun.blackdex.data.entity.DumpInfo
import java.io.File import java.io.File
@ -80,7 +83,17 @@ class DexDumpRepository {
private fun startCountdown(dexDumpLiveData: MutableLiveData<DumpInfo>) { private fun startCountdown(dexDumpLiveData: MutableLiveData<DumpInfo>) {
GlobalScope.launch { GlobalScope.launch {
val tempId = dumpTaskId val tempId = dumpTaskId
delay(10000)
while (BlackDexCore.get().isRunning){
delay(10000)
//10s
if(!AppManager.mBlackBoxLoader.isFixCodeItem()){
break
}
//fixCodeItem 需要长时间运行,普通内存dump不需要
}
if (tempId == dumpTaskId) { if (tempId == dumpTaskId) {
dexDumpLiveData.postValue(DumpInfo(DumpInfo.TIMEOUT)) 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.MaterialDialog
import com.afollestad.materialdialogs.files.fileChooser import com.afollestad.materialdialogs.files.fileChooser
import com.ferfalk.simplesearchview.SimpleSearchView import com.ferfalk.simplesearchview.SimpleSearchView
import com.roger.catloadinglibrary.CatLoadingView
import com.umeng.analytics.MobclickAgent import com.umeng.analytics.MobclickAgent
import top.niunaijun.blackbox.BlackDexCore import top.niunaijun.blackbox.BlackDexCore
import top.niunaijun.blackbox.core.system.dump.IBDumpMonitor 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.databinding.ActivityMainBinding
import top.niunaijun.blackdex.util.FileUtil import top.niunaijun.blackdex.util.FileUtil
import top.niunaijun.blackdex.util.InjectionUtil import top.niunaijun.blackdex.util.InjectionUtil
import top.niunaijun.blackdex.util.LoadingUtil
import top.niunaijun.blackdex.util.inflate import top.niunaijun.blackdex.util.inflate
import top.niunaijun.blackdex.view.base.PermissionActivity import top.niunaijun.blackdex.view.base.PermissionActivity
import top.niunaijun.blackdex.view.setting.SettingActivity import top.niunaijun.blackdex.view.setting.SettingActivity
import top.niunaijun.blackdex.view.widget.ProgressDialog
import java.io.File import java.io.File
@ -39,7 +38,7 @@ class MainActivity : PermissionActivity() {
private lateinit var mAdapter: MainAdapter private lateinit var mAdapter: MainAdapter
private lateinit var loadingView: CatLoadingView private var loadingView: ProgressDialog? = null
private var initialDir: File? = null private var initialDir: File? = null
@ -124,11 +123,6 @@ class MainActivity : PermissionActivity() {
showLoading() showLoading()
} }
DumpInfo.TIMEOUT -> { DumpInfo.TIMEOUT -> {
// 判断是否running
Log.e("Tag", "isRunning ${BlackDexCore.get().isRunning}")
if (BlackDexCore.get().isRunning) {
return@let
}
hideLoading() hideLoading()
MaterialDialog(this).show { MaterialDialog(this).show {
title(R.string.unpack_fail) title(R.string.unpack_fail)
@ -167,14 +161,13 @@ class MainActivity : PermissionActivity() {
private val mMonitor = object : IBDumpMonitor.Stub() { private val mMonitor = object : IBDumpMonitor.Stub() {
override fun onDump(result: DumpResult?) { override fun onDump(result: DumpResult?) {
result?.let { result?.let {
Log.e("mMonitor", "onDump: ${result.toString()}")
// 此处做进度条 // 此处做进度条
if (result.isRunning) { if (result.isRunning) {
val totalProcess = result.totalProcess loadingView?.setProgress(result.currProcess, result.totalProcess)
val currProcess = result.currProcess
return return
} }
if (result.isSuccess) { if (result.isSuccess) {
viewModel.mDexDumpLiveData.postValue( viewModel.mDexDumpLiveData.postValue(
DumpInfo( DumpInfo(
@ -223,17 +216,15 @@ class MainActivity : PermissionActivity() {
} }
private fun showLoading() { private fun showLoading() {
if (!this::loadingView.isInitialized) { if (this.loadingView == null) {
loadingView = CatLoadingView() loadingView = ProgressDialog()
} }
loadingView?.show(supportFragmentManager, "")
LoadingUtil.showLoading(loadingView, supportFragmentManager)
} }
private fun hideLoading() { private fun hideLoading() {
if (this::loadingView.isInitialized) { loadingView?.dismiss()
loadingView.dismiss() loadingView = null
}
} }
private fun hideKeyboard() { private fun hideKeyboard() {

@ -26,6 +26,8 @@ class SettingFragment : PreferenceFragmentCompat() {
private lateinit var saveEnablePreference: SwitchPreferenceCompat private lateinit var saveEnablePreference: SwitchPreferenceCompat
private lateinit var fixCodeItemPreference: SwitchPreferenceCompat
private val initialDirectory = AppManager.mBlackBoxLoader.getSavePath() private val initialDirectory = AppManager.mBlackBoxLoader.getSavePath()
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@ -38,6 +40,10 @@ class SettingFragment : PreferenceFragmentCompat() {
saveEnablePreference.onPreferenceChangeListener = mSaveEnableChange saveEnablePreference.onPreferenceChangeListener = mSaveEnableChange
saveEnablePreference.isChecked = AppManager.mBlackBoxLoader.saveEnable() saveEnablePreference.isChecked = AppManager.mBlackBoxLoader.saveEnable()
fixCodeItemPreference = findPreference("fix_code_item")!!
fixCodeItemPreference.onPreferenceChangeListener = mFixCodeItemChange
fixCodeItemPreference.isChecked = AppManager.mBlackBoxLoader.isFixCodeItem()
} }
private val mSavedPathClick = Preference.OnPreferenceClickListener { private val mSavedPathClick = Preference.OnPreferenceClickListener {
@ -73,6 +79,27 @@ class SettingFragment : PreferenceFragmentCompat() {
return@OnPreferenceChangeListener true 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 -> private val requestResult = { hasPermission: Boolean ->
AppManager.mBlackBoxLoader.saveEnable(!hasPermission) 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="file_save">文件储存</string>
<string name="use_default_file">使用默认储存路径</string> <string name="use_default_file">使用默认储存路径</string>
<string name="rewrite_file_path">自定义储存路径</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> </resources>

@ -23,4 +23,13 @@
<string name="file_save">File</string> <string name="file_save">File</string>
<string name="use_default_file">Use Default Path</string> <string name="use_default_file">Use Default Path</string>
<string name="rewrite_file_path">Customize the storage 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> </resources>

@ -12,4 +12,12 @@
android:key="save_path" android:key="save_path"
android:title="@string/rewrite_file_path" /> android:title="@string/rewrite_file_path" />
</PreferenceCategory> </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> </PreferenceScreen>
Loading…
Cancel
Save