文件结构
编译so
g++ -fPIC -shared -o liba/a.so liba/a.c
#include<stdio.h>
int a()
{
printf("aaaaaaaaaaaaaaaa\n");
return 0;
}
编译可执行程序
g++ src/test.cpp -o src/a.out -ldl
int main()
{
int (*test)();
void *handle=dlopen("../liba/a.so",RTLD_LAZY);
if (!handle)
{
printf("gg");
exit(1);
}
test = (int(*)())dlsym(handle,"a");
test();
dlclose(handle);
return 0;
}
查看反编译so
a
的方法名被编译器改变。
修改代码后编译
g++ src/test.cpp -o src/a.out -ldl
int main()
{
int (*test)();
void *handle=dlopen("../liba/a.so",RTLD_LAZY);
if (!handle)
{
printf("gg");
exit(1);
}
test = (int(*)())dlsym(handle,"_Z1av");
test();
dlclose(handle);
return 0;
}
readelf
原因
因为gcc
和g++
对编译后的符号处理不一样,因为g++
允许重载,往往会修改编译后的函数名。
可以通过extern "c"
避免g++
编译器修改。