Living@Greatwall

性能测试工具-locust

locust是一款开源的性能测试工具,采用python编写,适应于web性能测试,以及各种C/S结构的系统性能测试(这也是我为什么要用这个的原因,非常适用于自己构建的c/s系统,比loadrunner更适合定制化需求,只需自己实现客户端即可)。

locust测试框架中,测试场景完全是采用纯python语言来描述的,其在模拟并发方面是使用gevent的非阻塞IO和协程来实现的,并发较高。locust支持单进程部署和多进程分布式(master-slave模式)部署,单进程下只能充分利用一个core的能力,多进程分布式下能充分利用多核或者多个机器的能力。 官网地址: locust

Buffer Overflow Attack实验

这是cmu经典课程csapp的实验之一,主要任务是对课程提供的bufbomb程序进行buffer overflow攻击,以帮助我们深入理解x86 IA-32体系结构的函数调用惯例和栈组织结构,从而认识到这种攻击方法的本质,对我们编写安全的系统级代码非常有好处。这些实验同时也展示了如何攻击操作系统和网络服务器的安全弱点。

实验提供了以下3个可执行文件:

  • bufbomb: 这是我们要攻击的目标程序;
  • makecookie:根据用户id生成一个唯一的cookie,这个主要是防止抄袭作业:);
  • hex2raw:将16进制的ascii值转换称对于的ascii字符;

bufbomb程序会从标准输入中读取一个字符串,调用getbuf函数:

/* Buffer size for getbuf */
#define NORMAL_BUFFER_SIZE 32

int getbuf()
{
    char buf[NORMAL_BUFFER_SIZE];
    Gets(buf);
    return 1;
}

显然如果用户输入的字符串长度大于31时,就会破坏bufbomb的栈,如果在输入的字符串中带有特殊的地址和指令,就达到了攻击目的。下面的几个实验任务都是需要在这个字符串中嵌入特殊的指令和地址来完成实验任务。

Test 1: Candle

