pwnable的新一题,和堆分配相关。

http://pwnable.kr/bin/memcpy.c

ssh memcpy@pwnable.kr -p2222 (pw:guest)

我觉得主要考察的是堆块分配问题。

推荐《C和C++安全编码》

首先通过阅读源代码,看一下题目大意。

// compiled with : gcc -o memcpy memcpy.c -m32 -lm
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h> unsigned long long rdtsc(){
asm("rdtsc");
} char* slow_memcpy(char* dest, const char* src, size_t len){
int i;
for (i=; i<len; i++) {
dest[i] = src[i];
}
return dest;
} char* fast_memcpy(char* dest, const char* src, size_t len){
size_t i;
// 64-byte block fast copy
if(len >= ){
i = len / ;
len &= (-); while(i-- > ){
__asm__ __volatile__ (
"movdqa (%0), %%xmm0\n"
"movdqa 16(%0), %%xmm1\n"
"movdqa 32(%0), %%xmm2\n"
"movdqa 48(%0), %%xmm3\n"
"movntps %%xmm0, (%1)\n"
"movntps %%xmm1, 16(%1)\n"
"movntps %%xmm2, 32(%1)\n"
"movntps %%xmm3, 48(%1)\n"
::"r"(src),"r"(dest):"memory");
dest += ;
src += ;
}
} // byte-to-byte slow copy
if(len) slow_memcpy(dest, src, len);
return dest;
} int main(void){ setvbuf(stdout, , _IONBF, );
setvbuf(stdin, , _IOLBF, ); printf("Hey, I have a boring assignment for CS class.. :(\n");
printf("The assignment is simple.\n"); printf("-----------------------------------------------------\n");
printf("- What is the best implementation of memcpy? -\n");
printf("- 1. implement your own slow/fast version of memcpy -\n");
printf("- 2. compare them with various size of data -\n");
printf("- 3. conclude your experiment and submit report -\n");
printf("-----------------------------------------------------\n"); printf("This time, just help me out with my experiment and get flag\n");
printf("No fancy hacking, I promise :D\n"); unsigned long long t1, t2;
int e;
char* src;
char* dest;
unsigned int low, high;
unsigned int size;
// allocate memory
char* cache1 = mmap(, 0x4000, , MAP_PRIVATE|MAP_ANONYMOUS, -, );
char* cache2 = mmap(, 0x4000, , MAP_PRIVATE|MAP_ANONYMOUS, -, );
src = mmap(, 0x2000, , MAP_PRIVATE|MAP_ANONYMOUS, -, ); size_t sizes[];
int i=; // setup experiment parameters
for(e=; e<; e++){ // 2^13 = 8K
low = pow(,e-);
high = pow(,e);
printf("specify the memcpy amount between %d ~ %d : ", low, high);
scanf("%d", &size);
if( size < low || size > high ){
printf("don't mess with the experiment.\n");
exit();
}
sizes[i++] = size;
} sleep();
printf("ok, lets run the experiment with your configuration\n");
sleep(); // run experiment
for(i=; i<; i++){
size = sizes[i];
printf("experiment %d : memcpy with buffer size %d\n", i+, size);
dest = malloc( size ); memcpy(cache1, cache2, 0x4000); // to eliminate cache effect
t1 = rdtsc();
slow_memcpy(dest, src, size); // byte-to-byte memcpy
t2 = rdtsc();
printf("ellapsed CPU cycles for slow_memcpy : %llu\n", t2-t1); memcpy(cache1, cache2, 0x4000); // to eliminate cache effect
t1 = rdtsc();
fast_memcpy(dest, src, size); // block-to-block memcpy
t2 = rdtsc();
printf("ellapsed CPU cycles for fast_memcpy : %llu\n", t2-t1);
printf("\n");
} printf("thanks for helping my experiment!\n");
printf("flag : ----- erased in this source code -----\n");
return ;
}

题目是这样的,首先请用户输入10个数字,分别位于2的各次幂之间。

输入之后,根据用户输入的数据使用malloc函数,在堆上请求大小为用户输入数据的堆块。

然后,分别用slow_memcpy和fast_memcpy两种方式,对堆块内的数据向另外一个内存地址拷贝,并比较二者时间。

slow_memcpy使用的是最复杂的循环赋值,而fast_memcpy使用的是汇编指令movdqa进行拷贝。

当全部10数字拷贝结束后打印flag。

坑点在于全部的以mmap申请的空间基本对题目没有什么影响。

先运行一下,随意输入10个符合要求的数字,运行终止,出现段错误

并不清楚为什么,使用gdb调试一下看看:

结果显示出错位置在fast_memcpy函数中的movntps汇编语句上

也就是说是movntps执行出了问题,各寄存器值如下:

具体看一下movntps是做什么的

movntps m128,XMM
m128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.

也就是把之前从src中拷贝到XMM寄存器中的数据传递给新申请的栈块。

要求是必须对其16字节

一.什么是字节对齐,为什么要对齐?
    现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

16字节对齐的意思就是地址的末位必须为0,比如0xabcdef10,就是16字节对齐。

所以出错的原因是edx中的数据非16进制对齐数据(0x804c4a8)

因此,这道题的关键是构造每次申请的堆块地址都是16进制对齐数据。

