IOS安全测试学习-DVIA-v2

news2024/11/15 17:35:04

前言

为学习IOS知识并加深理解,故通过IOS漏洞靶场来直接体现IOS环境中的常见漏洞。

环境准备

iPhone X ios 13.4.1 已越狱

MacOS Big Sur 11.0 Bate 虚拟机

DVIA-v2 IOS 漏洞靶场app

grapefruit、objection

#pip3 install frida、pip3 install frida-tools、sudo npm install -g igf

注:工具和客户端的frida版本都是16.0.1

part1-Local Data Storage

任务:寻找存储在本地的敏感信息

Plist

PLIST 文件是一个特殊的文本文件,其中包含属性列表格式的数据。macOS、iOS 和 iPadOS 应用程序使用该文件以具有XML结构的键值格式存储设置和其他数据。

输入账号密码,数据会被保存到plist文件中

image-20221014134218487

objection -g DVIA-v2 explore 
env

使用objection定位app使用的目录,env 列出app当前环境(使用的目录),查看Documents目录下是否有plist文件

image-20221017105850586

默认情况下, 每个沙盒含有1个应用程序包和三个文件夹: Documents, Library和tmp. 因为沙盒机制, 应用只能在这几个目录读写文件.

MyApp.app

应用程序包, 这里面存放的是应用程序文件, 包括资源文件和可执行文件.

Documents

应用程序在运行时生成的一些需要长久保存的数据(比如: 个人设置等信息), 通过iTunes, iCloud备份时,会备份这个目录下的数据, 此目录下保存相对重要的数据.

Library/Caches

从网络上下载的文件或数据(如: 音乐缓存, 图片缓存等) , 此目录下的数据某些情况下会自动删除, 需要程序员手动清除该目录下的数据. ITunes, iCloud备份时不会备份此目录下的数据.一般用于存储体积不大, 不需要备份的非重要资源数据.

tmp

保存应用运行时产生的一些临时数据,应用程序退出,系统磁盘空间不够,手机重启时,都会自动清除该目录的数据。无需程序员手动清除该目录中的数据.iTunes、iCloud备份时,不会备份次目录。

发现明文存储的账号密码

image-20221017110640813

使用grapefruit查看

image-20221019151633964

NSUserDefaults

NSUserDefaults 是一个单例,它可以用于数据的永久存储,适合存储轻量级的本地数据。

NSUserDefaults 存储的位置为应用的 /Library/Preferences/目录下

cd /var/mobile/Containers/Data/Application/733E2124-8A28-4F84-A7/Preferences
ios plist cat com.highaltitudehacks.DVIAswiftv2.plist

image-20221017111616083

image-20221017112134613

使用grapefruit查看

image-20221019151903676

Keychain

Keychain Services 是 macOS 和 iOS 都提供一种安全的存储敏感信息的工具,比如,网络密码:用户访问服务器或者网站,通用密码:用来保存应用程序或者数据库密码.与此同时,用于认证的证书密钥和身份信息,也可以存储在Keychain中,Keychain Services 的安全机制保证了存储这些敏感信息不会被窃取。简单说来,Keychain 就是一个安全容器。

ios keychain dump

image-20221017112359838

image-20221018105513689

使用grapefruit查看,十六进制解密

image-20221019154910077

image-20221019154935242

Core Data

Core Data是苹果官方提供的管理数据层对象的框架,它提供了对象—关系映射(ORM)的功能,即能够将Objective-C对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成Objective-C对象。在此数据操作期间,不需要编写任何SQL语句。Core Data针对对象生命周期,以及持久化的对象图管理(object graph management)中的一些常见问题提供了解决方案。CoreData的主要任务是负责数据更改的管理、序列化到磁盘、最小化内存占用以及查询数据。CoreData通常能有效减少50%~70%模型层的代码量。

