安卓逆向_5 --- jeb 和 AndroidStudio 动态调试 smali

news2025/1/16 1:01:04

Jeb 工具的使用

  • :https://www.52pojie.cn/forum.php?mod=viewthread&tid=742250
  • :https://zhuanlan.zhihu.com/p/302856081

动态调试 smali 有两种方法:

  • Jeb 调试
  • AndroidStudio + smalidea 插件动态调试。

1、Jeb 动态调试 smali

​JEB是一个功能强大为安全专业人士设计的安卓应用程序反编译工具,用于逆向工程或者审计apk文件,可以提高效率减少许多工程师的分析时间。

jeb 动态调试分两种:

  • 普通调试 模式
  • debug 调试 模式

Jeb 常用功能、简单使用

  • 1. 反编译 apk、dex
  • 2. 包名 树状图
  • 3. 查看指定类的 smali 代码
  • 4. 转换成 java 语言
  • 5. java 代码中双击函数 进入函数方法的定义 ,查看方法的调用
  • 6. 查看 AndroidManifest.xml

打开 jeb 方法的 2 种方法:

  • 方法 1:直接打开 jeb.exe 软件
  • 方法 2:执行 jeb_wincon.bat,当需要定制 jeb 的参数时,可以直接修改 jeb_wincon.bat 再执行。

简单使用

  • 把 apk 拖拉到 JEB 中即可反编译 apk 双击 Bytecode 打开 smali 代码
  • 双击 包名 下的 类名 即可查看 smali 代码
  • 选中 smali 代码,然后按 tab 键 可转成 java 代码。或者 "右键 ---> 解析" 也可以转成 java 代码
  • 双击方法,可跳转到方法的定义
  • 点击方法,按 x 键可以查看方法的调用
  • 双击 Manifest 即可查看 AndroidManifest.xml
  • 搜索功能 可以搜索函数 字符串等。
  • 点击string查看dex中的字符串,ctrl+f就可以进行搜索。搜索到需要的字符串后双击就可以来到smali代码处,如果看不懂smali,按下tab就可以看到java代码

说明:对于Android逆向来说JEB是不可或缺的一款软件 本篇介绍了JEB的一些常用功能  更多详细功能还需自行百度。

Jeb 动态调试 ( 调试 zhuceji.apk )

jeb 调试 zhuceji.apk 找到注册码

普通调试 模式

1. 真机 (或者模拟器,例如:雷电模拟器、逍遥模拟器) 安装 zhuceji.apk。界面很简单。

2. Jeb 打开 apk,找到要调试的方法对应的 smali 代码,然后在 smali 代码中打上断代点。

鼠标点击要下断点的行:control+b 打断点

3. 下面开始对程序进行调试

debug ---> 开始 ---> 找到相关进程双击进行调试:

4. 首先在要调试的位置打上断点,然后在 app 中输入任意 16 位注册码进行调试 ( 通过查看 checkSN 源码,可以看到对 sn 长度进行检查,必须16位 ):

5. 通过调试 smali 代码,或者直接查看 Java 源码,可以找到 checkSN 方法是解决问题的关键。

 在 checkSN 方法上,按 tab 键,或者 "右键 ---> 解析" 即可查看 checkSN 对应的 Java 代码,

通过分析可以发现,把 userName 做了一个 md5,然后取出16位和 sn 相比 ( 注意:从第一位开始,间隔一位取一位)。

userName:李青

md5:4d85f1a100030c9ddb76e546152c1dfe

注册码:48fa0009d7e4121f

断点走到  access$2 时,单步进入函数。

在 access$2 函数中调用 checkSN 函数的。查看 参数值

进入 checkSN 函数继续 单步调试

 进入 checkSN 函数,并在 equalsIgnoreCase 打上断点,执行到断点处。

可以看到 v6 寄存器的值就是注册码,

userName:李青

注册码:48fa0009d7e4121f

输入正确的名字、注册码,即可验证通过

debug 调试 模式

debug 模式 和 普通模式的区别在于 启动过程

  • 普通模式:无法调试界面的 创建,即 onCreate 函数
  • debug 模式:可以调试 界面的 onCreate 函数,即刚开始创建界面是就开始调试

