当前位置: 首页 > article >正文

Android基础彻底解析-APK入口点,xml,组件,脱壳,逆向

第一章:引言与背景

Android逆向工程,作为一种深入分析Android应用程序的技术,主要目的就是通过分析应用的代码、资源和行为来理解其功能、结构和潜在的安全问题。它不仅仅是对应用进行破解或修改,更重要的是帮助开发者、研究人员和安全人员发现并解决安全隐患。
本文主要对整个安卓逆向入门的体系进行整理,解决一些安卓逆向时候的痛点问题!每个知识点都会有对应的例题下载,或者前文对应刷题的链接,在刷题中学习,才可以更快的掌握知识!
下面是本文的关键点:

  • APK逆向工具:工欲善其事,必先利其器(这部分可以掠过,只做了工具的下载地址和简单介绍)
  • APK的基本结构(详细解析了每个文件的作用和目的)
  • Android逆向分析中的基础(解决没有安卓开发基础学习安卓逆向时候的痛点问题)
    • 如何找出APP的程序的入口点?
    • 如何识别是否加壳,并且简单脱壳?
    • 如何寻找一个页面的xml布局文件?
    • 如何确定按钮所绑定的函数?
    • 如何寻找app中涉及到的资源文件?
    • 什么是java层逆向,什么是Native层逆向?
  • 安卓系统中的四大组件是如何在逆向题目中被应用的?
  • 最后进行了安卓体系的梳理!

第二章:APK逆向工具:工欲善其事,必先利其器

1.1 雷电模拟器运行APK

雷电模拟器,作为安卓模拟器的佼佼者,一直以来备受用户青睐。它不仅可以让你在PC上畅快运行安卓应用,还能提供与手机端接近的使用体验,让你在开发、调试乃至游戏娱乐中都能游刃有余。安装雷电模拟器其实并不复杂,但要确保顺利完成,还是有一些细节需要关注。
相关使用:雷电模拟器的使用 - 搜索
下载地址:雷电模拟器官网_安卓模拟器_电脑手游模拟器

1.2 ADB的使用

ADB(Android Debug Bridge),简直是安卓开发者和逆向工程师的“瑞士军刀”。无论是调试、安装应用,还是进行日志分析,ADB都是不可或缺的工具。你可能会认为ADB只是一个命令行工具,然而它的强大远超你的想象。
相关使用:ADB安装及使用详解(非常详细)从零基础入门到精通,看完这一篇就够了-CSDN博客
下载地址:https://dl.google.com/android/repository/platform-tools-latest-windows.zip

1.4 使用JADX反编译APK

JADX是一款非常流行且功能强大的APK反编译工具,它能够将APK中的DEX文件(即Dalvik Executable文件)反编译成可读的Java源代码。JADX的优势不仅仅在于它的易用性,还在于它的反编译效果非常优秀,能够清晰地显示反编译后的Java代码,帮助开发者和安全人员深入理解应用的内部逻辑。

JADX的优点:
  • 易用性:图形界面的设计使得操作简单直观,适合初学者和经验丰富的开发者。
  • 高效的反编译效果:JADX能够将DEX文件反编译成非常接近原始Java代码的源代码,对于Java层的应用分析尤为高效。
  • 支持多种格式:除了反编译Java代码,JADX还支持查看APK中的资源文件(如图片、XML文件等),让你能够全面了解应用的构成。
    相关使用:APK反编译工具jadx - chuyaoxin - 博客园
    下载地址:https://down.52pojie.cn/Tools/Android_Tools/jadx-1.5.0.zip
1.5 使用GAD进行APK反汇编

GAD(Google Android Disassembler)是一个专注于APK底层字节码分析的工具。与JADX不同,GAD更多侧重于字节码级别的反汇编,它能够帮助安全研究人员和开发者深入到应用的最底层,查看其具体的机器码和执行逻辑。GAD特别适用于那些对字节码和汇编语言感兴趣的逆向工程师,它可以帮助我们获得应用中深层次的行为信息。