cd /var/mobile/Containers/Data/Application/9C3F7322-BB5B-4727-922C-51F238A4893F/Library/Application\ Support/
cp Model.sqlite ../
scp -P 1234 root@127.0.0.1:/var/mobile/Containers/Data/Application/9C3F7322-BB5B-4727-922C-51F238A4893F/Library/Model.sqlite .
sqlite3 Model.sqlite
.tables
select * from ZUSER;

这里有个坑,到应用下复制sql文件到Mac上查看内容的时候是空的,而使用grapefruit工具查看的时候是有数据的

image-20221018105834045

image-20221018112923495

image-20221019170241210

Webkit Caching

使用UrWebView加载网页的应用程序通常使用缓存来加快响应时间。在某些情况下,它们可以缓存包含机密信息的响应。您的任务是找到存储请求和响应的位置–应用程序沙箱。提示:在数据库中使用cf_url缓存数据端口的表。

在app目录中只发现了数据库文件,里面没有发现一些有用的东西。可能是开放式命题,在app内打开的链接会生成缓存存储在数据库中,如果缓存中包含敏感信息,则会造成信息泄露。

image-20221019171541912

Realm

需要特定工具打开,先留着

Couchbase Lite

CouchBase是一款开源的,分布式的nosql数据库,主要用于分布式缓存和数据存储领域。能够通过manage cache提供快速的亚毫米级别的k-v存储操作,并且提供快速的查询和其功能强大的能够指定SQL-like查询的查询引擎。

image-20221019175651422

image-20221019175717496

但是这边不知道为什么写不进去,没有内容

YapDatabase

YapDatabase是以 键值对 的形式储存数据的,和NSUserDefault很像。但是Yap是数据库。
Yap里有 Collection,key。key对应value(可以储存任意对象)。而Collection可以理解为命名空间。

image-20221025143146563

image-20221025154751581

image-20221025154728130

part2-Jaibreak Detection

任务:绕过越狱检测

Test 1

frida-trace -U -i "*jail*" DVIA-v2

使用frida查看相关的越狱函数,点击Test 1事件,触发 _T07DVIA_v232JailbreakDetectionViewControllerC20jailbreakTest1TappedyypF() 方法,IDA反汇编查看相应代码,调用了几个函数,但是没什么内容,猜测应该是某个函数的返回值决定是否越狱

image-20221026112634807

image-20221026113118615

重新查看汇编代码,LDR指令中一般会在寄存器中存贮一些数据,可以通过配合BL指令来查看跳转函数