步骤:

1. 查看 application 节点 是否 为 可调式 。

如果是 False,则不能调试,需要改成 True 然后重新打包 apk,安装 可调试的 apk,然后执行命令:adb shell am start -D -n 应用程序包名/应用程序入口界面

除了在入口处添加Debug.waitForDebugger外,还可以使用下面的命令启动app,也能使app在入口处断下来:adb shell am start -D -S -n com.xy.testcrack/com.xy.testcrack.MainActivity

这里可以看到 apk 已经 可调试。

2. cmd ---> adb shell am start -D -n 应用程序包名/应用程序入口界面:

adb shell am start -D -n com.qianyu.zhuceji/.MainActivity

执行完后,真机 ( 或者 模拟器 ) 显示如图:

这时候,不需要点击弹窗。

3. 使用 jeb 开始调试

  • 首先 在 onCreate 方法打一个断点,设置断点的方法和普通模式相同。
  • 然后 点击菜单栏 “Debugger ---> Start” 开始调试 ( 和 普通模式 步骤一样 )。

点击 附上 之后,弹窗 自动消失,然后就会自动停在 onCreate 方法中设置的断点。

2、AndroidStudio + Smalidea 动态调试 smali 代码

下载、安装 Android Studio

安装 Android Studio 时,会自动弹出 Android sdk 的下载安装界面。Android Studio 自带有 java jdk,如果不想使用自带的 Java JDK 可以自己下载

  • Android Studio 下载地址: Download Android Studio & App Tools - Android Developers
  • Smalidea:用来给 smali 下断点,单步调试,下载地址:https://github.com/JesusFreke/smalidea
  • Smali Support:setting->Plugins->Marketplace->搜索Smali Support

Android studio 配置

  • Android Studio 配置(一):https://www.cnblogs.com/qianguyihao/p/4390905.html
  • Android Studio 配置(二):https://www.cnblogs.com/qianguyihao/p/4392611.html
  • Android Studio 配置(三):gradle项目构建:https://www.cnblogs.com/xiaofengfeng/p/9133043.html

 Android Studio手动配置Gradle的方法:[Android Studio系列(五)] Android Studio手动配置Gradle的方法_androidstudio gradle_u010142437的博客-CSDN博客

(1) android sutdio第一次打开一个工程巨慢怎么办? 
(2) 手动配置Gradle Home为什么总是无效? 
(3) 明明已经下载了Gradle,配置了gradle home,为什么打开工程还是去自动下载Gradle?

Gradle 构建配置详解:Gradle 构建配置详解 | 程序员笔记

史上最全 Android build.gradle 配置详解:史上最全Android build.gradle配置详解 - 简书

在开发过程中,

  • debug 版本我们可以跟踪调试,查看 bug 等信息,
  • 但是 release 版本中只能去打 log 进行代码进行猜测,还有就是 dump 堆栈等无法与代码直接交互的方法。无源码调试 指的是在没有源代码的情况下可以对 app 进行代码调试,逆向 smali 代码,然后查看其运行逻辑。对发现 release 版本问题的过程中可以让我们更块的定位错误。

安装 smalidea 插件

从 github 下载 smalidea.zip,然后在 Android 中依次选择:

  • File ---> setting -> Plugins -> 齿轮 -> Install Plugin from Disk…-> 找到smalidea-0.06.zip

在弹出选择对话框中,找到下载好的 smalidea 压缩包,选择ok即可

方法 1:导入 APK 调试 smali

Android Studio 2022 可以直接导入apk 包就可以进行动态调试

File ---> Profile or Debug APK ,会自动生成smali进行查看

设置 Project 的 sdk:

如果是通过 "新建项目" 导入的 smali ,则不需要设置 sdk,因为 新建工程 时已经有默认的 sdk

如果是通过 " 导入已经存在的 " 方式导入 smali ,则需要设置 sdk :

选择 sdk ,这里选择 sdk  1.8

调试

连接上手机,进行debug

方法 2:反编译 apk 为 smali 进行调试

常用的反编译工具有 Apktool、AndroidKiller、jadx、jeb 等

 第一步:拿到想要 debug 的 apk。