GAD的优点:
  • 底层分析能力:GAD能够提供非常详细的底层字节码分析,帮助你更深入地理解应用的执行过程。
  • 适用于高级分析:如果你需要分析复杂的应用行为或破解复杂的加密算法,GAD提供的反汇编信息可以帮助你做出准确的判断。
    相关使用:[原创]GDA使用手册-Android安全-看雪-安全社区|安全招聘|kanxue.com
    下载地址:https://down.52pojie.cn/Tools/Android_Tools/GDA4.11.zip
1.6 JEB进行APK反汇编

JEB的魅力在于其高精度的反汇编能力。它不仅能解析传统的DEX文件,还能处理各类复杂的文件格式,包括加固过的APK、经过混淆处理的代码,甚至是一些非标准的Android文件结构。它像一把锐利的刀刃,切开了应用的“外壳”,揭示其最核心的部分。

JEB的优点:
  • 强大的反汇编能力:JEB不仅仅局限于常规的字节码反汇编,它能够对各种复杂和非标准格式的APK进行深入分析。
  • 支持多种文件格式 :JEB支持广泛的文件格式解析,除了DEX文件,还包括PE(Portable Executable)、ELF、Java字节码等多种格式。
  • 高级功能与插件支持 :JEB的插件架构极为强大,用户可以根据自己的需求,定制化扩展JEB的功能。
    相关使用:第36讲: 使用Jeb工具反编译安卓APK_jeb反编译工具-CSDN博客
    下载地址:https://down.52pojie.cn/Tools/Android_Tools/JEB_Decompiler_3.19.1_Professional.rar
1.7 IDA进行反汇编

进入IDA的世界,你将步入一个顶级的反汇编领域。IDA(Interactive Disassembler)是众多逆向工程师手中的“神器”,无论是操作系统、应用程序还是嵌入式系统,它都能提供无与伦比的反汇编支持。

IDA的优势:
  • 精确的反汇编能力:IDA能反汇编几乎所有的二进制文件格式,展示底层机器码及其执行路径,让逆向分析更加精准。
  • 高度可扩展:IDA支持插件开发,用户可以根据需求扩展其功能,实现个性化分析。
  • 复杂任务支持:IDA特别适合进行复杂的逆向分析任务,如破解软件、分析恶意代码等。
    相关使用:菜鸟的逆向工程学习之路——逆向工具IDA的使用_ida工具-CSDN博客
    下载地址:https://down.52pojie.cn/Tools/Disassemblers/IDA_Pro_v8.3_Portable.zip
1.8 Frida脱壳工具的使用

Frida 是一个强大的动态分析工具,广泛应用于反向工程和安全测试中,尤其是在对 Android 应用进行脱壳(解除保护)时,它能够帮助研究人员通过动态注入脚本来分析应用程序的行为。以下是使用 Frida 进行脱壳的环境配置和基本步骤。

环境配置:
首先,确保你已经安装了 Frida 及其相关工具,可以通过以下命令进行安装:

pip install frida         # 安装 Frida 主库
pip install frida-tools   # 安装 Frida 的工具集,提供命令行工具
pip install frida-dexdump # 安装 frida-dexdump,用于分析 APK 文件的 dex 内容

这些工具将帮助你在 Android 环境中启动和操作 Frida Server,以及进行 APK 分析等操作。
Frida 的环境搭建并不复杂,特别是在虚拟设备(如雷电模拟器)和 Android Debug Bridge (ADB) 的支持下。具体的搭建流程可以参考以下链接:

  • Frida入门教程:基于逍遥模拟器和 ADB 环境搭建
    这个教程将详细介绍如何安装和配置 Frida 环境,并提供如何在模拟器和实际设备上运行 Frida Server 和脚本的操作步骤。

第三章:APK解析基础