__text:0000000100192C10 SUB             SP, SP, #0x60
__text:0000000100192C14 STP             X20, X19, [SP,#0x50+var_10]
__text:0000000100192C18 STP             X29, X30, [SP,#0x50+var_s0]
__text:0000000100192C1C ADD             X29, SP, #0x50
__text:0000000100192C20 STUR            X0, [X29,#var_18]
__text:0000000100192C24 STUR            X20, [X29,#var_20]
__text:0000000100192C28 STR             X20, [SP,#0x50+var_28]
__text:0000000100192C2C STR             X0, [SP,#0x50+var_30]
__text:0000000100192C30 BL              __T07DVIA_v213DVIAUtilitiesCMa
__text:0000000100192C34 ADRP            X20, #_swift_isaMask_ptr@PAGE
__text:0000000100192C38 LDR             X20, [X20,#_swift_isaMask_ptr@PAGEOFF]
__text:0000000100192C3C LDR             X30, [X0,#0x58]
__text:0000000100192C40 LDR             X8, [SP,#0x50+var_28]
__text:0000000100192C44 LDR             X9, [X8]
__text:0000000100192C48 LDR             X20, [X20]
__text:0000000100192C4C AND             X9, X9, X20
__text:0000000100192C50 LDR             X9, [X9,#0x80]
__text:0000000100192C54 MOV             X20, X8
__text:0000000100192C58 STR             X0, [SP,#0x50+var_38]
__text:0000000100192C5C STR             X30, [SP,#0x50+var_40]
__text:0000000100192C60 BLR             X9
__text:0000000100192C64 LDR             X8, [SP,#0x50+var_28]    #将[SP,#0x50+var_28]的值保存在寄存器x8中,值为0x1,对应true
__text:0000000100192C68 STR             W0, [SP,#0x50+var_44]
__text:0000000100192C6C MOV             X0, X8
__text:0000000100192C70 BL              _objc_retain
__text:0000000100192C74 LDR             X8, [SP,#0x50+var_28]
__text:0000000100192C78 LDR             X9, [SP,#0x50+var_40]
__text:0000000100192C7C LDR             W10, [SP,#0x50+var_44]
__text:0000000100192C80 AND             W11, W10, #1
__text:0000000100192C84 STR             X0, [SP,#0x50+var_50]
__text:0000000100192C88 MOV             X0, X11
__text:0000000100192C8C MOV             X1, X8
__text:0000000100192C90 LDR             X20, [SP,#0x50+var_38]   #修改这个值也能绕过
__text:0000000100192C94 BLR             X9
__text:0000000100192C98 LDR             X0, [SP,#0x50+var_30]
__text:0000000100192C9C BL              ___swift_destroy_boxed_opaque_existential_0
__text:0000000100192CA0 LDP             X29, X30, [SP,#0x50+var_s0]
__text:0000000100192CA4 LDP             X20, X19, [SP,#0x50+var_10]
__text:0000000100192CA8 ADD             SP, SP, #0x6

hook 脚本

var targetModule = 'DVIA-v2';
var addr = ptr(0x192c64); #ptr(0x192c90);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                    console.log('At the address ' + addr + ' the value is currently ' + this.context.x0);
        },
    });




var targetModule = 'DVIA-v2';
var addr = ptr(0x192c64); #ptr(0x192c90);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                if(this.context.x0 == 0x01){     #替换返回值
                    this.context.x0=0x00
                    console.log("Bypass Test1");
            }
        },
    });

替换返回值之后成功绕过越狱检测

frida -U -l jailbreak.js DVIA-v2

image-20221026144309259

image-20221026145838948

image-20221026143733697

Test 2

第二关用objection来测试比较方便

objection -g DVIA-v2 explore  #启动调试

ios hooking search classes jailbreak  #寻找越狱的相关类
ios hooking list class_methods JailbreakDetection   #列出类中的相关方法
ios hooking list class_methods DVIA_v2.JailbreakDetectionViewController   #列出类中的相关方法

image-20221026160912149

方法名称前的加号(+)和减号(-)表示方法的返回值。加号(+)表示这是一个返回BOOL类型的类方法。减号(-)表示这是一个实例方法。

只有一个返回BOOL值的类,即+ isJailbreak方法,极大是越狱的判定方法,可以通过改变布尔方法的返回值来越狱。

ios hooking watch method "+[JailbreakDetection isJailbroken]" --dump-args --dump-return   #hook该方法
ios hooking set return_value "+[JailbreakDetection isJailbroken]" false        #修改返回值为false

image-20221026161918533

image-20221026161939636

也可以通过frida hook返回值,脚本如下

var className = "JailbreakDetection"; 
var funcName = "+ isJailbroken"; 
var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');
var newretval = ptr("0x0");

Interceptor.attach(hook.implementation, { 
    onLeave: function(retval) { console.log("[*] Class Name: " + className); 
    console.log("[*] Method Name: " + funcName); 
    console.log("\t[-] Type of return value: " + typeof retval); 
    console.log("\t[-] Original Return Value: " + retval);  
    retval.replace(newretval) 
    console.log("\t[-] New Return Value: " + newretval) } });

image-20221026162341958

Test 3

第三关调用了两个函数,重点看第二个方法中的代码

image-20221026165044663

代码主要是检测越狱后的特征,比如安装软件、系统功能等,最终会写到一个jailbreak.txt文件中。

v2 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("/Applications/Cydia.app", 23LL, 1LL);
v4 = v3;
v5 = _T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v2);
swift_unknownRelease(v4);
v6 = (unsigned __int64)objc_msgSend(v1, "fileExistsAtPath:", v5);
v2 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("/Applications/Cydia.app", 23LL, 1LL);
v4 = v3;
v5 = _T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v2);
swift_unknownRelease(v4);
v6 = (unsigned __int64)objc_msgSend(v1, "fileExistsAtPath:", v5);
v23 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("/usr/sbin/sshd", 14LL, 1LL);
v25 = v24;
v26 = _T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v23);
swift_unknownRelease(v25);
v27 = (unsigned __int64)objc_msgSend(v22, "fileExistsAtPath:", v26);
v30 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("/etc/apt", 8LL, 1LL);
v32 = v31;
v33 = _T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v30);
swift_unknownRelease(v32);
v34 = (unsigned __int64)objc_msgSend(v29, "fileExistsAtPath:", v33);
v43 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("/private/jailbreak.txt", 22LL, 1LL);
v45 = v44;
v46 = _T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v43);
swift_unknownRelease(v45);
v104 = 0uLL;
v47 = (unsigned __int64)objc_msgSend(v42, "removeItemAtPath:error:", v46, &v104);

但是代码中有一个if逻辑决定是否越狱

  if ( v51 & 1 )
    v116 = 1;
  if ( v116 & 1 )
  {
    _T0So17UIAlertControllerCMa(v52);
    v53 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC(&unk_100391E4C, 0LL, 1LL);
    v55 = v54;
    v57 = v56;
    v58 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC(
            "Device is Jailbroken, the application will now exit",
            51LL,
            1LL);
    _T0So13UIAlertActionCMa();
  }
  else
  {
    _T0So17UIAlertControllerCMa(v52);
    v66 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC(&unk_100391E4C, 0LL, 1LL);
    v68 = v67;
    v70 = v69;
    v71 = _T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC("Device is Not Jailbroken", 24LL, 1LL);

  }

image-20221026165827201

__text:00000001001959D4 loc_1001959D4
__text:00000001001959D4 LDURB           W8, [X29,#var_30]
__text:00000001001959D8 AND             W8, W8, #1
__text:00000001001959DC TBZ             W8, #0, loc_10

and指令中,它对寄存器 8 和值 0x1 执行 AND 操作。该tbz指令定义为Test bit and branch if zero。因此该tbz指令正在测试寄存器 8 是 0x0 还是 0x1。如果它是 0x0,那么它将跳转。这意味着可以让寄存器 8 的值为 0x0,那么它将跳转到成功函数。

查看目前寄存器中存的值,是0x1,对应的是检测到越狱的分支,修改为0x0则绕过越狱检测

var targetModule = 'DVIA-v2';
var addr = ptr(0x1959dc);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                    console.log('At the address ' + addr + ' the value is currently ' + this.context.x8);
        },
    });
    
    
var targetModule = 'DVIA-v2';
var addr = ptr(0x1959dc);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                if(this.context.x8 == 0x01){
                    this.context.x8=0x00
                    console.log("Bypass Test3");
            }
        },
    });

image-20221026171351300

修改值之后

image-20221026171726818

image-20221026171740383

Test 4

操作同3

var targetModule = 'DVIA-v2';
var addr = ptr(0x1936E4);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                    console.log('At the address ' + addr + ' the value is currently ' + this.context.x8);
        },
    });
    
    
var targetModule = 'DVIA-v2';
var addr = ptr(0x1936E4);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                if(this.context.x8 == 0x01){
                    this.context.x8=0x00
                    console.log("Bypass Test4");
            }
        },
    });19702C