第二步:反编译 apk 得到 smali 代码。这里使用 AndroidKiller ( AK 实际是调用 apktool 进行反编译)。

让 apk 可调式

在 Android 真机上调试程序有一个前提,就是这个apk包必须有 debuggable=true 的属性才行。

让运行在设备中的程序支持 debug。方法有几种:

  • 把设备 root 掉,修改 /default.prop 文件的 ro.debuggable=1
  • 使用 模拟器
  • 修改 apk 的 Manifest application 属性 android:debuggable="true",可以用 apktool 解出 Manifest 然后修改,接着重新打包回去。
  • 打开系统调试总开关,使用 am 命令,以调试模式启动应用。
  • Magisk 模块可以实现 app 的 debug。xposed 也有对应模块。直接搜索 "debug" 找到对应模块安装即可。 ( 推荐 )
  • 终极办法,自己编译一个 debug 版的 rom,这个稍微麻烦一点,自己编一个,想怎么玩就怎么玩。

下面只说明两种方法,

  • 一种是 修改 " AndroidManifest.xml " 实现可调试 ,
  • 另一种是 "打开系统调试总开关"

修改 " AndroidManifest.xml " 实现可调试 

修改 " AndroidManifest.xml " 实现可调试。使用 AndroidKiller 进行反编译,然后在反编译出的 AndroidManifest.xml 添加 debug 属性

如果没有这个属性的话,需要自己添加 android:debuggable="true" 然后编译安装修改后的 apk 即可。。。

修改 AndroidManifest.xml 之后,只要以调试状态启动 app 即可

命令:adb shell am start -D -n com.wizardev.testjar/.MainActivity

转发 8700 端口 到安卓 对应进程 [app_pid]。命令:adb forward tcp:8700 jdwp:446

记住这时候需要将 DDMS 关掉,不然会出现错误

方法 2:

找到启动 apk 的启动界面,然后在启动界面的 onCreate 方法的第一行添加 invoke-static {}, Landroid/os/Debug;->waitForDebugger()V 这句代码。

怎么知道程序的启动界面呢? 其实可以通过以下几种方式:

方法 1: 观察 “AndroidManifest.xml” 文件中的代码,看下图

如果图中 “1” 处的代码,那么程序启动界面的 smail 文件就是 “2” 处的名称。如上图启动界面的 smali 文件就是“MainActivity.smali”。然后在 “MainActivity.smali” 文件中的 onCreate 方法中添加等待调试的代码即可。用 am 命令,使目标程序以调试模式运行。

方法 2:通过 adb 命令来发现 apk 的启动界面,命令:adb shell dumpsys activity top

运行命令后会出现以下界面

图中用红框标记的就是启动界面的 smali 文件名。注:这种方式找到的启动界面可能不准确,因为有的 app 会有欢迎页,因此推荐用第一种方法来找 app 的启动界面。

主 Activity 中加入  invoke-static {},Landroid/os/Debug;->waitForDebugger()V

回编译 apk 并签名安装到手机,如果启动 app 出现以下界面,则说明以启动模式运行app成功。

(这步如果重新打包失败,可以安装原始包,把手机 root 配置/default.prop 的 ro.debuggable=1 开启全局调试。

然后用命令启动 Activiry : adb shell am start -D -n package属性的值/android:name属性的值  )

打开系统调试总开关

这种方法不用修改 “AndroidManifest.xml”,而且当你打开这个开关后手机中的所有 App 都是可以调试的了。但是这种方法操作起来比较复杂,而且手机必须是已经 root 过的,下面会详细描述怎么打开系统调试的总开关。

这里会介绍两种方法,第一种方法是大家普遍采用的,但是我使用采用第一种方法没有成功,于是查找资料找到了第二种方法,如果你使用第一种方法不成功,那么可以试下第二种方法。

