Thinker 使用详解

article/2025/8/21 8:01:06

文章目录

      • Tinker基本介绍
        • 它主要包含以下几部分:
        • 为什么使用 Tinker
      • Tinker 执行原理及流程
      • 简单的使用 Tinker
        • 1,在项目的gradle.properties 中添加
        • 2,在项目的 gradle中添加:
        • 3,在 app 中的 gradle 中添加:
        • 4,接着进行初始化,新建一个类用于管理 tinker 的初始化
        • 5,自定义 application 继承自 ApplicationLike
        • 6,配置 tinker
        • 7,进行测试,打包
        • 8,创建补丁文件
        • 9,加载补丁文件,修复bug
      • 在项目中使用 Tinker
      • Tinker 高级用法
      • 总结一下

二次补充,直接用 bugly吧,基于 tinker,使用简单,方便集成

Tinker基本介绍

Tinker 是微信官方的 Andriod 热补丁解决方案,它支持动态下发代码,so库以及资源,让应用在不需要安装的情况下实现更新,当然,你也可以使用 Thinker 来更新你的插件。

它主要包含以下几部分:

​ 1,gradle 编译插件 tinker-patch-gradle-plugin:主要用于在 as 中直接完成 patch 文件的生成

​ 2,核心 sdk 库 tinker-android-lib :核心库,为应用层提供的 api

​ 3,非 gradle 编译用户的命令行版本,tinker-path-cli.jar :为 eclipse 做的一个工具

为什么使用 Tinker

​ 当前市面上 热修复的解决方案很多,但是他们都有一些无法解决的问题,但是 Tinker 的功能是比较全面的。

TinkerQZoneAndFixRobust
类替换yesyesnono
So 替换yesnonono
资源替换yesyesnono
全平台支持yesyesyesyes
即时生效nonoyesyes
性能损耗较小较大较小较小
补丁包大小较小较大一般一般
开发透明yesyesnono
复杂度较低较低复杂复杂
gradle 支持yesnonono
Rom 体积较大较小较小较小
成功率较高较高一般最高

Tinker 执行原理及流程

​ 基于 android 原生的 ClassLoader ,开发了自己的 ClassLoader,通过自定义的 ClassLoader去加载 patch 文件中的字节码

​ 基于 android 原生的 aapt,开发了自己的 aapt ,加载 资源文件

​ 基于 Dex 文件的格式,研发了 DexDiff 算法,通过 DexDiff 算法比较两个 apk 文件中的差异

简单的使用 Tinker

1,在项目的gradle.properties 中添加

# tinker版本号 ,控制版本,以下版本已经兼容 9.0
TINKER_VERSION=1.9.14
TINKERPATCH_VERSION=1.2.14

2,在项目的 gradle中添加:

classpath("com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}")

3,在 app 中的 gradle 中添加:

   compileOnly("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }annotationProcessor("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }// tinker 的核心 sdk 库implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") { changing = true }

4,接着进行初始化,新建一个类用于管理 tinker 的初始化

