binary hacks 记录

6、 静态库和共享库
静态库的编写通常如下:
cc -c -o foo.o goo.c
cc -c -o bar.o bar.c
ar ruv libfoo.a foo.o bar.o
查看库的内容:
ar tv libfoo.a
连接使用:cc -o baz baz.o -lfoo

而共享库的制作:
cc -fPIC -c -o foo.o foo.c
cc -fPIC -c -o bar.o bar.c
cc -shared -Wl,-soname, libfoo.so.0 -o libfoo.so foo.o bar.o

8、readelf 表示 ELF 文件信息
9、objdump 工具
11、用 objcopy 潜入可执行文件的数据

可以使用如下方式将 foo.jpg 转换为 x86 用的 ELF32 形式的目标文件 foo.o:
objcopy -I binary -O elf32-i386 -B i386 foo.jpg foo.o
然后
extern char _binary_foo_jpg_start[];
extern char _binary_foo_jpg_end[];
extern char _binary_foo_jpg_size[];

const char *start = _binary_foo_jpg_start;
const char *end = _binary_foo_jpg_end;
int size = (int)_binary_foo_jpg_size;

12 和 14、nm 命令的使用
-r 倒序输出
--size-sort 按符号所表示的对象大小从小到大排序
-S 输出对象大小
-f 指定格式:bsd,sysv,posix
-A 输出该符号被包含在哪个目标文件中:nm -A libc.a;nm -A *.o
strip 之后 nm 显示没有符号,用 -D 查动态库
nm foo.o | c++filt 或者 nm --demangle foo.o 转换 c++ 符号
15、add2line 从地址中获取文件名和行号
addr2line -f -e ADDR。

18、C 和 C++ 的互相调用
编译时带上 -dexceptions 选项
19、链接时的标识符冲突

20、PIC 编译
用 -fPIC 来编译共享库

21、statifier
将一个程序和对应所需的共享库制作成一个可执行文件,这样可以直接拿到别的机器上使用。

22、GNU 扩展入门
一些内置的函数 __built_in;
对函数声明时加上 attribute,对函数进行特殊优化。
int foo(int) __attribute__((attribute));
对于函数,attribute 可以包含如下内容:
constructor:调用 main 之前和加载共享目标时必须运行的函数。
23、gcc 中使用内联汇编
24、在 gcc built in 函数上的最优化
尽量使用 const 来修饰。
29、控制对外公开库的符号

31、在 main 前面调用函数
35、建成 PIE
42、GCC 安全编写入门

GCC 警告选项和 __attribute__ 的使用,环境变量 MALLOC_CHECK_ 在为 1 时继续运行,为 2 时立即终止。
43、用 ftrapv 检测整数溢出
有些情况无法检测

44, 45、用 Mudflap 和 -D_FORTIFY_SOURCE 检测缓冲区溢出
-g -fmudflap -lmudflap
还有个环境变量 MUDFLAP_OPTIONS 控制行为

47,48、位运算的问题
49、64 位下 0 和 NULL 的不同之处

NULL 并不是 0 这个 int 的值,带有 0 这个值的指针为 NULL。编译器必须要明白是用指针类型来解释的。

struct s *foo(const char *name, ...)
{
    va_list va;
    struct s *sp;
    char *p;
    va_start(va, fmt);
    sp = (struct s*)malloc(sizeof(struct s));
    if (!sp) return 0;
    memset(sp, '\0', sizeof(struct s));
    set_name(sp, name);
    while((p=va_arg(va, char *))) {
        set_item(sp, p);
    }
    return sp;
}
 
... sp = foo("foo", "bar", 0);

此程序据说在 64 位机器上无法正常运行。
只能如下使用 foo("foo", "bar", NULL);

51、注意信号处理函数中的非 volatile 和非 sig_atomic_t 型全局变量
不是所有函数都能被用在信号处理函数中,能从信号处理器安全的读出的函数称为“异步信号安全函数”。
52、用 sigwait 将异步信号进行同步处理
53、用 sigsafe 将信号处理安全化
60、LD_PRELOAD 更换共享库

63、C 的回溯(back trace)
backtrace() 和 backtrace_symbols_fd() 函数
64、检测运行中进程的路径名
readlink,getexecname,proc 文件系统
65、检测正在加载的共享库
dl_iterate_phdr 和 dlinfo
66、pmap 和进程的虚拟内存空间
67、用 libbfd 取得符号的一览表
68、运行 C++ 语言时进行 demangle

在运行时进行 demangle,一种是使用 binutils 的 libiberty 所包含的 cplus_demangle,另一种是使用包含在 libstdc++ 中的 abi::__cxa_demangle()。
70、用 libdwarf 取得调试信息
71、通过 dumper 简化 dump 出结构体的数据

利用 dumper 方便打印结构体的内容
76、用 sigaltstack 处理 stack overflow
77、面向函数的进入和退出的 hook

使用 GCC -finstrument-functions 选项,能调用面向函数的 enter 和 exit 时自生成的函数
78、从信号处理器中改写上下文
81、使用 SIGSEGV 来确认地址的有效性

#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
 
static struct sigaction orig_act;
static sigjmp_buf env;
 
static void sigsegv_handler(int sig)
{
    siglongjmp(env, 1);
}
 
int validate(void *addr)
{
    int is_valid = FALSE;
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = sigsegv_handler;
    sigaction(SIGSEGV, &act, &orig_act);
    if (sigsetjmp(env, TRUE) == 0)
    {
        volatile char c;
        c = *((char*)addr);
        *((char*)addr) = c;
        is_valid = TRUE;
    }
    else is_valid = FALSE;
    sigaction(SIGSEGV, &orig_act, NULL);
    return is_valid;
} 
 
int main(int argc, char **argv)
{
    int a;
    printf("variable a: %s\n", (validate(&a)?"valid":"invalid"));
    printf("100: %s\n", (validate((void *)100)?"valid":"invalid"));        
}

82,83:ltrace 和 strace
strace 用来 trace 系统调用
ltrace 用来跟踪系统调用共享库的函数
86、livepatch 在运行中的进程上发布补丁

87, 88,89:gprof,sysprof,oprofile 获取系统 profile。
获得系统整体 profile 的软件 —— sysprof,使用简单,功能有限。
oprofile 较复杂。



Related posts(相关文章):
This entry was posted in 系统编程. Bookmark the permalink.

3 Responses to binary hacks 记录

  1. seonaut says:

    好文章,强烈支持!
    欢迎交换友情链接www.seonaut.org

  2. qishengjun says:

    您好,想和您做一些技术上的交流,望能加我,谢谢!qq :85937023

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">