Test 5

同3

var targetModule = 'DVIA-v2';
var addr = ptr(0x19702C);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                    console.log('At the address ' + addr + ' the value is currently ' + this.context.x8);
        },
    });
    
    
var targetModule = 'DVIA-v2';
var addr = ptr(0x19702C);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                if(this.context.x8 == 0x01){
                    this.context.x8=0x00
                    console.log("Bypass Test5");
            }
        },
    });

part3-Runtime Manipulation

任务:绕过登录限制和修改url

Login Method 1

起初是想像越狱绕过一样hook TBZ指令的值来绕过登录,但是发现修改了也不行,所以改用objection

ios hooking search classes login  
ios hooking list class_methods LoginValidate  
ios hooking watch class LoginValidate
ios hooking watch method "+[LoginValidate isLoginValidated]" --dump-args --dump-return
ios hooking set return_value "+[LoginValidate isLoginValidated]" true

image-20221026190325062

image-20221026190512048

image-20221026190631360

image-20221026190642272

Login Method 2

定位登录方式2的方法,在代码中找到账号密码,登录成功

image-20221026191402265

image-20221026191430519

image-20221026191506562

Read tutorial

还未弄清,暂留

Validate code

在登录验证类中就包含该方法,验证码写死了,值为8848

image-20221027135904568

