首页
社区
课程
招聘
[原创] memcpy pwnable.kr writeup
发表于: 2019-8-5 23:04 9851

[原创] memcpy pwnable.kr writeup

2019-8-5 23:04
9851

地址: http://pwnable.kr/play.php

只要程序能够顺利执行完,flag就会被打印。
题目问题主要出在 fast_memcpy()函数上。
里面的movntps指令的目的地址必须16byte对齐。
而malloc函数返回的地址有可能不满足条件,这样的话就会segfault。
那怎么让malloc分配的内存地址是16byte对齐呢?

代码:

利用gdb加载程序, 在 main 函数中调用 malloc函数指令位置处下断点。
观察每次分配内存的地址。
内存size = 8:0x08f41010
size = 16:0x08f41020
size = 32: 0x08f41038
size = 64: 0x08f41060
size = 128: 0x08f410a8

可以观察到一个规律,那就是每次分配的内存地址减去上次分配的内存地址 都比上次请求的内存空间大小 多8个字节。
这8个字节应该就是堆块管理结构内容。

<u>所以:想要程序每次分配的内存地址都是16byte对齐。则每次分配的空间大小都应该是 size % 16 = 8</u>

普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。mmap并不分配空间, 只是将文件映射到调用进程的地址空间里(但是会占掉你的 virutal memory), 然后你就可以用memcpy等操作写文件, 而不用write()了.写完后,内存中的内容并不会立即更新到文件中,而是有一段时间的延迟,你可以调用msync()来显式同步一下, 这样你所写的内容就能立即保存到文件里了.这点应该和驱动相关。 不过通过mmap来写文件这种方式没办法增加文件的长度, 因为要映射的长度在调用mmap()的时候就决定了.如果想取消内存映射,可以调用munmap()来取消内存映射

start: 指向映射的内存起始地址;NULL表示系统自动选择地址
length: 内存大小。
prot: 映射内存的保护方式

flags: 内存区域的各种特性。调用时必须指定 MAP_SHARED / MAP_PRIVATE 之一。

fd: 要映射到内存中的文件描述符。 fd为-1表示匿名内存映射。

返回值: 映射成功返回内存起始地址。

从XMM寄存器复制4个单精度浮点数至128位内存单元
reference
The source operand is an XMM register, YMM register or ZMM register, which is assumed to contain packed single-precision, floating-pointing. The destination operand is a 128-bit, 256-bit or 512-bit memory location. The memory operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary otherwise a general-protection exception (#GP) will be generated.
对应源操作数为XMM,则目的内存为128比特内存位置。内存必须16字节对齐,否则会生成一个 general-protection 异常。

移动对齐的双四字 128bit

reference
SSE指令集提供了xmm寄存器,xmm一组8个128位的寄存器,分别名为xmm0-xmm7
对应指令
movaps 把4个对准的单精度值传送到xmm寄存器或者内存
movups 把4个不对准的单精度值传送到xmm寄存器或者内存
movss 把1个单精度值传送到内存或者寄存器的低位双字
movlps 把2个单精度值传送到内存或者寄存器的低四字
movhps 把2个单精度值传送到内存或者寄存器的高四字
movlhps 把2个单精度值从低四字传送到高四字
movhlps 把2个单精度值从高四字传送到低四字

movapd 把2个对准的双精度值传送到xmm寄存器或者内存
movupd 把2个不对准的双精度值传送到xmm寄存器或者内存
movdqa 把2个对准的四字节整数传送到xmm寄存器或者内存
movdqu 把2个不对准的四字节整数传送到xmm寄存器或者内存
movsd 把1个双精度值传送到内存或者寄存器的低四字
movhpd 把1个双精度值传送到内存或者寄存器的高四字
movlpd 把1个双精度值传送到内存或者寄存器的低四字

程序尝试去读或者写一个非法内存地址

A segfault occurs when a reference to a variable falls outside the segment where that variable resides, or when a write is attempted to a location that is in a read-only segment.

代码参考

context.terminal = ['terminator','-x','sh','-c']
第一个参数 terminator 为本地可用的terminal。

context.log_level = 'DEBUG'
这样可以输入对程序的输入和程序的输出信息

 
 
 
 
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 3
支持
分享
最新回复 (2)
雪    币: 785
活跃值: (33)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
看了一下pwnable的writeup,题目不错
2019-8-17 23:19
1
雪    币: 649
活跃值: (73)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
gdxzll 看了一下pwnable的writeup,题目不错
适合从入门到放弃哈哈哈
2019-8-19 19:10
0
游客
登录 | 注册 方可回帖
返回
//