第一种方法

  • 下载 mprop 文件 ( https://github.com/wpvsyou/mprop )
  • 依次运行一下命令设置 “ro.debuggable”
    adb push “下载mprop文件所在的位置”\mprop /data/local/tmp/
    adb shell su
    chmod 755 /data/local/tmp/mprop
    data/local/tmp/mprop
    setprop ro.debuggable 1
    /data/local/tmp/mprop -r
  • 运行 getprop ro.debuggable 命令可以查看 debuggable 的状态,显示为 1,表示更改成功。

注:这种方法在开机后设置的“debuggable”将会失效,需要重新设置

第二种方法

这种方法其实说复杂也不复杂,说不复杂呢!还是有一点复杂的。具体操作方法如下:

  • 需要手机刷入“Magisk”,下载:Releases · topjohnwu/Magisk · GitHub。Magisk是什么:简单的说就是集成了root的框架,它强大的是root权限还可以设置对其他软件隐藏。
    Magisk的强大远不止这点,想了解Magisk具有哪些功能可以自行搜索。
  • 通过Magisk安装“MagiskHide Props Config”模块,安装的方法可以看下面的动图。

安装完成之后需要重启,才能生效。

打开终端,输入以下命令

adb shell
props

会出现这个界面

然后,输入3,回车,会出现这个界面

然后,输入1,回车,出现这个界面

可以看到图中显示当前的 “ro.debuggable” 的值为0,如果要修改为1的话输入“y”,回车即可修改完成。接着终端会弹出是否重启,这时继续输入“y”重启,重启后修改的“ro.debuggable”才会生效。

经过以上5步,就可以打开系统调试的总开关,这时我们打开“Monitor”工具就可以看见当前运行的所有的所有进程了。

注:通过这种方式修改的 “ro.debuggable” 值,重启手机后不会还原,就是设置过后,手机重启后不需要再次设置。

打开系统调试的总开关后,这时通过 am 命令以调试模式启动应用,即可让目标应用处于可调式状态。

adb shell am start -D -n xxx

这里的 “xxx” 为我们要调试应用的启动界面,如我们要调试应用的启动界面为 com.wizardev.testjar/.MainActivity 则输入以下命令

adb shell am start -D -n com.wizardev.testjar/.MainActivity

这是目标应用就会以调试模式运行,处于等待调试的状态。

反编译的 smali  导入到 Android Studio 

把 project 文件夹单独复制一份,然后导入 Android Studio 中。

导入步骤:菜单栏 ---> File ---> New ---> import Project... ---> 选择Create project from existing sources,之后一直选择 next 即可

导入完成后,切换到 project 视图 ( 不是 Android 视图 )。然后选择smali目录作为资源目录

不新建项目也行,但需要新建一个 module。
将项目切换到 project 视图,将新建的项目下 app 中 src 目录下的代码删除或将新建的 module 下 src 目录下的代码删除。
将我们反编译的 smali 文件夹放入 src 目录下。
这样,就将反编译的 smali 文件导入到 AndroidStudio 目中了。

配置远程调试的选项

设置调试器:run --> edit configurations ---> + --> Remote JVM Debug,端口选择:8700

 

Project Structure(Ctrl+Shift+ALT+S),Project SDK设置为 Android API 10 Platform

远程调试配置,Run -> Edit Configuration进入Run/Dubug Configurations;Add New Configuration(+符号) -> Remote,将 5005 端口,修改为 8700 端口

smali 打断点

安装设置 debug=true 的 APK,通过 adb shell dumpsys activity top | grep --color=always ACTIVITY 在终端获取包名和页面信息。也可以通过 配置文件查看包名

在 smali 中需要断点的地方打好断点,

通过以下命令行启动进程调试等待模式:

调试模式打开 app ( 命令: adb shell am start -D -n )

adb shell am start -D -n com.qianyu.zhuceji/.MainActivity

对 apk 进行动态调试,这条命令运行后手机屏幕将会进入到调试界面,千万别点手机上弹出来的对话框(不要点Force Close),它是在等待 debug 接入

  

进入等待调试

查看 Monitor 并记住下面红框里的两个值。

新版本的 AndroidStudio 已经淘汰了 Android Device Monitor 功能,可以使用 monitor 代替 ( D:\Android\Sdk\tools 下打开 monitor.bat )

  

然后把 Android Device Monitor关掉(这里一定要关掉,因为它会占用8700端口 导致后面转发端口失败)

开启转发

C:\>netstat -aon |findstr 8700
  TCP    127.0.0.1:8700         0.0.0.0:0              LISTENING       10708
    看看有没有哪个进程占用端口,没有就直接开启端口转发: 
C:\>taskkill /PID 10708 /F
    成功: 已终止 PID 为 10708 的进程。

开启转发(这里jdwp是自己Android Device Monitor中要调试app的Online值,tcp为debug值)
C:\>adb forward tcp:8700 jdwp:3669
8700

C:C:\>

获取运行 apk 的进程(pid):adb shell ps | grep 包名

  • 示例:adb shell ps | findstr "zhuceji" ,如下图所示,可以看到 pid 是 3170

端口映射: adb forward tcp:8701 jdwp:<pid>

  • 执行:adb forward tcp:8701 jdwp:3170    建立端口转发,即把端口 8701 上面的信息通过 jdwp 转发到 pid 是 3170 上面

开始等待调试

在 Android Studio 附加、动态 调试 smali

图二

此时,已经 Attach 到进程中,可以快乐的调试了。通过断点可以查看内存的信息。

打好断点之后。然后 Run --> Debug 'zhuceji_smail' 进行调试。

android studio 已经进入debug模式了  按F8执行下一步,F9运行程序 

以上方法经常会出现端口转发问题,现象就是 android studio debug 的TCP端口  与 设备应用的端口无法绑定,导致启动debug 无法启动。

解决方法:直接 attach 一个进程

步骤: 菜单栏 ---> run ---> attach Process

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/387636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 236.二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

Modbus协议初探(C#实现)

由于作者水平有限&#xff0c;如有写得不对得地方请指正 趁着今天休息&#xff0c;就折腾一下Modbus协议&#xff0c;之前零零散散的看过几篇博客&#xff0c;听说搞上位机开发的要会这个协议&#xff0c;虽然我不是搞上位机开发的&#xff0c;但个人对这个比较感兴趣。按照我个…

开发一个看番app[樱花动漫移动端app]

使用react-native开发&#xff0c;功能&#xff1a; 支持看番支持历史记录浏览支持追番 项目地址: https://github.com/HGGshiwo/Sakura 界面&#xff1a; 首页分类用户界面播放界面历史记录搜索界面全部动漫追番

OpenAI Whisper and ChatGPT 语音助手

OpenAI Whisper and ChatGPT ASR Gradio Web UI一 环境准备1.1 python1.2 windows二 导入所需要的包三 加载模型四 定义openai和whisper接口五 生成Gradio Web UI麦克风输入&#xff0c;展示三种结果输入ASR结果输出文本输出TTS结果 一 环境准备 1.1 python gradio3.19.1 gTT…

ubuntu 如何搭建git远程仓库

ubuntu 安装git sudo apt-get install git配置用户名和邮箱 git config --global user.name “xxx” git config --global user.email “邮箱地址”关于远程仓库 Git是分布式版本控制系统&#xff0c;同一个Git仓库&#xff0c;可以分布到不同的机器上。这就需要一台电脑充当…

打印名片-课后程序(Python程序开发案例教程-黑马程序员编著-第一章-课后作业)

实例2&#xff1a;打印名片 名片是标示姓名及其所属组织、公司单位和联系方法的纸片&#xff0c;也是新朋友互相认识、自我介绍的快速有效的方法。本实例要求编写程序&#xff0c;模拟输出效果如图1所示的名片。 图1 名片样式 实例目标 掌握print()函数的用法 实例分析 名片…

【办公类-19-01-02】办公中的思考——Python,统计教职工的姓名中那些字最多?

背景需求&#xff1a;上一篇计算了教职工的姓氏谁最多&#xff0c;col[0]]这一篇统计教职工的&#xff08;姓氏名字&#xff09;里面哪些字出现最多。材料准备&#xff1a;1、下载所有员工名单写代码。py 包含”姓氏名字“的重字率统计from pandas import DataFrame, Series im…

DevOps践行

DevOps 是开发 (Dev) 和运营 (Ops) 的复合词&#xff0c;它将人、流程和技术结合起来&#xff0c;不断地为客户提供价值。 DevOps 对团队意味着什么&#xff1f; DevOps 使以前孤立的角色&#xff08;开发、IT 运营、质量工程和安全&#xff09;可以协调和协作&#xff0c;以生…

二次封装element plus (el-select-v2远程搜索组件)

根据项目需求,需要给每个对应的搜索字段进行 远程搜索项目中有跟多地方都需要使用,所以进行二次封装会很方便.创建一个ElSelectV2文件夹> index.vue<template><div><el-select-v2v-model"valueName"filterableremote:remote-method"remoteMet…

tomcat启动流程以及线程池配置

一、启动流程 二、 线程池配置 Tomcat的maxConnections、maxThreads、acceptCount三大配置&#xff0c;分别表示最大连接数&#xff0c;最大线程数、最大的等待数&#xff0c;可以通过application.yml配置文件来改变这个三个值&#xff0c;一个标准的示例如下&#xff1a; se…

Linq的底层原理探讨

前言有一篇文章ABP-引入SqlSugar很多人都在催促我&#xff0c;出下一章因为工作忙一直没写。现在开第二节课Linq的底层原理探讨。一起探讨完&#xff0c;看看有没有引起SqlSugar的新思路。这文章叫linq的底层原理。从哪里开始说呢&#xff1f;Linq To SQL、Linq To Objects、Li…

计算机的学习路线

本文是介绍如何成为一个Geek&#xff0c;一个真正的计算机高手。 适合有成为IT领域技术大牛的人参考。 写给大一新生和所有向深耕IT领域的人&#xff0c;避免走一些弯路。 第一门入门的必备功课-语法与算法 什么是计算机&#xff1f; 用来做运算的机器 电子计算机在运算方面…

[1.3_1]计算机系统概述——操作系统的运行机制

文章目录第一章 计算机系统概述操作系统的运行机制前提知识&#xff1a;程序是如何运行的内核程序与应用程序特权指令与非特权指令内核态与用户态小结第一章 计算机系统概述 操作系统的运行机制 操作系统的运行机制&#xff0c;也就是操作系统在计算机上是怎样运行的问题。 操…

Go语言的条件控制语句及循环语句的学习笔记

一、Go的条件控制语句 Go 语言提供了以下几种条件判断语句&#xff1a; 语句描述if 语句if 语句 由一个布尔表达式后紧跟一个或多个语句组成。if…else 语句if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。if 嵌套语句你可以在 if 或…

C++概览:工具链、基础知识、进阶及总结

本篇写给C初学者&#xff0c;作为概览&#xff0c;文中仅包含各方面基础知识&#xff0c;无深入分析。 C基础概念简介 C编译过程示意图 关键词&#xff1a;源文件、预编译、编译、汇编、链接 C工具链总结 cmake项目工程文件是一种中介工程文件&#xff0c;可以转化成其他…

Python+Qt指纹录入识别考勤系统

PythonQt指纹录入识别考勤系统如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01;前言这篇博客针对<<PythonQt指纹录入识别考勤系统>>编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学…

如何在 OpenEuler 系统中安装 Docker

Docker 是一种流行的开源容器化平台&#xff0c;它能够将应用程序与其依赖项打包成可移植的容器&#xff0c;从而简化了应用程序的部署和管理。本文将介绍在 OpenEuler 系统中安装 Docker 并使用 Docker 容器控制 5G 模块的具体步骤。 安装 Docker 安装 Docker 的具体步骤如下…

react动态路由组件的封装

react动态路由组件的封装 我这篇比较全面 首先下载包 npm i react-router-dom5 这里为什么要用5的版本为啥不用最新的&#xff0c;原因在于老版本跟新版本写法不一样 老版本 import { HashRouter, Route, Switch, Redirect } from react-router-dom;render() {return (<Ha…

JavaEE——何为线程及创建线程

文章目录一、认识线程1. 线程的概念2. 出现多线程的原因3. 进程与线程4. 对多线程的详细解释二、初次实现多线程代码1. 初步了解2. 使用 Java 中的工具查看当前的所有线程3. Java 中创建线程的多种方式一、认识线程 1. 线程的概念 所谓线程&#xff0c;就是指在一个 ‘执行流…

机器学习、数据挖掘和统计模式识别学习(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 机器学习是让计算机在没有明确编程的情况下采取行动的科学。在过去的十年中&#xff0c;机器学习为我们提供了自动驾驶汽车&…