堆块是由链表结构组成的,dlalloc系列的堆块结构图和分配过程可参看《C和C++安全编码》,堆块有一明显特征是堆块除了用户数据外还有堆块大小和标志位共计4字节。而malloc分配的堆块大小是以8字节对其的。

假设用户申请的堆块大小是a的话,malloc(a)分配的堆块大小为 8*(int((a+4)/8)+1)。

因此假设第一个malloc分配地址是16字节对齐的,则每次请求大小为16字节对齐的数据块即可成功运行结束。

以如下脚本可检测是否,malloc分配的字节大小是16字节对齐的

# coidng  = utf-8
while(1):
a = raw_input()
a = int(a)
if (a+4)%16>=9 || (a+4)%16==0:
print a," is ok"
else:
print a," is wrong"

因此,只要每次输入数字前先用脚本测试一下,基本就可以通过验证。

服务器上的代码在另外一个文件夹下,用nc命令连接

nc 0 9022后就可以输入了:

在检测的python脚本里留下了许多不行的数据:

【pwnable.kr】 memcpy的更多相关文章

  1. 【pwnable.kr】 asm

    一道写shellcode的题目, #include <stdio.h> #include <string.h> #include <stdlib.h> #inclu ...

  2. 【pwnable.kr】 [simple login]

    Download : http://pwnable.kr/bin/login Running at : nc pwnable.kr 9003 先看看ida里面的逻辑. 比较重要的信息时input变量再 ...

  3. 【pwnable.kr】 brainfuck

    pwnable.kr第二关第一题: ========================================= Download : http://pwnable.kr/bin/bfDownl ...

  4. 【pwnable.kr】 unlink

    pwnable.kr 第一阶段的最后一题! 这道题目就是堆溢出的经典利用题目,不过是把堆块的分配与释放操作用C++重新写了一遍,可参考<C和C++安全编码一书>//不是广告 #includ ...

  5. 【pwnable.kr】 codemap

    pwnable新的一题. download: http://pwnable.kr/bin/codemap.exe ssh codemap@pwnable.kr -p2222 (pw:guest) 这道 ...

  6. 【pwnable.kr】 uaf

    目测是比较接近pwnable的一道题.考察了uaf(use after free的内容),我觉得说白了就是指针没有初始化的问题. ssh uaf@pwnable.kr -p2222 (pw:guest ...

  7. 【pwnable.kr】input

    这道题是一道一遍一遍满足程序需求的题. 网上其他的题解都是用了C语言或者python语言的本地调用,我想联系一下pwntools的远程调用就写了下面的脚本, 执行效果可以通过1~4的检测,到最后soc ...

  8. 【pwnable.kr】cmd2

    这道题是上一个cmd1的升级版 ssh cmd2@pwnable.kr -p2222 (pw:mommy now I get what PATH environmentis for :)) 登录之后, ...

  9. 【pwnable.kr】cmd1

    最近的pwnable都是linux操作系统层面的. ssh cmd1@pwnable.kr -p2222 (pw:guest) 首先还是下载源代码: #include <stdio.h> ...

随机推荐

  1. RHEL6配置CentOS yum源

    RHEL6配置CentOS yum源

  2. mysql5.7 忘记root密码修改方式

    参考文档: http://www.jb51.net/article/77858.htm # /etc/init.d/mysql stop --停止mysql服务 # /work/program/mys ...

  3. Steam游戏《Zengeon(神明在上)》修改器制作-[先使用CE写,之后有时间的话改用C#](2020年寒假小目标06)

    日期:2020.01.30 博客期:138 星期四 [温馨提示]: 只是想要修改器的网友,可以直接点击此链接下载: 只是想拿CT文件的网友,可以直接点击此链接下载: 没有博客园账号的网友,可以将页面下 ...

  4. LeetCode刷题--21.合并两个有序链表(简单)

    题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1 -> 2 -> 4 ,1 -> 3 -> 4 输出:1 ...

  5. 解决Python2中文ascii编码的方法

    在YiiChina签到的时候,经常会看到有人在说说里面发群主是最帅的,yii 是 PHP 最好的框架,没有之一,就想到使用一言,在每天签到的时候也发一句话 同时使用方糖将内容推送到微信,防止有什么不对 ...

  6. 吴裕雄--天生自然HADOOP学习笔记:使用yum安装更新软件

    实验目的 了解yum的原理及配置 学习软件的更新与安装 学习源代码编译安装 实验原理 1.编译安装 前面我们讲到了安装软件的方式,因为linux是开放源码的,我们可以直接获得源码,自己编译安装.例如: ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:表示一个危险的操作

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Python3中找不到xrange定义和不能用len(map())

    问题1:python3中找不到xrange的定义,vscode中提示未定义 解决:改成range,因为python3中取消了vscode 问题2:python3中map函数返回的是迭代器,因此无法用l ...

  9. SQL 笔记1,left join,group by,having

    表:XS,XK,CJ left join 表1 on 表1.字段=表2.字段 group by 分组条件 order by 排序条件 asc正序(小到大),desc倒序 having 跟条件类似whe ...

  10. Linux CentOS7 VMware 文件和目录权限chmod、更改所有者和所属组chown、umask、隐藏权限lsattr/chattr

    一.文件和目录权限chmod u User,即文件或目录的拥有者:g Group,即文件或目录的所属群组:o Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围:a All,即全部 ...