/*** 对 TinkerManager api 做一层封装*/
public class TinkerManager {/*** 是否初始化*/private static boolean isInstalled = false;private static ApplicationLike mApplike;/*** 完成 Tinker初始化** @param applicationLike*/public static void installTinker(ApplicationLike applicationLike) {mApplike = applicationLike;if (isInstalled) {return;}//完成 tinker 初始化TinkerInstaller.install(mApplike);isInstalled = true;}public static void loadPatch(String path) {if (Tinker.isTinkerInstalled()) {TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), path);}}/*** 通过 ApplicationLike 获取 Context*/private static Context getApplicationContext() {if (mApplike != null) {return mApplike.getApplication().getApplicationContext();}return null;}}

5,自定义 application 继承自 ApplicationLike

//通过 DefaultLifeCycle 注解来生成我们程序中需要用到的 Application
@DefaultLifeCycle(application = ".MyTinkerApplication",flags = ShareConstants.TINKER_ENABLE_ALL,loadVerifyFlag = false)
public class CustomTinkerLike extends ApplicationLike {public CustomTinkerLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);}@Overridepublic void onBaseContextAttached(Context base) {super.onBaseContextAttached(base);//初始化TinkerManager.installTinker(this);}
}

为什么需要继承 ApplicationLike,而不直接在 Application 中初始化呢?

​ 因为 ApplicationLike 需要对 Application 的生命周期进行监听, 所以他通过 ApplicationLike 进行代理。通过这个代理可以完成对 Application 的生命周期监听,然后在不同的生命周期做一些别的工作,因为Tinker 初始化非常复杂,所用用 ApplicationLike 进行了代理,这样使用就非常简单了!

​ 注意上面的注解:通过这个注解可以生成 需要在程序中进行添加的 application

public class MyTinkerApplication extends TinkerApplication {public MyTinkerApplication() {super(15, "com.testdemo.www.tinker.CustomTinkerLike", "com.tencent.tinker.loader.TinkerLoader", false);}
}

​ 上面这个就是通过注解生成的。我们需要将他添加的 AndroidManifest 中。

6,配置 tinker

//buildDir 代表的是 app 目录下 build 文件夹,
// 如果创建成果,他会在 build 文件夹中创建 bakApk文件夹,存放 old.apk
def bakPath = file("${buildDir}/bakApk") //指定基准文件存放位置ext {tinkerEnable = truetinkerID = "1.0"tinkerOldApkPath = "${bakPath}/"tinkerApplyMappingPath = "${bakPath}/"tinkerApplyResourcePath = "${bakPath}/"
}//是否启用 tinker
def buildWithTinker() {return ext.tinkerEnable
}
// old 路径
def getOldApkPath() {return ext.tinkerOldApkPath
}
// 混淆文件路径
def getApplyMappingPath() {return ext.tinkerApplyMappingPath
}
// 资源文件路径
def getApplyResourceMappingPath() {return ext.tinkerApplyResourcePath
}
// id
def getTinkerIdValue() {return ext.tinkerID
}if (buildWithTinker()) {//启用 tinkerapply plugin: 'com.tencent.tinker.patch'//所有 tinker 相关的参数配置tinkerPatch() {oldApk = getOldApkPath() // old.apk 路径ignoreWarning = false //不忽略警告,如果警告取消生成patchuseSign = true  // 强制 patch 文件使用签名tinkerEnable = buildWithTinker() //指示是否启用 tinkerbuildConfig() {applyMapping = getApplyMappingPath() // 指定old.apk 打包时所使用的的混淆文件applyResourceMapping = getApplyResourceMappingPath() // 指定 old.apk 资源文件tinkerId = getTinkerIdValue() //指定 TinkerIdkeepDexApply = false //一般置为 false,true:生成patch 的时候会根据 dex 文件的分包去动态的编译 patch 文件}dex() {dexMode = "jar"  //jar 是配到14以下,会将dex压缩为jar文件,然后进行处理,体积小row只能在14以上使用,直接对 dex 文件处理pattern = ["classes*.dex", "assets/secondary-dex-?.jar"]//指定 dex 文件位于哪些牡蛎loader = ["com.testdemo.www.tinker.MyTinkerApplication"] //指定加载patch文件时所用到的类}//工程中的 jar 和 solib {pattern = ["libs/*/*.so"]}res { //指定 tinker 可以修改的资源文件路径pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]ignoreChange = ["assets/sampple_meta.txt"] //制定不受影响的资源路径,即时修改了这个资源文件,也不会被打入 patchlargeModSize = 100 //资源修改大小默认值}
//-----------------必须项配置完成-------------------------------------//patch的介绍packageConfig {//补丁加载完成后通过 key 可以拿到这些 valueconfigField("patchMessage", "fix 1.0 version's bugs")configField("patchVersion", "1.0")}//使用压缩sevenZip {zipArtifact = "com.tencent.mm:SevenZip:1.1.10"}}List<String> flavors = new ArrayList<>()project.android.productFlavors.each { flavor ->flavors.add(flavor.name)}
boolean hasFlavors = flavors.size() > 0/*** 复制基准包和其它必须文件到指定目录*/android.applicationVariants.all { variant ->/*** task type, you want to bak*/def taskName = variant.namedef date = new Date().format("MMdd-HH-mm-ss")tasks.all {if ("assemble${taskName.capitalize()}".equalsIgnoreCase(it.name)) {it.doLast {copy {def fileNamePrefix = "${project.name}-${variant.baseName}"def newFileNamePrefix = hasFlavors ? "${fileNamePrefix}" : "${fileNamePrefix}-${date}"def destPath = hasFlavors ? file("${bakPath}/${project.name}-${date}/${variant.flavorName}") : bakPathfrom variant.outputs[0].outputFileinto destPathrename { String fileName ->fileName.replace("${fileNamePrefix}.apk", "${newFileNamePrefix}.apk")}from "${buildDir}/outputs/mapping/${variant.dirName}/mapping.txt"into destPathrename { String fileName ->fileName.replace("mapping.txt", "${newFileNamePrefix}-mapping.txt")}from "${buildDir}/intermediates/symbols/${variant.dirName}/R.txt"into destPathrename { String fileName ->fileName.replace("R.txt", "${newFileNamePrefix}-R.txt")}}}}}}}