image-20221027135952648

image-20221027140043313

part4-Side Channel DataLeakage

Device Logs

提交信息就崩溃,暂留

App Screenshot

暂不清楚意义,暂留

Pasteboard

读取剪贴板的信息,但是另一个应用访问权限还不太清楚

ios pasteboard monitor

image-20221027154505557

Cookies

ios cookies get

image-20221027155219924

part5-Broken Cryptography

这一关环节使用 RNEncryptor 对数据进行加密存贮,使用的是AES加密,可以根据key和密文等信息解密出数据,但是试了一番发现自己对swift语言不太会,没办法编写对应解密工具,所以就先放一放。此题wp见:https://resources.infosecinstitute.com/topic/ios-part-29-insecure-broken-cryptography/

Challenge 1

Challenge 2

part6-Webview Issues

任务:向app注入一些代码以完成需求

MSG “Hello Word”

正常提交数据

image-20221107145526851

向app注入代码,成功弹出数据

<script>alert(/Hello Word/)</script>

image-20221107145809534

其他要求是通过注入代码达到开启其他app的效果,但是没找到相关资料没能复现成功

part7-Network Layer Security

任务:绕过证书检测

SslPinning

使用objection hook即可,和安卓端的思路一样

objection --gadget DVIA-v2 explore
ios sslpinning disable

手机配置burp的代理后发送请求,即可截获信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6AEi5uDa-1669259570834)(C:/Users/xinghe/AppData/Roaming/Typora/typora-user-images/image-20221107164149486.png)]

image-20221107164343709

image-20221107164401242

part8-Application Patching

任务:绕过一些特定的检测

Login Method 1

在ida中查看方法也能看到账号密码,但是任务要求我们要用hook的方式通关。定位到检测登录的代码,关键处理逻辑跟前面一样也是if判断,直接hook结果

frida-trace -U -i "*ApplicationPatching*" DVIA-v2  #定位触发函数

image-20221107171426912

image-20221107171458788

hook代码

var targetModule = 'DVIA-v2';
var addr = ptr(0x1AC1B4);
var moduleBase = Module.getBaseAddress(targetModule);
var targetAddress = moduleBase.add(addr);
   Interceptor.attach(targetAddress, {
        onEnter: function(args) {
                if(this.context.x8 == 0x00){
                    this.context.x8=0x01
                    console.log("Bypass OK");
            }
        },
    });

image-20221107175553488

剩下的关卡也是和前面一样hook,就不做演示

总结

在练习这个DVIA-v2靶场的时候可借鉴的学习资料太少,IOS独有的漏洞还不太了解。因为swift和object-c语言自己平时也没接触,不熟悉app的开发语法,信息在app之前的传输、保存、读取等操作。但有些漏洞其实和安卓的大差不差,移动安全主要偏向于隐私保护,不能让其他未授权的app轻易读取敏感数据文件。后面的学习中可能会偏向于IOS的app开发,了解基础语法和权限申请、数据传递等知识。

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

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

相关文章

【App自动化测试】(五)移动端自动化常用的元素定位工具——Uiautomatorviewer、 ATX WEditor、Appium Inspector

