Android上实现可执行的SO文件

Linux下的so文件通常是作为动态链接库使用的,但其实so文件跟可执行程序一样都是ELF格式,所以应该都是可以直接执行的。

Linux下编译可以执行的so文件如下:

#include <stdio.h>
#include <stdlib.h>

void lib_entry()
{
    printf("Entry point of the service library\n");
    exit(0);
}

注意,lib_entry()必须以exit(0)结束,否则会导致进程退出失败。

使用如下命令编译源代码:

$ gcc -shared service.c -o libservice.so -Wl,-e,lib_entry -fPIC

-Wl表示传递给链接器ld的参数,分隔的逗号会被替换成空格。-e,lib_entry就指明了入口函数。

而对于Android来说,只需要在Android.mk文件中增加LOCAL_LDLIBS += -Wl,-e,lib_entry就可以达到相同的目的了。

需要注意的问题


1.这个入口函数是否可以传递类型int main(int argc,char* argv[])这样的参数进去?

答案是不能,那么启动参数从哪里读取呢? 答案就是从/proc/$pid/cmdline中手工解析获取。

2.入口函数并没有初始化C库的代码,在调用代码时候为什么没有崩溃?

正常情况下,可执行程序的入口函数实际上是C库的的入口函数,然后C库自身初始化完成,解析参数后调用我们自己实现的入口函数。按照常规逻辑,如果没有初始化C库,那么调用C库函数的时候,几乎肯定是会崩溃的。

反编译正常的可执行程序,应该都能看到C库的初始化函数,而指定了入口的,基本上都没有这个函数的调用。

但是在Linux下面ld.so会帮我们初始化一次C库,而我们又是被ld.so加载起来的,因此理论上,我们不需要再次初始化C库了。

参考链接


发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注