注意 ext 中:

tinkerEnable = true //是否启用 tinker
tinkerID = “1.0” // id ,线上的版本 id 和 补丁包的 tinkerID 必须相等

详细的说明

7,进行测试,打包

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private static final String FILE_END = ".apk";private String mPatchDir;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建路径mPatchDir = getExternalCacheDir().getAbsolutePath() + "/tpatch/";File file = new File(mPatchDir);file.mkdir();findViewById(R.id.btn).setOnClickListener(this);}@Overridepublic void onClick(View v) {//加载补丁包TinkerManager.loadPatch(getPatchName());}//拼装一个路径private String getPatchName() {return mPatchDir.concat("tinker").concat(FILE_END);}}

看一下布局

<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><androidx.appcompat.widget.AppCompatButtonandroid:id="@+id/btn"android:layout_width="match_parent"android:layout_height="50dp"android:layout_marginTop="20dp"android:text="加载 PATCH 包"android:textSize="20sp"tools:ignore="HardcodedText" /></androidx.appcompat.widget.LinearLayoutCompat>

接着我们就可以进行打包了,注意不能是 debug 。是需要签名的。打包完成后会在 build 文件下生成 bakApk 文件夹,里面就是打包的 apk。
在这里插入图片描述

然后把这个apk安装到手机上即可。

8,创建补丁文件

创建补丁文件的时候需要线上的 apk。所以在这里 我们将刚才打包的 apk 名字复制下来,然后放在build.gradle 中的 ext 中,如下所示:
在这里插入图片描述
这里的路径就是 build 中 bakApk 中的文件,第一个是 apk,第二个是混淆路径,因为我没有使用混淆,所以在上面打包后就没有混淆文件。第三个对应资源文件。注意这里一定要填正确,否则会导致不能生成补丁文件。弄完之后同步一下。

接着就可以修复bug了。这里我们进行模拟一下。

<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><androidx.appcompat.widget.AppCompatButtonandroid:id="@+id/btn"android:layout_width="match_parent"android:layout_height="50dp"android:layout_marginTop="20dp"android:text="加载 PATCH 包"android:textSize="20sp"tools:ignore="HardcodedText" /><TextViewandroid:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:text="我是被修复的bug"android:textSize="25sp" /></androidx.appcompat.widget.LinearLayoutCompat>

修改了一下布局,添加了一个 TextView。

接着就需要使用 tinker 插件生成补丁了。如下

在这里插入图片描述

点击 tinkerPatchRelease 即可生成 补丁包,如果出现 IO 异常,可以删除 build 文件夹中除过 bakApk 文件以外的所有文件,可能是有冲突。

或者是 出现 config 的错误:则在 gradle 的 android 包下添加如下:

 signingConfigs {config {storeFile file('C:\\Users\\Administrator\\Desktop\\345\\Project\\Tinker\\keystore.jks')storePassword '123456789'keyAlias = 'key0'keyPassword '123456789'}}

因为使用 tinker 插件打包的时候也需要 key 和 密码等。

最后生成的结果如下

在这里插入图片描述

9,加载补丁文件,修复bug

其中 patch_signed.apk 就是我们需要的补丁包。我们需要将补丁包复制到的我们程序中定义的路径中:

在这里插入图片描述

这里我用的电脑直接复制到手机中了

然后点击加载 加载 PATCH 包 接着程序会直接退出。当你再次打开的时候就会发现你添加的 TextView 已经显示出来了,最终的结果如下:

在这里插入图片描述

​ 经过上面几步,我们就已经完成了一个从本地加载的热修复

在项目中使用 Tinker

​ 当然了,我们不可能一直从本地加载补丁文件。所以我们需要对加载 补丁文件进行修改一下。

​ 新建一个 服务。在服务中我们会进行请求服务器是否有新的补丁,如果有补丁就下载到指定的目录中,然后进行加载补丁文件。

public class TinkerService extends Service {/*** 文件后缀名*/private static final String FILE_END = ".apk";/*** 下载 patch 文件信息*/private static final int DOWNLOAD_PATCH = 0x01;/*** 检查是否有 patch 更新*/private static final int UPDATE_PATCH = 0x02;/*** patch 要保存的文件夹*/private String mPatchFileDir;/*** patch 文件保存路径*/private String mFilePath;/*** 服务器 patch 的信息*/private BasePatch mBasePatchInfo;@SuppressLint("HandlerLeak")private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_PATCH:checkPatchInfo();break;case DOWNLOAD_PATCH:downloadPatch();break;}}};private void downloadPatch() {//下载补丁文件mFilePath = mPatchFileDir.concat("tinker").concat(FILE_END);//.....下载完成,进行加载TinkerManager.loadPatch(mFilePath);//加载完成后终止服务stopSelf();}@Overridepublic void onCreate() {super.onCreate();init();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//检查是否有 patch 更新mHandler.sendEmptyMessage(UPDATE_PATCH);return START_NOT_STICKY;}private void init() {mPatchFileDir = getExternalCacheDir().getAbsolutePath() + "/tPatch/";File patchFileDir = new File(mPatchFileDir);try {if (!patchFileDir.exists()) {//文件夹不存在则创建patchFileDir.mkdir();}} catch (Exception e) {e.printStackTrace();//无法创建文件,终止服务stopSelf();}}@Overridepublic IBinder onBind(Intent intent) {return null;}/*** 检查是否有更新*/private void checkPatchInfo() {//.....网络请求获取是否更新补丁文件,不更新就终止服务//下载补丁文件mHandler.sendEmptyMessage(DOWNLOAD_PATCH);}
}

