upload-labs通关练习---更新到15关
目录
环境搭建
第一关
方法一 修改文件类型
方法二 前端禁用JS绕过
第二关
方法一 修改Content-Type类型
方法二 修改上传文件类型
第三关
第四关
第五关
方法一 Windows大小写绕过
方法二 利用.user.ini
第六关
第七关
第八关
第九关
第十关
第十一关
第十二关
第十三关
第十四关
第十五关
环境搭建
upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助网络攻防初学者对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。
靶场链接:https://github.com/c0ny1/upload-labs/releases/tag/0.1
具体搭建参考过程如所示:https://blog.csdn.net/2302_80946742/article/details/137714313?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-137714313-blog-135903159.235^v43^pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.1&utm_relevant_index=3
第一关
方法一 修改文件类型
该关卡是通过前端验证,前端验证通过之后再上传文件,上传文件的过程不进行过滤。所以我们可以先将PHP文件改为PNG,绕过前端JS验证,通过之后使用BurpSuite抓取上传文件的数据包,并将文件类型改为PHP继续上传。
先准备一句话木马如下,文件类型PNG
此后尝试上传文件,并且通过后台BurpSuite抓取上传文件的数据包,并将其进行修改。
对回显的图片右键可以获取图片地址,之后可以通过一些链接工具进行连接测试。由于是在本地搭建,通过查看路径发现文件已经上传成功。
方法二 前端禁用JS绕过
在游览器按F12打开页面审查,找到设置里面Disable JavaScript点击禁用。之后就可以上传PHP文件。
第二关
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
MIME 的组成结构非常简单,由类型与子类型两个字符串中间用 / 分隔而组成,不允许有空格。type 表示可以被分多个子类的独立类别,subtype 表示细分后的每个类型。MIME类型对大小写不敏感,但是传统写法都是小写。
这一关不再进行前端验证,通过查看提供的源码,我们发现他是一个在服务端对数据包的MIME进行验证,并且发现只对文件的Content-Type类型有限制:`if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {`:检查上传的文件是否为 JPEG、PNG 或 GIF 格式的图像文件。如果不是这些格式,会提示用户文件类型不正确并要求重新上传。
方法一 修改Content-Type类型
我们可以上传PHP文件,之后通过BurpSuite抓取上传文件的数据包,将Content-Type类型改为image/jpeg、image/png、image/gif(三种任选其一),重新发包。
方法二 修改上传文件类型
我们可以上传图片文件,之后通过BurpSuite抓取上传文件的数据包,将文件的后缀改为PHP即可。
第三关
通过直接上传PHP文件返回发现会提示黑名单,即扩展名检测机制,后端利用$_FILES()和strrchr()获取文件名后缀。由于是黑名单限制且名单不完整,其实可以采用一些方法绕过。比如在某些特定环境中某些特殊后缀仍会被当作php文件解析的扩展名有:php、php2、php3、php4、php5、php6、php7、pht、phtm、phtml
。
通过分析源代码我们发现,代码修改了文件名称,生成一个新的文件路径,包括上传路径、当前时间戳和随机数以及文件后缀,以确保文件名的唯一性。但是由于可以直接在前端获取文件名称,所以这一步并没有对后续操作进行限制。
第四关
通过直接上传PHP文件返回发现会提示黑名单,即扩展名检测机制,和第三关不一样的是基本上限制了所有可用的文件类型。但是还有一种文件类型可以利用,即.htaccess
文件。
.htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。.htaccess主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。.htaccess的用途范围主要针对当前目录。并且该文件的优先级比较高,甚至高于Apache的主要配置文件(httpd-conf)
创建.htaccess
文件代码如下,这个代码的作用是,如果当前目录下有.png
的文件,就会被解析为.php
,成功上传。
<FilesMatch ".png">
SetHandler application/x-httpd-php
</FilesMatch>
再上传一个一句话木马,文件名为 test.png,依旧访问 test.png,但其会以 PHP形式显示
第五关
通过查看源码发现依然是黑名单过滤,但是过滤的文件类型更加齐全,不能使用.htaccess
文件。由于本机环境是在Windows下进行的,所以此时就可以尝试使用大小写绕过限制上传文件,或者是使用`.user.ini
配置文件。
方法一 Windows大小写绕过
通过分析源码发现和之前几关相比,少了一段代码$file_ext = strtolower($file_ext); //转换为小写
在这行代码中,strtolower
函数被用于将变量$file_ext
所包含的字符串转化为全小写。所以可以修改PHP文件的后缀大小写从而实现绕过。大小写绕过原理:
Windows系统下,对于文件名中的大小写不敏感。例如:test.php和test.PHP是一样的。Linux系统下,对于文件名中的大小写敏感。例如:test.php和 test.PHP就是不一样的。
方法二 利用.user.ini
它比.htaccess 用的更广,不管服务器是 nginx/apache/IIS,当使用 CGI/FastCGI 来解析 php 时,php 会优先搜索目录下所有的.ini 文件,并应用其中的配置。作用:特定用于用户或者特定目录的配置文件,通常位于Web应用程序的根目录下。类似于 apache 的.htaccess,但语法与.htacces 不同,语法跟php.ini一致,并且.user.ini先级较高。内容如下:auto_prepend_file=test.png
再上传一个内容为 php 一句话脚本,命名为 test.png。.user.ini
文件作用:所有的 php 文件都自动包含 test.png文件。.user.ini
相当于一个用户自定义的 php.ini。但是由于当前环境不符合该条件,所以该方法不能进行测试。
注意应用前提是:
-
版本选择最好大于5.3.0,最好是7.x的版本;
-
并且Server API 为CGI/FastCGI;
-
.user.ini
可以生效,并且该目录下有PHP文件;
第六关
分析源代码我们发现,相比于之前的代码,次出少了部分内容$file_ext = trim($file_ext); //首尾去空
并没有对文件后缀名进行首尾去空的操作。这一行代码使用了PHP的trim
函数对变量$file_ext
所存储的字符串进行处理。trim
函数的作用是去除字符串首尾的空白字符(包括空格、换行符、制表符等),所以这里可以通过对文件后缀名末尾进行添加空格的方式来进行绕过。
Windows 系统下,对于文件名中空格会被作为空处理,程序中的检测代码却不能自动删除空格。从而绕过黑名单。
所以可以通过BurpSuite抓取上传文件的数据包,通过在文件名称后面添加空格来绕过判断。
第七关
通过对比前几关的源码,发现少了$file_name = deldot($file_name);//删除文件名末尾的点
。该代码主要是去除文件名后面的点。并且windows等系统默认删除文件后缀的.和空格,没有过滤点。
因为代码是通过拼接合成文件,使用$file_ext = strrchr($file_name, '.');
,通过查找文件名中最后一个点来获取文件后缀。并且之后对文件后缀进行大写转小写。之后随机文件名称 + 修改后的后缀拼接文件名称。所以我们可以通过BurpSuite抓取上传文件的数据包,在filename
最后面添加.
来将文件名称33.php
改为33.php.
。此时文件名称为33.php
,文件后缀为空。
第八关
通过分析源码,发现与之前相比发现少了对上传的文件后缀名为做去::$DATA 处理的过程,上传到服务器的文件在Windows中会自动去掉::$DATA。
利用Windows特性
-
在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名。
-
例如:"phpinfo.php::$DATA"Windows会自动去掉末尾的::$DATA变成"phpinfo.php"
所以可以通过BurpSuite抓取上传文件的数据包,在filename
最后面添加::$DATA
来绕过检查文件后缀名称。
第九关
通过分析代码发现,将文件名进行过滤操作后,将文件名拼接在路径后面,所以需要绕过前面的首尾去空以及去点。
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空if (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}
代码首先获取文件全称,之后通过deldot函数删除文件末尾出现的点,之后会基于.
进行分割获取文件后缀。并且将后缀转小写、去除字符串::$DATA、首位去除空格。完成一系列操作之后会将文件名称存储到upload文件夹下。它只去掉一次空格
和点
,举个例:测试.php. .
最后代码执行完后变成 测试.php.
。所以可以构建$file_name=33.php
,即通过BurpSuite抓取上传文件的数据包,修改文件名称格式为点+php+点+空格+点
。
第十关
通过分析代码发现$file_name = str_ireplace($deny_ext,"", $file_name);
,利用str_ireplace()将文件名中符合黑名单的字符串替换成空。但是只替换了一次,所以可以尝试双写后缀绕过。
注意str_ireplace()函数一下特点:
-
该函数必须遵循下列规则:
-
如果搜索的字符串是一个数组,那么它将返回一个数组。
-
如果搜索的字符串是一个数组,那么它将对数组中的每个元素进行查找和替换。
-
如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换
-
如果是对一个数组进行查找,但只对一个字符串进行替换,那么替代字符串将对所有查找到的值起作用。
注释:该函数不区分大小写。请使用 str_replace()函数来执行区分大小写的搜索。
-
基于以上规则修改文件类型,将原本33.php
,修改为33.pphphp
,进行测试。
第十一关
通过分析代码发现$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
:定义上传文件的目标路径,通过获取 URL 参数中的保存路径($_GET['save_path']
),并结合随机数、当前时间戳和文件后缀名生成唯一的文件名,所以可以通过控制文件路径,将其截断,将图片中的PHP代码存入其中。
通过BurpSuite抓取上传文件的数据包,修改设置save_path
参数内容为upload/test.php%00
,添加test.php%00
内容为了控制路径,上传文件后缀为白名单即可,上传一个文件后缀问白名单中的后缀的PHP文件。保存后为/upload/test.php%00*****.png
,但服务端读取到%00时会自动结束,将文件内容保存至test.php中。
PS:需要 php 的版本号低于 5.3.29,且 magic_quotes_gpc 为关闭状态。
第十二关
该关卡依然使用白名单限制上传文件类型,但上传文件的存放路径可控,但因为是 POST 型,需要在 16 进制中修改,因为 POST 不会像 GET 那样对%00 进行自动解码。
第十三关
分析代码getReailFileType()函数
function getReailFileType($filename){}:定义一个函数,用于获取文件的真实类型。
$file = fopen($filename, "rb");:以二进制只读模式打开文件。
$bin = fread($file, 2); //只读 2 字节:读取文件的前两个字节。
fclose($file);:关闭文件。
$strInfo = @unpack("C2chars", $bin);:将读取的两个字节解包为一个关联数组。
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);:将两个字节组合成一个整数,作为文件类型代码。
$fileType = '';:初始化文件类型变量。
switch($typeCode){...}:根据文件类型代码判断文件类型,并设置相应的文件类型字符串。
return $fileType;:返回文件类型。
通过读文件的前 2 个字节,检测上传文件二进制的头信息,判断文件类型,利用010 Editor变写图片内容为一句话木马从而绕过检测。并且后端会根据判断得到的文件类型重命名上传文件,之后通过文件包含漏洞进行连接。
常见图片文件二进制:Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNGJpg图片文件包括2字节:FF D8。Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。Bmp图片文件包括2字节:42 4D。即为 BM
可以使用010 Editor查看图片马的内容
将这个文件上传到服务器之后,通过利用文件包含漏洞去包含这个图片文件以便于执行PHP代码。
第十四关
通过分析代码发现,代码首先定义了允许的图像文件类型扩展名的字符串 $types
。然后通过 file_exists
函数检查文件是否存在。如果存在,使用 getimagesize
函数获取文件的图像相关信息(如宽度、高度、图像类型等),接着通过 image_type_to_extension
函数将获取到的图像类型转换为对应的文件扩展名。最后通过 stripos
函数检查转换后的扩展名是否在允许的类型字符串中,如果是则返回该扩展名,否则返回 false
。如果文件不存在,也直接返回 false
。
图片马可以通过cmd直接制作命令格式为:copy logo.jpg/b+test.php/a test.pnglogo.jpg为任意图片;test.php 插入的木马文件;test.jpg 生成的图片木马
之后在网页直接上传文件,利用文件包含漏洞进行包含图片,并且通过蚁剑连接。
第十五关
分析代码发现与之前的相比exif_imagetype()读取一个图像的第一个字节并检查其后缀名。返回值与getimage()函数返回的索引2相同,但是速度比getimage快,并且判断更加严格。
相关文章:

upload-labs通关练习---更新到15关
目录 环境搭建 第一关 方法一 修改文件类型 方法二 前端禁用JS绕过 第二关 方法一 修改Content-Type类型 方法二 修改上传文件类型 第三关 第四关 第五关 方法一 Windows大小写绕过 方法二 利用.user.ini 第六关 第七关 第八关 第九关 第十关 第十一关 第十二…...
WPF 应用程序中使用 Prism 框架时,有多种方式可以注册服务和依赖项
Prism 提供了更多的注册方式,适应不同的需求和场景。下面我会全面列出 IContainerRegistry 提供的所有常见注册方式,并附带相应的示例。1. 注册单例(Singleton) 注册单例类型服务,整个应用生命周期内只会创建一个实例&…...

【ESP32】ESP-IDF开发 | 低功耗管理+RTC唤醒和按键唤醒例程
1. 简介 ESP32支持5种低功耗模式,低功耗管理单元包括调压器、功耗控制器、电源开关单元、电源域隔离单元 (Isolation Cell) 等部分。 1.1 RTC单元 RTC单元是ESP32低功耗管理的核心,可用于管理低功耗模式的进入和退出,控制时钟源、PLL、电源开…...

Windows 局域网IP扫描工具:IPScaner 轻量免安装
IPScaner是一款258KB的工具,具备快捷修改IP、批量扫描、地址计算等功能,自动识别本机IP网段,快速查看IP使用情况,适用于监控维护、企业IT运维等场 软件功能介绍: 1)快捷修改本地IP、IP批量扫描、IP地址计算…...
HTML的浮动与定位
1. 浮动 浮动可以使一个元素脱离自己原本的位置,并在父元素的内容区中向左或向右移动,直到碰到父元素内容区的边界或者其它浮动元素为止。 值描述left元素向左浮动right元素向右浮动 普通文档流:浏览器在默认情况下规定一个块元素在父元素…...
【网络安全 | 漏洞挖掘】我如何通过路径遍历实现账户接管
未经许可,不得转载。 文章目录 不久前,我发现了一个我在高中时非常常用的知名应用程序,它在Intigriti上是一个私有程序,本文称之为REDACTED。 我开始参与REDACTED的漏洞赏金计划,这个应用程序在我开始进行黑客攻击之前我已经非常熟悉了。最初我并没有抱太高的期望。 我首…...

DB-GPT系列(四):DB-GPT六大基础应用场景part1
一、基础问答 进入DB-GPT后,再在线对话默认的基础功能就是对话功能。这里我们可以和使用通义千问、文心一言等在线大模型类似的方法, 来和DB-GPT进行对话。 但是值得注意的是,DB-GPT的输出结果是在内置提示词基础之上进行的回答,…...

SpringCloud篇(服务拆分 / 远程调用 - 入门案例)
目录 一、服务拆分原则 二、服务拆分示例 1. 案例需求 2. 案例要求 3. 导入SQL语句 4. 实现思路 4.1. 创建父工程 cloud-demo 管理依赖 依赖导入思路 4.2. 创建子工程 order-servic 4.3. 创建子工程 user-servic 4.4. 创建 cloud_order 数据库和表并插入数据 4.5. …...
Rust 建造者模式
在DDD中,DTO(数据传输对象)->BO(业务对象)、BO(业务对象)->PO(持久化对象,有的叫DO,即和数据表映射的实体)等等情况要做转换,这里提供以下转换方式 1、from或者try_from trait实现对象转换 需要转换对象满足接收对象的所有…...
ANN DNN CNN SNN
这些缩写代表了不同类型的人工神经网络: • ANN(Artificial Neural Network):人工神经网络,是模仿人脑神经元之间连接和交互方式的计算模型。它由节点(或称为“神经元”)组成的网络,…...
go语言进阶之并发模式
并发模式 并发模式是指在程序设计中同时处理多个任务或进程的方式,以提高效率和响应性 for select循环模式 for select循环模式通常用于处理并发操作,尤其是在需要等待多个通道时。 select的执行过程主要是以下几步 阻塞等待,直到其中一…...
Spring Cloud LoadBalancer:负载均衡的服务调用
在微服务系统中,有时候一个服务会部署多个实例,在我们调用这类实例时,如何实现负载均衡的调用呢?这时候就要用到Spring Cloud的负载均衡组件LoadBalancer了 LoadBalancer简介 LoadBalancer是Spring Cloud官方提供的负载均衡组件,通过它能使客户端在多个服务实例之间分发传…...

微信小程序之轮播图
效果图 实现 <swiper class"banner" indicator-dots"true" indicator-color"rgba(255,255,255,1)" indicator-active-color"#ff0000" autoplay"true" interval"100" circular"true"><swi…...
羲和数据集收集器1.3
为了实现所要求的功能,我们需要进一步完善代码,使其能够处理多种格式的输入文件,并生成符合要求的 JSON 格式的输出文件。具体来说,我们完善了以下内容: 增强 extract_qa_pairs_from_content 函数:使其能够识别和处理不同格式的 QA 对。 确保输出文件的格式正确:每个 Q…...
UE--IOS打包失败 AutomationTool exiting with ExitCode=9 (9)
[Remote] Executing build UATHelper: 打包 (IOS): Setting up bundled DotNet SDK UATHelper: 打包 (IOS): /Users/zyh/UE5/Builds/DESKTOP-FKKSVFQ/Y/UE/UE_5.2/Engine/Build/BatchFiles/Mac/../../../Binaries/ThirdParty/DotNet/6.0.302/mac-x64 UATHelper: 打包 (IOS)…...

第8章利用CSS制作导航菜单
8.1 水平顶部导航栏 水平菜单导航栏是应用范围最广的网站导航设计,一般位于页面顶部。它适用性强,几乎适用于所有类型的网站,且设计难度低。若导航过于普通,无法承载复杂信息结构,在内容模块较多时,则需结…...

UNIX网络编程-TCP套接字编程
概述 TCP客户端/服务器程序示例是执行如下步骤的一个回射服务器: 客户端从标准输入读入一行文本,并写给服务器。服务器从网络输入读入这行文本,并回射给客户端。客户端从网络输入读入这行回射文本,并显示在标准输出上。 TCP服务器…...

美团代付微信小程序 read.php 任意文件读取漏洞复现
0x01 产品描述: 美团代付微信小程序是美团点评旗下的一款基于微信小程序技术开发的应用程序功能,它允许用户方便快捷地请求他人为自己支付订单费用。通过微信小程序,用户可以轻松实现代付操作,无需跳转到其他应用或网页…...

centos7 node升级到node18
使用jenkins发布vue3项目提示node18安装失败 错误日志: /var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node18/bin/node: /lib64/libm.so.6: version GLIBC_2.27 not found (required by /var/lib/jenkins/tools/jenkins.plugins.node…...

使用Matlab建立随机森林
综述 除了神经网络模型以外,树模型及基于树的集成学习模型是较为常用的效果较好的预测模型。我们以下构建一个随机森林模型。 随机森林是一种集成学习方法,通过构建多个决策树并结合其预测结果来提高模型的准确性和稳定性。在MATLAB中,可以…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...