bufbomb中函数test会调用getbuf,如下:

 void test()
 {
     int val;
     /* Put canary …

Makefile函数

利用Makefile自带的函数能更一部精简我们的Makefile的编写,下面介绍一下常用的几个函数。

1. 通配符函数wildcard

Makefile中通配符扩展是在规则中自动进行的,但是如果要对一个变量进行类似的操作时,我们就需要使用这个wildcard 这个函数来进行扩展,用法如下: $(wildcard pattern...) 这个函数会将符合这个pattern模式的所有文件以空格为分隔符列出来,例如我们要获取src目录下所有的.c文件,则实现为: SRC = $(wildcard *.c) 假设src目录下有a.c和b.c两个文件,那么SRC相当于如下: SRC = a.c b.c

2. 字符串操作函数

常用的有notdir, subst, patsubst, strip, filter, findstring等。

1) $(notdir text) notdir用于去掉字符串中路径名,如:

NO_DIR = $(notdir src/a.c)

也就等同于:

NO_DIR = a.c

2 …

利用Debugfs调试linux kernel

调试内核的方法很多,debugfs就是其中一种利用虚拟文件系统来调试内核的方法之一,debugfs与profs,sysfs类似, 是一种虚拟文件系统。默认情况下,debugfs文件系统挂载在/sys/kernel/debug/目录下,也可用手动命令来加载: mount -t debugfs none //debugfs

下面的示例将建立一个内核模块debugfs_hello,并在该内核模块中调用debugfs的API创建下面3个值: /sys/kernel/debug/debugfs_hello/hello /sys/kernel/debug/debugfs_hello/add /sys/kernel/debug/debugfs_hello/sum 其中hello是一个可读写的整数值,即用户可用cat和echo命令来查看和修改该; add是可写的,当用户调用echo命令向其写入一个值,该值会被内核模块加到sum这个值中; sum是只读的,用于计算所有输入给add的值的总和,用户可用cat命令查看该值。

#include <linux/module.h>
#include <linux/kernel.h …

如何在linux内核模块中加入netlink通信接口

与系统调用,/proc,sysfs等类似,netlink也是一种用于用户进程与内核通信的机制,它是基于BSD套接字协议, 使用AF_NETLINK地址簇。 与系统调用,proc,sysfs文件系统等方式相比,netlink具有简单,支持双向通信的特点,并支持消息多播机制。 当我们编写内核驱动并需要与用户进程通信时,我们便能利用netlink来实现这个通信机制。hostapd(一个无线 AP的dameon)中就是采用netlink接口(nl80211)与内核进行通信,下文将通过一个实例来说明如何在自己的内核 模块中支持netlink通信。

1. 编写内核模块

首先编写内核模块文件:netlink_hello_mod.c,并增加相应的makefile,代码如下:

netlink_hello_mod.c:

#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>

#define MY_NETLINK_TYPE 31 …

Google's Python Class

粗略看过一些python教材,还是觉得google出品的python class比较好,内容突出重点,同时提供了一些练习项目可做, 感兴趣的可去Google Developer瞧瞧:Google's Python Class

如果翻不了墙的话可以去我github看看google提供的练习题:My Github,等 哪天有时间了会在我的blog上提供这些课程的中文版。

一款很好用的报文流量生成和分析工具:Ostinato

最近测试一个功能需要用到报文生成工具来打流量,公司虽然有高大上的打流量利器Ixia,但是杀鸡焉用牛刀!于是找出了很早就用的 ostinato,但是由于要生成一系列的报文(ICMP的各种type和code),用这个工具得手工一个一个来制造这些icmp报文,想着都麻烦, 立马想到这个工具是否支持脚本自动化,于是goole了一下这个工具,发现其最新版本支持自动化部署,提供了python接口,顿时心情大好。

Ostinato是一个采用QT写的跨平台的工具,支持window/linux,作者要把该工具打造为:Wireshark in Reverse,足见作者的野心!不过 该工具确实很好用,可以方便的构造各类报文。

Ostinato采用agent-controller架构:ostinato是GUI agent,drone是controller,另外支持用户使用python-ostinato模块来打造自己的 agent,用户写的agent与controller之间的通讯是采用google的protocol buffers结构化数据,下面是该工具的官方网站:

Ostinato

贴上用python写的与drone交互的script:

#! /usr/bin/env python
# This is a tool script used with Ostinato to generate …

const修饰变了能否被修改

今天无意中想到一个问题,const修饰的变量能否被修改,虽然修改const变量是个不好的习惯, 但是仍想去验证一下这个问题。 const一般用于修饰变量或者函数参数,用于函参修饰指针时表示函数不会改变该指针指向 的变量的值,一个经典的问题就是:const int *p 与 int * const p的区别。在c++中, const还用于修饰成员函数,表示该成员函数不能修改成员变量,只能修改mutable类型的 成员变量。 看下面一段测试代码,g为全局常量,a为局部常量,下面分别通过指针去修改这两个变量的 值,下面程序执行到最后修改g变量时出现segmentation fault,也就是说能修改局部常量, 但不能修改全局定义的常量,因为g是保存在只读数据段.rodata里。 (使用gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2,运行在 Intel(R) Core(TM) i7-3770 CPU)

const int g …

ptmalloc内存管理解析

1. 简介

内存管理是操作系统比较复杂的一环,对系统的性能有着关键性的作用,内存管理的知识涉及到内存分配算法,硬件的内存管理单元, 如MMU,Cache等单元。本文将简单分析一下我们使用的最多的mallc/free,这两个库函数是由glibc库提供的,通过调用系统的 sbrk和mmap来实现(小内存使用sbrk,大内存使用mmap)。glibc库的mallc最开始 是由Doug Lea实现的(也称dlmalloc),但由于其对并行多线程支持不好,所以后来在dlmalloc的基础上出现了ptmalloc,能较好的 支持编程,现在glibc使用的是ptmalloc3,也是本文分析的对象。另外,google自家也提供了一个malloc实现叫tcmalloc,性能比前面的都好,留待以后研究。

2. 内存管理设计目标

衡量内存管理算法优劣的主要指标有如下几点:

  • 分配与释放的快慢:主要考虑算法复杂度,如何利用局部性原理,并行无锁设计,cache的友好性;
  • 内存碎片:如何尽可能的减少内存碎片,这跟分配算法相关,以及释放时如何合并等;
  • 回收机制:高级语言都自带回收机制,主要算法有引用计数,Mark&Sweep,分代机制(利用对象的生存期)等;
  • 跨平台可移植性 …

gcc -Wshdow选项

今天写LRU算法时遇到一个crash问题,代码如下:elem自动变为NULL,看了一会没找到elem为什么会变成null(很简单的手误,一眼就能看出来),上gdb,反汇编看看,果然一下就看出问题了,是个重复定义的问题,(但是g++编译器怎么没报错???后面解释),最开始I定义的elem地址为[ebp-0x20],后面定义的一个elem地址为[ebp-0x1c](函数局部变量都是通过ebp基址寄存器加偏移来获取的,栈向低地址生长)。

img1

img2

关于编译器为什么没报错,在stackoverflow上看到了答案:c89/90/99和c++标准都允许这么做(查了下c99标准,讲得比较晦涩)。标准把这个叫做块作用域(block scope),一个block是包含在一对{}符号里面的代码,可嵌套(一个block内可保护另一个block),在一个block内定义的变量,该变量在整个block(包括内部嵌套的block都是可见的accessible),但是block之外是不不可见的,下面的代码编译会出错的:

{
    int  a = 10;
    ....
}
a = 11; //Comple error,a not declared

但是如果内嵌的block里面有一个变量与当前block里面的变量名一样怎么办 …