在Visual Studio中快速展开复合宏的方式

对例如dlmalloc之类的函数代码宏套着宏的代码复杂,但是工程简单(只有少量文件)的项目来说,展开宏会让静态阅读看起来更爽(其实是老方法,但是最近发现不少不用Windows开发的朋友完全不知道..)。要展开也非常简单,三步:

1、 将工程导入Visual Studio
2、 查看工程属性,打开预编译到文件选项。
precompile.jpg
正如它提示的那样,预编译到文件意味着不会生成obj文件,也就是说,工程现在开始不能编译成目标文件。
3、 编译工程,去工程目录下寻找.i文件吧。

.i文件前面会包含一大堆乱七八糟的数据,那些是系统库的一些头文件,定位到你的代码前,把系统库的代码全部删掉,最后整理一下多行回车、在VS里面格式化一下代码,大功告成。

dlmalloc模式的内存layout

主要自己最近在调试这个,相比Windows的来说,Linux程序选择alloc的方式真是千奇百怪,alloc也是有一大堆,先看一个dlmalloc的实现。

A 简介

dlmalloc是目前一个十分流行的内存分配器,其由Doug
Lea1从1987年开始编写,到目前为止,最新版本为2.8.32,由于其高效率等特点被广泛的使用和研究(很多linux系统等用的就是dlmalloc或其变形,比如ptmalloc)。

B 内存布局

pdlmalloc.png
来源@https://cw.fel.cvut.cz/old/_media/courses/a4m33pal/04_dynamic_memory_v6.pdf

实际上的内存类似于:
dmp.png

P位的作用是:1 代表前一个thunk在使用,0 代表被释放。
参考@https://medium.com/@ktecv2000/heap-exploit-%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-d724d0afa59b

C 有点太快了
源代码可以从ftp://gee.cs.oswego.edu/pub/misc/malloc.c获取到。
看一下malloc.h中的作者简介吧。写的比百度百科的词条要好很多。(机器翻译,我用上瘾了)

重要情报: 支持的指针/size_t表示:4或8个字节。size_t必须是与指针宽度相同的无符号类型。 (如果您使用的是一个将size_t 声明为有符号类型的古老系统,或者需要它与指针的宽度不同,则可以使用此malloc的以前版本(例如2.7.2)来支持)
对齐:8个字节(最少)。这对几乎所有当前机器和C编译器来说都足够了。但是,如果需要的话,您可以将MALLOC_ALIGNMENT定义为更宽的范围(最多128字节),代价是使用更多的空间。
每个分配块的最小开销:4或8个字节(如果是4字节大小,原文如此,指32bit)、8或16个字节(如果是8字节大小,指64bit),每个malloc的块都有一个隐藏字,其中包含大小和状态信息,如果定义了FOOTER,则还有其他交叉检查字。
最小分配大小:4字节指针:16字节(包括开销),8字节指针:32字节(包括开销),即使是对零字节(即malloc(0))的请求也会返回一个指向最小可分配大小的指针。
最大开销浪费(即分配的额外字节数比malloc中请求的字节数)小于或等于最小大小,但通过mmap()服务的请求>=mmap_阈值除外,其中最坏的浪费大约是32个字节加上系统页面(最小mmap单元)的剩余部分;通常是4096或8192字节。

安全性:静态安全;可选地,malloc的“安全性”或多或少是指恶意代码在调用malloc的代码中强调错误影响的能力(例如,释放当前未被恶意占用的空间或覆盖过块的末端)。此malloc保证即使存在使用错误,也不会修改堆以下的任何内存位置(即静态变量)。例程还检测到大多数不适当的free和realloc。只要malloc本身的静态记录不被其他方法破坏,所有这些保护都是有效的。

这只是安全性的一个方面--这些检查也不能检测到所有可能的编程错误。如果FOOTER被定义为非零,则每个分配的块都带有一个额外的检查字,以验证它是从其空间中malloc的。
这些检查字在使用malloc的程序的每次执行中是相同的,但如果再次执行则不同,因此无法free由恶意代码构造的假内存块。
这可以通过拒绝可能损坏堆内存的free/realloc程序来提高安全性,此外还可以防止对始终处于打开状态的static写入进行检查。
这可能会以牺牲时间和空间开销为代价进一步提高安全性。(请注意,FOOTER可能也值得与MSPACES一起使用)。
默认情况下,检测到的错误会导致程序中止(调用“abort()”)。您可以重写它,通过定义PROCEED_ON_ERROR来处理错误。

在这种情况下,恶意的free不会有任何影响,遇到用户覆盖造成的坏地址的malloc将通过将指针和索引删除所有已知内存而忽略恶意地址。
这可能适用于在遇到编程错误时应尽可能继续运行的程序,尽管它们可能会耗尽内存,因为这样的话,程序将永远不会回收掉那些恶意内存。
如果您不喜欢这两种选项中的任何一种,则可以定义CORRUPTION_ERROR_ACTION 和 USAGE_ERROR_ACTION
来执行其他任何操作。

如果您确信您使用malloc的程序没有错误或漏洞,您可以将不安全定义为1,这可能(也可能不会)提供一个小的性能改进。还可以使用malloc_set_footprint_limit来限制最大总可分配空间。这本身并不是一个安全特性(对设置限制的调用没有屏蔽或特权),但是作为安全实现的一个方面可能很有用。

关于文章更新……

最近一直忙于一个项目,本来预计的是说一个月一篇的,不过现在看来时间不是很多啊...

不过相比于麻烦的原创文章,我也在更新一个翻译(大部分是机器翻译+人工润色)的博客:http://tem.pw

虽然说是机器翻译,不过现在机器翻译质量明显上升了,我只需要手动修改一点点就变得很通顺了,于是采用了这么个快捷简单的方式来更新文章……

也许得到下次搞出大新闻的时候nul.pw这边才有空更新吧 [/捂脸]

HTTPS访问异常的问题

站点因为历史原因,一直托管在一个虚拟主机上,HTTPS访问配置异常,请暂时使用HTTP来访问本站。

近期将会迁移到我自己的主机上,之后我会给本站开启正确的HTTPS的证书。


服务器抽风,HTTP也异常了,好在点了一下就好了,之前404的页面现在又可以访问了。

Google Chrome对本地文件进行MIME Sniffing的问题

偶然发现,不是多严重,本地文件没有MIME,Google Chrome应该只对kSecondaryMappings中的内容进行处理,而其他未知的理应作为plain text处理,但是Chrome却对文件内容进行了嗅探,这导致任何文本文件的内容都可能会被当作脚本执行。63以后版本的Chrome已经修复了此问题。
https://bugs.chromium.org/p/chromium/issues/detail?id=777737