在深入理解Android应用的工作原理和内部结构之前,我们首先需要了解应用打包的核心文件——APK(Android Package)。APK 文件是Android操作系统中的应用程序包,它包含了应用的所有资源、代码和必要的配置文件。可以把APK看作一个容器,其中集成了Android应用的所有组成部分。
为了能够更深入地分析和理解Android应用的结构,我们可以将APK文件拆解为多个关键组件。每个组件在应用运行中都扮演着不同的角色,理解这些组件有助于我们全面掌握应用的运行机制,甚至为后续的逆向分析和漏洞挖掘打下基础。

APK的基本结构

实际上,APK 文件是以 ZIP 格式进行压缩打包的,因此,我们可以像操作普通的ZIP文件一样,使用解压工具对其进行解压。通过解压后查看APK文件的目录结构,我们能够清晰地了解每个组成部分的作用。以下是一个典型的APK文件的结构示例:

APK 文件通常包括以下几个主要部分

  1. AndroidManifest.xml
  2. classes.dex
  3. resources.arsc
  4. assets/
  5. lib/
  6. res/
  7. META-INF/
    接下来,我们将详细解析这些文件和目录的作用及其内容。
    将一个apk进行解压,可以发现如下结构的文件目录,测试案例下载:攻防世界-Mobile-easy-so
1.AndroidManifest.xml(关键核心)

AndroidManifest.xml 是每个Android应用不可或缺的配置文件,它包含了应用的关键信息。我们可以把它看作是应用的“蓝图”或“说明书”,它向系统声明了应用的基本属性、组件以及权限等。AndroidManifest.xml中包括以下重要部分:

  • 应用的包名(package):每个Android应用都有一个唯一的包名,通过包名来区分不同的应用。
  • 应用的组件(Activities, Services, Broadcast Receivers, Content Providers):声明应用包含哪些组件,以及这些组件的属性和功能。
  • 权限声明:列出应用所需的权限,如访问网络、读取存储、使用相机等。
  • 应用主题和图标:定义应用的UI样式、图标等。
  • 最小SDK版本和目标SDK版本:确定应用能在什么版本的Android系统上运行。

详细解析Manifest中的关键字段

  • <manifest>:包含整个应用的包信息及权限定义。
    • package: 定义了应用的包名,通常为反向域名格式,如com.example.app
    • android:versionCode: 定义应用的版本号。
    • android:versionName: 定义应用的版本名称。
  • <application>:包含应用的核心配置,如主题、图标等。
    • android:icon: 定义应用的图标。
    • android:label: 定义应用的名称。
    • android:theme: 应用的UI主题。
  • <activity>:声明应用的各个界面(Activity),以及这些Activity的属性和行为。
    • android:name: Activity的类名。
    • android:label: Activity的标签。
    • android:theme: Activity特有的UI主题。
  • <uses-permission>:声明应用所需要的权限,如访问网络、发送短信等。
  • <intent-filter>:定义组件的功能和响应的事件,如Activity的启动方式或Broadcast Receiver接收的广播类型。
2. classes.dex

classes.dex 文件包含了应用程序的可执行代码。它是应用的Dalvik字节码文件,也是Android应用在运行时通过 Dalvik虚拟机ART(Android Runtime) 解释执行的核心文件。每个Android应用中,所有的Java源代码都经过编译后形成一个或多个DEX(Dalvik Executable)文件,这些文件包含了应用的业务逻辑和代码实现。
在Android 5.0(Lollipop)之后,Google引入了 ART(Android Runtime) 代替了传统的Dalvik虚拟机,ART的执行方式比Dalvik更高效,支持Ahead-of-Time(AOT)编译和即时编译(JIT)策略。
这部分比较难可以拓展阅读一下,相关文档:

  • JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比_java dalvik-CSDN博客
  • 安卓逆向学习----smali,dex,java等文件之间转换关系_dex与smail-CSDN博客
3. resources.arsc

resources.arsc 文件包含了应用程序的所有编译后的资源映射信息。这个文件并不存储实际的资源内容(如图片或字符串),而是存储资源与资源ID的映射关系。例如,它会保存应用中的字符串、颜色、尺寸、样式等信息以及这些资源的ID。通过这个文件,Android系统能够在应用运行时快速访问和加载所需的资源。