目录1. uiautomatorviewer1.1 uiautomatorviewer 的安装1.2 uiautomatorviewer 工具功能介绍1.3 uiautomatorviewer 的使用方法2. ATX WEditor2.1 ATX WEditor的安装2.2 ATX WEditor 功能介绍2.3 ATX WEditor 的使用3. Appium Inspector3.1 Appium Inspector安装与运行3.2 Appi…

【AWS系列】第八讲:AWS Serverless之S3

目录 序言 1.基础介绍 1.1 概念介绍 1.2 原理介绍 1.3 应用场景 1.3.1 构建数据湖 1.3.2 备份和还原关键数据 1.3.3 以最低成本存档数据 1.3.4 运行云原生应用程序 1.4 S3 的功能 1.4.1 存储类 1.4.2 存储管理 1.4.3 访问管理 2 使用方法 2.1 创建存储桶 ​2.2…

用DIV+CSS技术设计的网页与实现制作【体育文化】dreamweaver学生网页设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

day074:XML、XML的解析

目录 一、XML 1.什么是XML 2.XML作用 3.XML语法规则 4.XML文件代码示例 二、解析XML文件 1.解析XML 2.常用的解析思想 &#xff08;1&#xff09;DOM思想 &#xff08;2&#xff09;图解 3.XML解析工具 一、XML 1.什么是XML XML&#xff08;EXtensible Markup Lan…

【已解决】CentOS7等linux系统时区时间不对显示误差8小时

文章目录问题解决处理时区问题date查看时间、时区timedatectl查看时间、时区查看localtime设置时区处理时间问题问题 中国使用的是东八区上海时间&#xff0c;而linux服务器&#xff0c;一般默认是0时区UTC&#xff0c;所以需要将时区改为东八区CST将时区改为东八区后&#xf…

机器学习-决策树算法

机器学习-基础知识 机器学习-线性回归 机器学习-逻辑回归 机器学习-聚类算法 机器学习-决策树算法 机器学习-集成算法 机器学习-SVM算法 文章目录1. 决策树算法1.1. 什么是决策树/判定树1.2. 决策树归纳算法1.3. 熵概念1.4. 具体算法1.5. 决策树剪枝1.6. 连续值与缺失值处理1.6…

MCE | 正确认识阿尔茨海默病

什么是阿尔茨海默病 (Alzheimer Disease, AD)&#xff1f; 1907 年德国神经病理学家阿尔茨海默 (Alois Alzheimer) 仔细描述了一名具有进行性痴呆表现的 51 岁妇女 (Auguste Deter) 的症状&#xff1a; “她的记忆力严重受损。如果向她显示了对象&#xff0c;她会正确地命名它…

还在调API写所谓的AI“女友”,唠了唠了,教你基于python咱们“new”一个(深度学习)

文章目录前言停用词闲聊语料基础知识词的表示表达one-hot编码词嵌入大致原理实现简单版复杂版如何训练转换后的形状RNN循环网络RNNRNN投影图RNN是三维立体的LSTM&GRU构建数据配置数据集准备分词划分数据集加载模型搭建基本概念Encoder搭建DecoderAttention机制decoder与bea…

赫夫曼树赫夫曼编码的创建

目录基础知识点最优二叉树如何构造赫夫曼树赫夫曼编码编码与压缩文件代码结构体设计创建赫夫曼树创建构建赫夫曼编码基础知识点 赫夫曼树又称为最优树&#xff0c;是一种带权路径长短最短的树&#xff0c;有着广泛的应用。 最优二叉树 我们给出路径和路径长度的概念。从树的…

盘点面试常见的设计类算法问题

设计问题也是一种很重要的考察类型&#xff0c;特征是整体难度不大&#xff0c;但是要求结构合理、复用性好、考虑周全&#xff0c;代码规范等等。有些面试官不喜欢烧脑的动态规划等问题&#xff0c;就喜欢设计题&#xff0c;笔者曾经在面试微博和猿辅导都遇到过类似的问题。这…

【操作系统】2.1 进程与线程总结

