编译属性 "__attribute__" 的一些简单认识
前端时间,在打geekpwn的时候,需要做后门,一开始我做的是macos的后门,用的是 macos dylib注入(劫持?)。
这里可以提一下,我这里用的是这个项目insert_dylib,曾经看过有人用这个项目,去掉了macos上企业微信的水印,所以一直有点印象。
使用方式如下:insert @executable_path src dst
最后能类似这样的一个效果:
红色框的,是我注入的dylib 程序,那么另外一个问题来了,如何让在程序启动前或者后,执行外面的代码呢?这里就是这个文章想提的一个东西。
什么是 @executable_path ?
executable_path 是macOS的链接路径的解决方案之一,除此之外还有 @loader_path 和 @rpath,具体细节不在这里表述,感兴趣可以自己搜一下。
attribute
认识
首先,什么是 attribute ?
__attribute__
是一个编译属性,用于向编译器描述特殊的标识、错误检查或高级优化。它是GNU C特色之一,系统中有许多地方使用到。 __attribute__
可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute)等。
接着如何利用该编译属性达到我们想要的效果?
这里我们要认识两个编译属性
- attribute((constructor))
- attribute((destructor))
这两个带着 __attribute__
编译属性的标识并不相同,一个是constructor 一个是 destructor。
从字面上理解 constructor 是构造器的意思,destructor 是 a refuse-burning furnace(焚化炉的意思?),我们可以简单的理解其为c++ 函数里的构造函数和析构函数,其特点就是在于:
attribute((constructor)) 确保此函数在 在main
函数被调用之前调用,iOS中在+load
之后main
之前执行。
constructor
和destructor
会在ELF
文件中添加两个段-.ctors
和.dtors
。当动态库或程序在加载时,会检查是否存在这两个段,如果存在执行对应的代码。
attribute((destructor)),确保此函数在 在main
函数被调用之后调。
例子
我这里可以放一个,当时macos后面的一个例子:
1 |
|
我们这里可以选择Xcode 进行编译,选择编译成dylib,或者直接 gcc test.c -shared 编译也可。
最后改成相应的名字,放到被注入的程序的对应目录里即可。