使用jadx可以看见:

4. assets/

assets/ 目录包含了应用程序的原始资源文件,这些资源不经过编译,直接以原始形式存储。通常,开发者可以在该目录中存放字体文件、音频文件、HTML文件等,应用在运行时通过API来读取这些资源。例如,游戏可能会将所有的地图文件或纹理图像存放在此目录中。通过AssetManager API,应用可以访问这些文件。

5. lib/

lib/ 目录包含了本地库文件,通常是通过 JNI(Java Native Interface) 与C/C++编写的本地代码。这些库文件可以针对不同的硬件架构(如arm、x86等)进行编译,因此lib/目录下通常会为每个架构创建相应的子目录。这个目录中存放的本地库可以通过Java代码调用JNI接口实现与系统底层的交互。

下面是一个案例进入lib进入到目录中得到以下目录结构,不同架构的手机拥有不同的操汇编代码所以使用四种架构的汇编分别实现一次:

├─arm64-v8a
│      libcyberpeace.so
│
├─armeabi-v7a
│      libcyberpeace.so
│
├─x86
│      libcyberpeace.so
│
└─x86_64libcyberpeace.so
6. res/

res/ 目录包含了Android应用所需的所有资源文件。与 assets/ 目录不同,res/ 目录中的资源文件是经过编译的,按照不同类型的资源进行组织,例如:

  • drawable/:存放图像资源(如PNG、JPEG等格式的图片)。
  • layout/:存放XML格式的布局文件,定义界面的结构。
  • values/:存放各种配置文件,定义应用的常量、颜色、字符串等资源。例如:
    • strings.xml:存储应用的文本字符串。
    • colors.xml:存储应用使用的颜色资源。
    • styles.xml:存储样式资源。

values/目录下,除了strings.xmlcolors.xml等常见资源文件,还会有像dimens.xml(尺寸定义文件)和attrs.xml(自定义属性)等资源文件。

可以在文件夹目录中找到也可以在jadx里面查看:

7. META-INF/

META-INF/ 目录与Java的JAR文件类似,用于存放APK文件的元数据,如签名文件、校验信息等。此目录主要包括以下文件:

  • MANIFEST.MF:存放APK的清单文件,包含关于APK文件本身的信息。
  • CERT.RSA:包含APK文件的数字签名。
  • CERT.SF:存放APK文件的签名摘要。
    这些文件确保了APK的完整性和安全性,保证APK文件没有被篡改,且来自合法的开发者。
    下面是一个示例:

第四章:Android逆向分析中的基础

Android 逆向分析是一个深入挖掘应用内部工作原理的过程,通常用于漏洞挖掘、恶意软件分析或应用的安全性研究。在这章中,我们将深入探讨 Android APK 的反编译与结构分析,剖析壳分析与绕过技术,以及如何对资源与布局文件进行分析。我们还会涉猎 Java 层的逆向技巧,以及如何在 Native 层执行逆向工程。每一部分都将逐一分析和讲解,以帮助读者在 Android 逆向分析中取得更好的突破。

1. APK反编译与结构分析:如何找出程序的入口点

在进行 Android 逆向时,首先需要对 APK 文件进行反编译和结构分析。理解 APK 的基本结构至关重要,因为它帮助我们定位关键组件和入口点。一个典型的 APK 文件包含多个元素,如 AndroidManifest.xml、DEX 文件、资源文件和库文件等。

定位入口点实战案例

目标: 学习如何反编译 APK 文件并分析其结构,找出应用程序的入口点。
文章: android apk入口分析_5.apk的程序入口界面 - CSDN博客
实战案例:BUU刷题-简单注册器
更详细的WP:BUUCTF之简单注册器(RE) - Eip的浪漫 - 博客园

首先梳理一下基本app的逆向流程:

1.将apk拖入JADX后寻找到AndroidManifest.xml文件:

下面给出AndroidManifest.xml文件的详细注释:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"android:versionCode="1"  <!-- 应用版本代码,用于区分不同版本的更新 -->android:versionName="1.0"  <!-- 应用版本名称,通常为可见版本号 -->package="com.example.flag">  <!-- 应用包名,唯一标识应用 --><!-- 使用的最低 SDK 版本和目标 SDK 版本 --><uses-sdkandroid:minSdkVersion="8"  <!-- 设置应用的最低 SDK 版本,表示应用可在 SDK 8 或以上的设备上运行 -->android:targetSdkVersion="19"/>  <!-- 设置应用的目标 SDK 版本,表示应用针对 SDK 19 的优化 --><applicationandroid:theme="@style/AppTheme"  <!-- 设置应用的主题 -->android:label="@string/app_name"  <!-- 设置应用的名称 -->android:icon="@drawable/ic_launcher"  <!-- 设置应用的图标 -->android:debuggable="true"  <!-- 设置应用是否可调试,调试模式下可以进行调试 -->android:allowBackup="true">  <!-- 设置是否允许应用数据备份 --><!-- 定义应用的主 Activity --><activityandroid:label="@string/app_name"  <!-- 设置 Activity 的名称 -->android:name="com.example.flag.MainActivity">  <!-- 定义该 Activity 的完整类名 --><!-- 配置启动该 Activity 的 Intent Filter --><intent-filter><action android:name="android.intent.action.MAIN"/>  <!-- 指定这是应用的主入口 --><category android:name="android.intent.category.LAUNCHER"/>  <!-- 表明该 Activity 是启动器中的入口 --></intent-filter></activity></application></manifest>

在 Android 应用中,AndroidManifest.xml 文件是至关重要的,它定义了应用的所有组件以及组件之间的关系,包括应用的入口点。打开反编译后的 APK 中的 AndroidManifest.xml 文件,查找 <activity> 标签,它们通常定义了应用的各个 Activity(包括启动 Activity)。

入口点通常由以下两个标记表示:

  • <action android:name="android.intent.action.MAIN" />:标记这是应用的主入口。
  • <category android:name="android.intent.category.LAUNCHER" />:表示该 Activity 会出现在应用启动器中(即桌面)。

所以最终得出该app的程序入口点代码是在android:name="com.example.flag.MainActivity"处!

2.成功寻找到activity的代码入口处,开始分析activity的生命执行流程:
根据android:name="com.example.flag.MainActivity"字段成功找到Activity的功能实现代码位置,一个Activity的生命周期是:onCreate()->onStart()->onResume()->onPause()->onStop()->onDestroy(),所以可以先锁定omCreate函数,锁定app加载的主要逻辑!

3.开始分析按钮的逻辑代码,成功解析出需要输入的内容:
在主要逻辑中可以发现界面中的一个按钮绑定了一个onclick按钮点击事件:

该函数用于处理用户点击事件,验证输入框中的文本是否符合特定规则,如果符合规则,则对一个预定义的字符串进行一系列字符运算和逆序处理,最终显示一个特定格式的“flag”;否则,显示错误提示“输入注册码错误”。
也就是说我们只需要输入一个正确的字符串就可以成功拿到flag!
将代码提取出来分析:

        button.setOnClickListener(new View.OnClickListener() { // from class: com.example.flag.MainActivity.1@Override // android.view.View.OnClickListenerpublic void onClick(View v) {int flag = 1;String xx = editview.getText().toString();if (xx.length() != 32 || xx.charAt(31) != 'a' || xx.charAt(1) != 'b' || (xx.charAt(0) + xx.charAt(2)) - 48 != 56) {flag = 0;}if (flag == 1) {char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();x[2] = (char) ((x[2] + x[3]) - 50);x[4] = (char) ((x[2] + x[5]) - 48);x[30] = (char) ((x[31] + x[9]) - 48);x[14] = (char) ((x[27] + x[28]) - 97);for (int i = 0; i < 16; i++) {char a = x[31 - i];x[31 - i] = x[i];x[i] = a;}String bbb = String.valueOf(x);textview.setText("flag{" + bbb + "}");return;}textview.setText("输入注册码错误");}});}

这里的逻辑代码就很清晰了:

int flag = 1;
String xx = editview.getText().toString();
if (xx.length() != 32 || xx.charAt(31) != 'a' ||

相关文章:

Android基础彻底解析-APK入口点,xml,组件,脱壳,逆向

第一章:引言与背景 Android逆向工程,作为一种深入分析Android应用程序的技术,主要目的就是通过分析应用的代码、资源和行为来理解其功能、结构和潜在的安全问题。它不仅仅是对应用进行破解或修改,更重要的是帮助开发者、研究人员和安全人员发现并解决安全隐患。 本文主要对…...

ubuntu 2204 安装 vcs 2018

安装评估 系统 : Ubuntu 22.04.1 LTS 磁盘 : ubuntu 自身占用了 9.9G , 按照如下步骤 安装后 , 安装后的软件 占用 13.1G 仓库 : 由于安装 libpng12-0 , 添加了一个仓库 安装包 : 安装了多个包(lsb及其依赖包 libpng12-0)安装步骤 参考 ubuntu2018 安装 vcs2018 安装该…...

Express中间件(Middleware)详解:从零开始掌握(3)

实用中间件模式25例 1. 基础增强模式 请求属性扩展 function extendRequest() {return (req, res, next) > {req.getClientLanguage () > {return req.headers[accept-language]?.split(,)[0] || en;};next();}; } 响应时间头 function responseTime() {return (r…...

深入理解微信小程序开发:架构、组件化与进阶实战

&#x1f4d8;博文正文&#xff1a; 深入理解微信小程序开发&#xff1a;架构、组件化与进阶实战 微信小程序已成为移动互联网的重要入口。随着业务复杂度提升&#xff0c;仅靠入门知识已无法应对日常开发需求。本文将深入剖析小程序开发架构、组件化模式、状态管理、网络封装…...

逆向|中国产业政策大数据平台|请求体加密

2025-04-11 逆向地址:aHR0cDovL3poZW5nY2UuMmIuY24v 打开开发者工具出现debugger,直接注入脚本过掉无限debugger let aaa Function.prototype.constructor; Function.prototype.constructor function (params) { if(params ‘debugger’){ console.log(params); return null…...

在SpringBoot中访问 static 与 templates 目录下的内容

目录 步骤一&#xff1a;添加 Thymeleaf 依赖 (处理 Templates 目录)步骤二&#xff1a;配置静态资源路径 (可选但建议了解)步骤三&#xff1a;访问不同目录下的 HTML 文件访问 static 目录下的 HTML 文件访问 templates 目录下的 HTML 文件 总结 在使用 Spring Boot 开发 Web …...

游戏引擎学习第226天

引言&#xff0c;计划 我们目前的目标是开始构建“元游戏”结构。所谓元游戏&#xff0c;指的是不直接属于核心玩法本身&#xff0c;但又是游戏体验不可或缺的一部分&#xff0c;比如主菜单、标题画面、存档选择、选项设置、过场动画等。我们正在慢慢将这些系统结构搭建起来。…...

青少年编程与数学 02-016 Python数据结构与算法 22课题、并行算法

青少年编程与数学 02-016 Python数据结构与算法 22课题、并行算法 一、GPU并行计算矩阵乘法示例 二、MPI并行计算allgather操作示例 三、Python中的并行计算多线程并行计算多进程并行计算 四、SIMD并行计算SIMD并行计算示例 总结 课题摘要: 并行算法是通过同时执行多个任务或操…...

Ubuntu系统18.04更新驱动解决方法

原始是&#xff1a;ubuntu18.04里面的驱动是470&#xff0c;对应cuda11.4 现在需要更新为525&#xff0c;对应cuda为12.0 实现&#xff1a; 1、打开终端 Ctrl Alt T2、使用 lspci 命令&#xff08;快速查看显卡型号&#xff09; lspci | grep -i vga3、终端输入 ubuntu-d…...

Notepad++安装Markdown实时预览插件

具体操作 打开notepad -> 插件 -> 插件管理 -> 可用 -> “Markdown Panel” -> 安装&#xff0c;安装完成后工具栏点击"Markdown Panel"按钮。 注意&#xff1a;由于网络等原因可能安装失败 导致工具栏没出现""Markdown Panel"按钮&am…...

Mysql-视图和存储过程

视图 1.介绍 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条…...

FreeRTOS入门与工程实践-基于STM32F103(二)(互斥量,事件组,任务通知,软件定时器,中断管理,资源管理,调试与优化)

互斥量 一、互斥量&#xff08;Mutex&#xff09;&#xff1a;解决多任务 “抢资源” 的问题 1. 是什么&#xff1f; 互斥量是一种 “任务间互斥访问资源” 的工具&#xff0c;本质是一个 只能被锁定&#xff08;0&#xff09;或释放&#xff08;1&#xff09;的二进制信号量…...

stm32面试

数据结构相关问题 stm32面试 数据结构相关问题 目录基础数据结构树与图排序与查找算法 Linux相关问题Linux系统基础Linux命令与脚本Linux网络与服务 操作系统相关问题操作系统基础概念操作系统调度算法操作系统同步与通信 STM32相关问题STM32硬件基础STM32编程与开发STM32应用与…...

202524 | 分布式事务

分布式事务&#xff08;Distributed Transaction&#xff09; 分布式事务是指跨多个数据库、服务或系统节点的事务操作&#xff0c;要求所有参与方要么全部成功提交&#xff0c;要么全部回滚&#xff0c;保证数据一致性。 1. 为什么需要分布式事务&#xff1f; 在单体应用中&…...

Python 企业级架构实战(上篇)

深入企业级系统设计与高可用架构,掌握构建可扩展 Python 系统的核心技能。 41. 微服务架构设计与 FastAPI 实现 多服务协同开发示例 # 用户服务 (user_service/main.py) from fastapi import FastAPI app = FastAPI() users_db = { 1: {"id": 1, "name&…...

在 macOS 上修改 最大文件描述符限制(Too many open files) 和 网络端口相关参数 需要调整系统级配置的详细步骤

在 macOS 上修改 最大文件描述符限制&#xff08;Too many open files&#xff09; 和 网络端口相关参数 需要调整系统级配置。以下是详细步骤&#xff1a; 在 macOS 上修改 最大文件描述符限制&#xff08;Too many open files&#xff09; 和 网络端口相关参数 需要调整系统级…...

Python 文本和字节序列(字符问题)

本章将讨论下述话题&#xff1a; 字符、码位和字节表述 bytes、bytearray 和 memoryview 等二进制序列的独特特性 全部 Unicode 和陈旧字符集的编解码器 避免和处理编码错误 处理文本文件的最佳实践 默认编码的陷阱和标准 I/O 的问题 规范化 Unicode 文本&#xff0c;进行安全的…...

通过Arduino IDE向闪存文件系统上传文件

注意&#xff1a;适用于Arduino IDE 2.0版本以上。对于Arduino IDE版本在2.0以下的请参考太极创客的教程&#xff1a;http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/spiffs/upload-files/。 1. 下载脚本文件 下载地址&#xff1a;https://github.com/earl…...

leetcode 121. Best Time to Buy and Sell Stock

题目描述 本题属于动态规划类问题。 dp数组的含义 dp[i][0]表示从第0天到第i天为止&#xff0c;处于持有股票的状态下&#xff0c;账户里的最大金额。 dp[i][1]表示从第0天到第i天为止&#xff0c;处于不持有股票的状态下&#xff0c;账户里的最大金额。 按照这个定义dp[n-…...

【Docker-13】Docker Container容器

Docker Container&#xff08;容器&#xff09; 一、什么是容器&#xff1f; 通俗地讲&#xff0c;容器是镜像的运行实体。镜像是静态的只读文件&#xff0c;而容器带有运行时需要的可写文件层&#xff0c;并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容器有…...

LoadableTransportInfo函数分析之RPCRT4!LOADABLE_TRANSPORT::LOADABLE_TRANSPORT初始化过程

LoadableTransportInfo函数分析 第一部分&#xff1a; RPC_STATUS LoadableTransportInfo ( IN RPC_CHAR * DllName, IN RPC_CHAR PAPI * RpcProtocolSequence, OUT TRANS_INFO * PAPI *pTransInfo ) { 。。。。。。。 pTransportInterface (*TransportLo…...

大模型预标注和自动化标注在OCR标注场景的应用

OCR&#xff0c;即光学字符识别&#xff0c;简单来说就是利用光学设备去捕获图像并识别文字&#xff0c;最终将图片中的文字转换为可编辑和可搜索的文本。在数字化时代&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术作为处理图像中文字信息的关键手段&#xff0c;其…...

Zookeeper 命令返回数据的含义

下面详细讲解这三个 Zookeeper 命令返回数据的含义&#xff1a; 1. ls /path - 列出子节点 命令功能&#xff1a; 列出指定路径下的所有直接子节点名称&#xff08;不包含孙子节点&#xff09; 示例返回&#xff1a; [child1, child2, child3] 输出解析&#xff1a; 返回…...

蓝宝石狼组织升级攻击工具包,利用新型紫水晶窃密软件瞄准能源企业

网络安全专家发现&#xff0c;被称为"蓝宝石狼"&#xff08;Sapphire Werewolf&#xff09;的威胁组织正在使用升级版"紫水晶"&#xff08;Amethyst&#xff09;窃密软件&#xff0c;对能源行业企业发起复杂攻击活动。此次攻击标志着该组织能力显著提升&am…...

2025蓝桥杯python A组省赛 题解

真捐款去了&#xff0c;好长时间没练了&#xff0c;感觉脑子和手都不转悠了。 B F BF BF 赛时都写假了&#xff0c; G G G 也只写了爆搜。 题解其实队友都写好了&#xff0c;我就粘一下自己的代码&#xff0c;稍微提点个人的理解水一篇题解 队友题解 2025蓝桥杯C A组省赛 题…...

JMeter重要的是什么

重要特性 支持多种协议&#xff1a; JMeter支持对多种协议进行性能测试&#xff0c;包括HTTP、HTTPS、FTP、JDBC&#xff08;数据库&#xff09;、LDAP、JMS、SOAP、REST等。这使得它能够适应各种不同的测试场景。强大的负载模拟能力&#xff1a; JMeter能够模拟大量的虚拟用户…...

深入探索如何压缩 WebAssembly

一、初始体积&#xff1a;默认 Release 构建 我们从最基础的构建开始&#xff0c;不开启调试符号&#xff0c;仅使用默认的 release 模式&#xff1a; $ wc -c pkg/wasm_game_of_life_bg.wasm 29410 pkg/wasm_game_of_life_bg.wasm这是我们优化的起点 —— 29,410 字节。 二…...

浅谈SQL Server系统内核管理机制

浅谈SQL Server系统内核管理机制 应用环境 Microsoft Windows 10.0.19045.5487 x64 专业工作站版 22H2Microsoft SQL Server 2019 - 15.0.2130.3 (X64)SQL Server Management Studio -18.6 laster 文章目录 浅谈SQL Server系统内核管理机制数据库和文件服务器管理视图系统目录…...

关于我的服务器

最近我买了台腾讯云服务器&#xff0c;然后新手小白只会用宝塔。。。 安装完之后默认的端口是8888&#xff0c;打开面板就会提示我有风险。然后 我改了端口之后&#xff0c;怎么都打不开。 于是 学到了几句命令可以使用&#xff1a; //查看端口是否已经修改成功 cat www/se…...

vue + element-plus自定义表单验证(修改密码业务)

写一个vue组件Password.vue 没有表单验证只有3个表单项 <template><div><el-form><el-form-item label"旧密码"><el-input></el-input></el-form-item><el-form-item label"新密码"><el-input>&l…...