【pwnable.kr】 memcpy
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是做什么的
也就是把之前从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的更多相关文章
- 【pwnable.kr】 asm
一道写shellcode的题目, #include <stdio.h> #include <string.h> #include <stdlib.h> #inclu ...
- 【pwnable.kr】 [simple login]
Download : http://pwnable.kr/bin/login Running at : nc pwnable.kr 9003 先看看ida里面的逻辑. 比较重要的信息时input变量再 ...
- 【pwnable.kr】 brainfuck
pwnable.kr第二关第一题: ========================================= Download : http://pwnable.kr/bin/bfDownl ...
- 【pwnable.kr】 unlink
pwnable.kr 第一阶段的最后一题! 这道题目就是堆溢出的经典利用题目,不过是把堆块的分配与释放操作用C++重新写了一遍,可参考<C和C++安全编码一书>//不是广告 #includ ...
- 【pwnable.kr】 codemap
pwnable新的一题. download: http://pwnable.kr/bin/codemap.exe ssh codemap@pwnable.kr -p2222 (pw:guest) 这道 ...
- 【pwnable.kr】 uaf
目测是比较接近pwnable的一道题.考察了uaf(use after free的内容),我觉得说白了就是指针没有初始化的问题. ssh uaf@pwnable.kr -p2222 (pw:guest ...
- 【pwnable.kr】input
这道题是一道一遍一遍满足程序需求的题. 网上其他的题解都是用了C语言或者python语言的本地调用,我想联系一下pwntools的远程调用就写了下面的脚本, 执行效果可以通过1~4的检测,到最后soc ...
- 【pwnable.kr】cmd2
这道题是上一个cmd1的升级版 ssh cmd2@pwnable.kr -p2222 (pw:mommy now I get what PATH environmentis for :)) 登录之后, ...
- 【pwnable.kr】cmd1
最近的pwnable都是linux操作系统层面的. ssh cmd1@pwnable.kr -p2222 (pw:guest) 首先还是下载源代码: #include <stdio.h> ...
随机推荐
- QCMS代码审计:XSS+SQL+后台getshell
qcms是一款比较小众的cms,最近更新应该是17年,代码框架都比较简单,但问题不少倒是... 网站介绍 QCMS是一款小型的网站管理系统.拥有多种结构类型,包括:ASP+ACCESS.ASP+SQL ...
- jdbc学习over
这次的代码和之前学习到一般的代码主要就是将一些很常见的操作(建立连接.清除连接)不管做什么操作都需要用到它们,所以将它们单独放到另一个工具类里面去. 用到的术语: 1.事务:https://www.c ...
- 《java核心技术:卷1》PDF版 和 Word版下载
链接:https://pan.baidu.com/s/1OcpdZ4wfeo55xeJQQBHXRg 提取码:hds0
- 2017 青岛现场赛 Suffix
Consider n given non-empty strings denoted by s1 , s2 , · · · , sn . Now for each of them, you need ...
- 数据库事务ACID特效
一.数据库事务正确执行的4个基础要素: 1.原子性 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状 ...
- 一、java基础-数据类型_数据类型转化_字符编码_转义字符
1.Java 支持的8种基本数据类型: java的四种整数数据类型:byte 1 short 2 int4 long8 byte 8位带符号整数 -128到127之 ...
- 关于dotnet跨平台 微信公众号
dotNET跨平台 <dotNET跨平台>是国内首个以.NET程序员.技术文化.新闻为主题的公众号,拥有超过6万读者.在这里你可以谈微软.NET,Mono的跨平台开发技术,也可以谈谈其他的 ...
- texlive 安装
texlive 可以从下面两个网址下载 https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/ https://mirror ...
- 16 SQL Mode
1.SQL Mode解决的问题: a.通过设置SQL Mode , 可以完成不同严格程度的数据校验,有效地保障数据准确性. b.通过设置SQL Mode 为ANSI模式,来保证大多数S ...
- C#遍历DataSet
] foreach (DataRow dr in dt.Rows) ///遍历所有的行 foreach (DataColumn dc in dt.Columns) //遍历所有的列 Console.W ...