文件結構
編譯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++
編譯器修改。