2.1.1 操作系统之进程的定义、特征、组成、组织 2.1.1 操作系统之进程的定义、特征、组成、组织_StudyWinter的博客-CSDN博客 进程由程序段、数据段、进程控制块&#xff08;PCB&#xff09;三部分组成。 进程是进程实体的运行过程&#xff0c;是系统进行资源分配和资源调度的…

隆化的大米排之首 国稻种芯·中国水稻节:河北承德十大特产

隆化的大米排之首 国稻种芯中国水稻节&#xff1a;河北承德十大特产 中新网河北新闻10月8日电 (张桂芹 王思明) 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xf…

python基础项目实战-俄罗斯方块

一、俄罗斯方块游戏设计分析: 俄罗斯方块是一款风靡全球,从一开始到现在都一直经久不衰的电脑、手机、掌上游戏机产品,是一款游戏规则简单,但又不缺乏乐趣的简单经典小游戏,上手容易,适用范围广泛,人所共知。俄罗斯方块游戏基本规则是油4个小方块组成的7种不同的规则图形…

DevOps持续部署的关键要素

当有版本通过持续集成流水线进行构建之后&#xff0c;就可以将其部署至某个具体的环境&#xff0c;这就需要自动化部署技术&#xff0c;将这个自动化部署和持续集成流水线连接起来&#xff0c;就可实现持续部署。如图1所示&#xff0c;实现持续部署的前提是至少拥有一条完整的自…

mipi phy理解

MIPI 接口广泛用于摄像头,和显示部分;PHY 属于 MIPI 接口的最底层部分,也就是物理层,直接涉及到物理连线,信号传输等等,要搞清楚 MIPI 的数据传送,那么从 PHY 入手了解,是一个不错的选择;在 PHY 上,只负责定义数据物理层的收发标准; MIPI 的 PHY 分为了 3 种: D-P…

BartForConditionalGeneration的使用细节

输入到 BartForConditionalGeneration 类的各个参数是什么意思&#xff1f; decoder_input_ids 是必须要以 <s> 开头的。这个参数可以自己生成然后传入到模型中&#xff0c;也可以交由代码自己生成&#xff08;一般会根据label右移一位再补0&#xff09; case 1&#x…

ImmunoChemistry艾美捷细胞内GSH测定试剂盒方案

用ImmunoChemistry艾美捷细胞内GSH测定评估细胞内谷胱甘肽水平的变化。这种全细胞谷胱甘肽测定采用专有的硫醇敏感染料ThioBright™ 绿色&#xff0c;以监测游离形式谷胱甘肽&#xff08;即GSH&#xff09;浓度的相对变化。通过流式细胞术分析荧光信号。 谷-胱-甘肽&#xff0c…

​DPDK 高效原因初探

Linux处理Packets主逻辑 系统接受数据包的过程 当网卡收到第一个包时候,通过DMA把这个包发送给接受队列(rx)系统通过中断的方式通知新数据包的到来,同时也需要把数据包传递给内核的buffer(每个包一个buffer,sk_buff struct).一个数据包到来会触发多次的中断&#xff0c;内核处…

.net-----语言集成查询LINQ

语言集成查询LINQ前言相关语言要素初始值设定项匿名类型相关语言要素Lambda表达式扩展方法LINQ的概念和基本操作集成语言查询LINQLINQ查询操作标准查询运算符数据排序数据筛选数据投影数据分组联接运算数据分区限定运算聚合运算集合运算生成运算元素操作串联运算相等运算数据类…

【新知实验室 基于WEB的实时音视频(TRTC)案例搭建】

文章目录1. 实时音视频&#xff08;TRTC&#xff09;1.1 实时音视频(TRTC)概述1.2 实时音视频(TRTC)功能集成1.2.1 含 UI 组件集成方案1.2.2 无 UI 组件集成方案1.3 实时音视频(TRTC)架构2. 使用体验2.1 注册腾讯云2.2 申请实时音视频(TRTC)应用2.3 下载SDK的Demo源码2.4 获取 …