Tinker 高级用法

  • Tinker 如何支持多渠道打包

    首先在项目中集成多渠道,我使用的是 walle,集成的方式非常简单:

    添加插件

     classpath 'com.meituan.android.walle:plugin:1.1.6'
    

    在 app 的 build.gradle 中引入插件,设置依赖,进行配置

  apply plugin: 'walle'android{......walle {// 指定渠道包的输出路径apkOutputFolder = new File("${project.buildDir}/outputs/channels");// 定制渠道包的APK的文件名称apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}-${versionCode}.apk';// 渠道配置文件channelFile = new File("${project.getProjectDir()}/channel")}}dependencies {implementation 'com.meituan.android.walle:library:1.1.6'}

然后在 app 中新建一个channel 文件,不要指定任何后缀,里面写入渠道名称即可
在这里插入图片描述

这样多渠道就配置完了。

使用多渠道后打包需要用命令行或者插件来执行,这里使用插件的方式,如下:
在这里插入图片描述
一种是 debug,一种是 release。点击 replace就会生成相应的渠道文件,如下:

在这里插入图片描述

可以看到渠道已经生成了。在bakApk 中也生成了 基准包,这个 apk 不是用来发布的,而是用来生成补丁用的。生成补丁的方式就和上面讲的一样了。

将渠道文件中的 apk 发布后,出现 bug 。使用基准包生成 补丁文件,然后放在服务器中,进行下发即可。

如果使用 android 自带的渠道,需要每个渠道apk 都要生成补丁文件,而 使用 walle 只需要一个补丁即可,而且 使用 walle 生成渠道apk 的速度非常快。

我们可以app中获取渠道的信息,并且传给 友盟统计,这样非常方便,如下:

//当前渠道
String channel = WalleChannelReader.getChannel(getApplication());
UMConfigure.init(getApplication(), "*********", channel, UMConfigure.DEVICE_TYPE_PHONE, "");
  • 如何自定义 Tinker 行为

​ 1,自定义TinkerResultService 改变 patch 安装成功后行为

​ 一般情况下 patch 安装后 tinker 会杀掉进程,所以我们才会看到 patch 加载完成后程序闪退的问题,我们可以通过 重写 DefaultTinkerResultService 来自定义这个行为,如下:

​ 在 DefaultTinkerResultService 的 onPatchResult 方法中 判断了 patch 安装成功后的行为。如下:

 @Overridepublic void onPatchResult(PatchResult result) {......// only main process can load an upgrade patch!if (result.isSuccess) {//加载完成后删除 patch 文件deleteRawPatchFile(new File(result.rawPatchFilePath));//如果成功,则杀掉进程if (checkIfNeedKill(result)) {android.os.Process.killProcess(android.os.Process.myPid());} else {TinkerLog.i(TAG, "I have already install the newly patch version!");}}}

​ 从源码可以很清楚地看到杀掉进程。我们可以通过继承的方式来解决如下:

public class CustomResultService extends DefaultTinkerResultService {private static final String TAG = "CustomResultService";//返回 patch 文件的安装结果@Overridepublic void onPatchResult(PatchResult result) {......// if success and newPatch, it is nice to delete the raw file, and restart at once// only main process can load an upgrade patch!if (result.isSuccess) {deleteRawPatchFile(new File(result.rawPatchFilePath));if (checkIfNeedKill(result)) {TinkerLog.e(TAG, "patch加载成功,重启生效");} else {TinkerLog.i(TAG, "I have already install the newly patch version!");}}}
}

​ 其实和源码中差不多,只是改了一句而已。加载成功后打印 log 即可。

​ 弄完以后,我们需要修改一下初始化方法。我们是在 TinkerMananger 的 installTinker 方法中初始化的,下面我们进行修改,如下:

 LoadReporter loadReporter = new DefaultLoadReporter(applicationLike.getApplication());PatchReporter patchReporter = new DefaultPatchReporter(applicationLike.getApplication());PatchListener patchListener = new DefaultPatchListener(applicationLike.getApplication());AbstractPatch upgradePatchProcessor = new UpgradePatch();//完成 tinker 初始化TinkerInstaller.install(applicationLike,loadReporter,patchReporter,patchListener,CustomResultService.class,upgradePatchProcessor);

​ CustomResultService 就是我们自定义的。将他传入即可,注意这是一个服务,必须在 AndroidManifest.xml 中注册

​ 结果如下:

2019-11-21 16:59:42.335 6337-6404/? E/CustomResultService: patch加载成功,重启生效

2,自定义 PatchListener 监听 patch receiver 事件

​ 也就是上面代码中的 DefaultPatchListener ,继承他即可,使用它可以完成 patch 的校验

​ 例如,从服务器拉取补丁时服务器返回一个 md5, 我们可以在这个里面进行判断。

/*** 1,校验 patch 文件是否合法,2,启动 Service 去安装 patch*/
public class CustomPatchListener extends DefaultPatchListener {private String currentMD5;public void setCurrentMD5(String currentMD5) {this.currentMD5 = currentMD5;}public CustomPatchListener(Context context) {super(context);}@Overrideprotected int patchCheck(String path, String patchMd5) {if (Utils.isFileMD5Matched(path,currentMD5)){return ShareConstants.ERROR_PATCH_DISABLE;}return super.patchCheck(path, patchMd5);}
}

​ 同样的要将初始化方法中第四个参数改为这个类对象

3,其他的自定义

 //加载补丁文件加载时的异常监听LoadReporter loadReporter = new DefaultLoadReporter(applicationLike.getApplication());//补丁文件合成阶段的异常监听,PatchReporter patchReporter = new DefaultPatchReporter(applicationLike.getApplication());PatchListener patchListener = new DefaultPatchListener(applicationLike.getApplication());AbstractPatch upgradePatchProcessor = new UpgradePatch();//完成 tinker 初始化TinkerInstaller.install(applicationLike,loadReporter,patchReporter,patchListener,CustomResultService.class,upgradePatchProcessor);

​ 通过继承 loadReporter 和 patchReporter 可以实现异常的监听。当然还有一下其他的,可以去官网查看。


总结一下

热修复这块基本的用法基本都已经掌握了。总结如下:

​ 在学习任何一个东西时一定要先看官方的文档,不然吃大亏,就和我一样,搞了好多天。。如果项目中需要用到热修复,不要着急的直接选使用哪个,要从需求和一下客观因素来觉得要使用那种,在满足需求的条件下哪个学习的成本低,就学哪个。学习成本差不多的建议选择大公司的解决方案。

​ 关于tinker的使用,例如上面这种就比较麻烦。但是有了 bugly 以后感觉挺简单的。毕竟也是免费的。tinker 使用的是冷启动,下发一次补丁需要十多分钟,撤回的话没怎么测。但是配合 walle 一起使用效果还是挺好的。

​ 在使用 bugly 的时候发现在有些手机上使用失败的问题。例如我的小米6。。。在 bugly 后台上传 补丁包一直显示 版本对应不上。我还以为是代码问题,结果改代码改了一两天。。最后用了一个模拟器居然成功了。。无奈啊

​ 注意热修复的作用不是替代版本的迭代。他只是为了在线上的 app 出现问题后的一种解决方式。按照一般流程重新进行版本的迭代就会浪费大量的时间,而且还指不定用户会不会更新。因为如此,所以才有了热修复。但是不能将他和迭代混为一谈。

​ 关于上面 tinker 的用法我写了一个demo,demo中也集成了walle和友盟统计。bugly就不传了,官方文档非常详细。但是注意文档上的依赖版本不是最新的。这个亏我已经吃了。。。

​ 其实学完以后才发现这种用法已经比较老了。所以我还是觉定用 bugly。他内部也是用的 tinker ,使用起来比较简单,当前一定要认真看文档,比如说我。。。吃了不少亏


参考:慕课网视频


http://chatgpt.dhexx.cn/article/wgZ4iAqe.shtml

相关文章

python界面编程-thinker

一、介绍 thinker是python内置界面库不需要额外安装 二、控件使用 1、窗口 import tkintertop tkinter.Tk()#创建窗口 top.mainloop()#消息循环2、按钮 from tkinter import *def button_event():print("按钮按下\n")return#创建窗口 main_window Tk() #设置窗口…

python thinker(菜单,滚动条,回调函数,对话框)

菜单menu from tkinter import * root Tk() def lab():label0Label(root,text"hello world")label0.grid(column0) root.geometry("800x480")#窗口大小menu0Menu(root)#参数是父级控件 for x in [文件,编辑,视图]:menu0.add_command(labelx,commandlab)#…

永恒之蓝(勒索病毒)

1、要有一台靶机和一台攻击机&#xff0c;这里的攻击机为kali&#xff0c;靶机为Windows2008。 2、添加一个新的网卡&#xff0c;防止病毒传播到主机。 1、添加网卡&#xff1a; 注意&#xff1a;这里添加的子网ip不能和前面的重复。 3、给虚拟机设置网卡。 两台虚拟机要设置为…

老生常谈,永恒之蓝-winxp

老生常谈&#xff0c;永恒之蓝-winxp 环境说明&#xff1a; 攻击机&#xff1a;kali 靶机&#xff1a;windows xp sp2 靶机开放服务&#xff1a;无&#xff0c;IE浏览器版本 6.0 信息收集&#xff1a; 扫描当前网段存活主机&#xff0c;发现目标主机&#xff1a;IP&#xf…

msf渗透测试学习-与永恒之蓝漏洞案例

MSF是Metasploit Framework的缩写&#xff0c;是一款广泛使用的渗透测试工具&#xff0c;具有强大的攻击功能。它提供了一个模块化的平台&#xff0c;通过将各种攻击载荷、漏洞利用和辅助工具组装在一起&#xff0c;可用于模拟各种攻击&#xff0c;测试系统安全性&#xff0c;也…

永恒之蓝--Windows7

永恒之蓝是在Windows的SMB服务处理SMB v1请求时发生的漏洞&#xff0c;这个漏洞导致攻击者在目标系统上可以执行任意代码。通过永恒之蓝漏洞会扫描开放445文件共享端口的Windows机器&#xff0c;无需用户任何操作&#xff0c;只要开机上网&#xff0c;不法分子就能在电脑和服务…

win7永恒之蓝

一 使用msfconsole命令开启MSF&#xff0c;并使用search命令搜索永恒之蓝模块 search ms17-010 二 &#xff1a;使用搜索出来的第三个模块来进行探测目标是否存在永恒之蓝漏洞&#xff0c;并设置好以下参数进行扫描测试 >>>use auxiliary/scanner/smb/smb_ms17_010 …

永恒之蓝从渗透的复现

永恒之蓝又称为勒索病毒&#xff0c;同样这个漏洞成为了黑客现在训练的好方式&#xff08;记住千万不可以攻击别人的电脑&#xff09;&#xff0c;这个漏洞在win7中十分常见&#xff0c;而永恒之蓝对应的是445端口&#xff0c;所以说我们将用win7虚拟机&#xff08;受害者&…

永恒之蓝(Eternal Blue)复现

永恒之蓝介绍 什么是永恒之蓝 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子通过改造“永恒之蓝…

kali与永恒之蓝

kali永恒之蓝攻击 写在前面一、永恒之蓝是何方神圣&#xff1f;二、神马是SMB协议&#xff1f;三、MSF四、攻击步骤1、攻击主机与靶机配置2、攻击步骤 五、种植后门 写在前面 这是我的第一篇CSDN博客&#xff0c;最近又参加了一个CTF比赛&#xff0c;当然&#xff0c;纯属兴趣爱…

利用虚拟机复现漏洞 “永恒之蓝”

利用虚拟机复现漏洞“永恒之蓝” 攻击&#xff1a;kali Linux 2020.3 靶机&#xff1a;Windows Server 2008 R2 x64 下面详细讲述测试的过程。 —— —— “ 永恒之蓝 ”简介 利用 Windows 系统的 SMB 漏洞可以获取系统最高权限。于 2017 年在全球的范围内大面积爆发&#…

永恒之蓝简介

永恒之蓝是指2017年4月14日晚&#xff0c;黑客团体Shadow Brokers&#xff08;影子经纪人&#xff09;公布一大批网络攻击工具&#xff0c;其中包含“永恒之蓝”工具&#xff0c;“永恒之蓝”利用Windows系统的SMB漏洞可以获取系统最高权限。5月12日&#xff0c;不法分子通过改…

永恒之蓝-永恒之蓝漏洞(linux)

扫描存活主机 fping -a -g 192.168.52.1 192.168.56.254 &#xff0c;因为kali是192.168.52.134&#xff0c;所以win2003是192.168.52.133 像192.168.52.2或者192.168.52.1这种不用管&#xff0c;一般是网关 开启msfconsole 搜索载荷&#xff0c;永恒之蓝的载荷是ms17_010 …

永恒之蓝漏洞复现

一&#xff0c;永恒之蓝 一、漏洞简介\n1、永恒之蓝介绍:\n永恒之蓝漏洞&#xff08;MS17-010&#xff09;&#xff0c;它的爆发源于 WannaCry 勒索病毒的诞生&#xff0c;该病毒是不法分子利用NSA&#xff08;National Security Agency&#xff0c;美国国家安全局&#xff09…

永恒之蓝靶场

声明&#xff1a;本文仅限交流学习使用,请勿使用在任何非法商业活动,禁止用于非法用途。否则后果自负。如有侵权,请告知删除,谢谢! 在虚拟机上搭建win7环境&#xff08;靶机&#xff09; 攻击者kali2021版: 模拟永恒之蓝攻击过程的话&#xff0c;需要win7&#xff08;靶机&…

永恒之蓝复现

目录 1.知识点&#xff1a; 2.前提准备 3.复现 1.知识点&#xff1a; &#xff08;永恒之蓝适应低版本的电脑没有打ms17_010的补丁&#xff0c;现在win7以上的高版本已经不可以使用&#xff09; 百度百科&#xff1a;永恒之蓝是指2017年4月14日晚&#xff0c;黑客团体Shadow…

永恒之蓝MS17-010漏洞复现

永恒之蓝漏洞复现 永恒之蓝漏洞简介准备工作命令功能查询靶机IP地址Nmap工具Msf框架相关搜索指令如下设置扫描对象扫描对方是否存在445端口开始攻击 设置攻击载荷设置攻击机及靶机攻击成功简单演示攻击结束 永恒之蓝漏洞简介 本次漏洞复现主要展示如何复现一次永恒之蓝漏洞攻击…

kali之永恒之蓝使用流程(操作全套步骤)

第一步需要kali系统的电脑和win7系统电脑的ip的地址在同一网段&#xff0c;互相之间可以ping通。 第二步关闭win7系统的防火墙。 往往失败就是这两部分的错误。 下边开始进入正题。 打开我们的kali系统&#xff0c;永恒之蓝控制版面开启指令 &#xff1a;msfconsole 小马图…

网络攻防——永恒之蓝

永恒之蓝 1.引言2.永恒之蓝定义3.SMB协议3.windows7版本说明4.攻击实例4.1攻击者和被攻击者展示4.2详细攻击过程4.3接下来尝试攻击一下windows10 5.参考文献 1.引言 让一个不爱学习的人整天蒙英语题&#xff0c;听张宇的视频实在是枯燥了点&#xff0c;于是决定看看网安&#x…

Kali--MSF-永恒之蓝详解(复现、演示、远程、后门、加壳、修复)

目录 一、永恒之蓝概述 二、SMB协议 三、准备工作 四、漏洞复现 1、主机发现 2、端口扫描 3、利用模块 五、演示功能 1.获取cmd 2.捕获屏幕 3.上传文件 4.下载文件 5.远程登录 6.上传后门 7.免杀加壳 8.运行wannacry 9.清除日志 六、预防方案 1.打开防火墙 …