花了2天的時間安裝dyninst,之前安裝9.3.2一直出問題,無奈只能選擇安裝dyninst9.3.1,竟然沒出問題。
在網上找的教程不但少,而且有各種問題,好不容易安裝成功了,記錄一下過程:
參考網址:http://blog.csdn.net/lfdanding/article/details/50276129,http://blog.csdn.net/ldzm_edu/article/details/64919493,http://blog.csdn.net/adrian169/article/details/8893443,https://www.douban.com/note/350093839/,
1.安裝dyninst需要的其他軟件:boost、libelf、libdwarf、g++等,先用下面的命令,若缺少或報錯則自己再源碼安裝
sudo apt-get install cmake libblkid-dev e2fslibs-dev libboost-all-dev libaudit-dev texlive-latex-base libelf-dev libdwarf-dev libiberty-dev
我是自己源碼安裝的boost和libdwarf,下面只介紹如何源碼安裝libdwarf
源碼安裝libdwarf過程:下載libdwarf,參考鏈接http://askubuntu.com/questions/502749/install-libdwarf-so-on-ubuntu
dwarf-20180129下載地址:https://www.prevanders.net/dwarf.html#releases
1、Download dwarf-20180129.tar.gz
Extract the archive and in terminal type:
2、cd dwarf-20180129/libdwarf
./configure --enable-shared
make
3、At the end, just copy the libdawrf.so into /usr/lib (linux自帶cp命令sudo cp libdwarf.so /usr/lib/)
2.下載dyninst9.3.1,官網地址:http://www.dyninst.org/downloads/dyninst-9.x1)解壓進入dyninst9.3.1目錄中:
1.cmake /home/lu/new10g/sda3/dyninst-9.3.1 -Dfoo=bar -DBoost_INCLUDE_DIR=/home/lu/software/boost_1_59_0/ -DLIBDWARF_INCLUDE_DIR=/home/lu/new10g/sda3/dwarf-20180129/libdwarf -DLIBDWARF_LIBRARIES=/home/lu/new10g/sda3/dwarf-20180129/libdwarf/libdwarf.so
2.make
3.sudo make install
注意:cmake時boost和libdwarf路徑一定要配置好,要不然make就會報錯.
3.運行dyninst例子:
1)test_dynamic.c:
#include<stdio.h>
#include<unistd.h>
void old(){
printf("old old old pid is %d\n",getpid()) ;
}
void new(){
printf("new new new pid is %d\n",getpid()) ;
}
int main(){
while(1){
old() ;
sleep(5) ;
}
}
這個程序裏面包含2個函數,各自輸出不同的打印信息。從程序裏面我們可以看到,這個程序在運行時候,調用old函數,也就是說該程序的輸出就是old old……..,這樣的信息,那麼好,我們編寫修改程序,動態改變該程序,讓該程序輸出new函數的打印信息。
2)modify.cpp:
#include<iostream>
#include<sys/fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include"BPatch.h"
#include"BPatch_Vector.h"
#include"BPatch_thread.h"
#include"BPatch_snippet.h"
int main(int argc,char** argv){
BPatch* bpatch = new BPatch ;
BPatch_Vector<BPatch_function*> old_func ;
BPatch_Vector<BPatch_function*> new_func ;
BPatch_process* app = bpatch->processAttach("test_dynamic",atoi(argv[1])) ;
BPatch_image* appImage = app->getImage() ;
BPatch_Vector<BPatch_function*> *tmp = appImage->findFunction("old",old_func) ;
tmp = appImage->findFunction("new",new_func) ;
app->replaceFunction(*old_func[0],*new_func[0]) ;
app->detach(1) ;
return 0 ;
}
3)設置運行環境,執行例子
在.bashrc最後面添加
vim ~/.bashrc
DYNINST_INCLUDE=/usr/local/include
DYNINST_LIB=/usr/local/lib
export DYNINSTAPI_RT_LIB=$DYNINST_LIB/libdyninstAPI_RT.so
編輯/etc/sysctl.d/10-ptrace.conf參考連接http://www.2cto.com/os/201303/197816.html
sudo vim /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0
將dyninst共享庫加入標準路徑中:
先找到共享庫文件的位置,然後修改管理共享庫的文件:
cd /etc
sudo gedit ld.so.conf
通常ld.so.conf文件中有這麼一句話,“include /etc/ld.so.conf.d/*.conf”,需要做的就是把共享庫文件的位置/usr/local/lib添加到這句話下面,保存之後關掉。然後在終端中輸入下面這句話更新一下共享庫:
sudo ldconfig
4)重啓電腦
5)編譯test_dynamic.c
gcc -o test_dynamic test_dynamic.c
6)編譯modify.cpp :先編寫Makefile文件
DYNINST_INCLUDE=/usr/local/include
DYNINST_LIB=/usr/local/lib
modify: modify.o
$(CC) modify.o -L$(DYNINST_LIB) -ldyninstAPI -o modify -lstdc++
modify.o: modify.cpp
$(CC) -c $(CFLAGS) -I$(DYNINST_INCLUDE) modify.cpp -std=c++0x
最後
make
7)運行例子
先運行 ./test_dynamic 再運行 ./modify [pid] (注意:該pid爲./test_dynamic中輸出的pid)
方法二:不用Makefile編譯
modify.cpp爲:
#include<iostream>
#include<sys/fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include"BPatch.h"
#include"BPatch_Vector.h"
#include"BPatch_thread.h"
#include"BPatch_snippet.h"
int main(int argc, char **argv)
{
BPatch* bpatch = new BPatch ;
BPatch_Vector<BPatch_function*> func_new ;
BPatch_Vector<BPatch_function*> func_old ;
// Specify the executable file name and process id of the application as arguments
BPatch_process *appProc = bpatch->processAttach(argv[1], atoi(argv[2]));
// BPatch_process inherit from BPatch_addressSpace
BPatch_addressSpace *app = appProc;
BPatch_image *appImage = app->getImage();
// Find function:old()
BPatch_Vector<BPatch_function*> *tmp = appImage->findFunction("old", func_old);
// find function: new()
tmp = appImage->findFunction("new", func_new);
// Exchange function "old()" to "new()"
appProc->replaceFunction(*func_old[0], *func_new[0]);
// Detach from the mutatee process, optionally leaving it running
appProc->detach(1);
return 0;
}
編譯方法爲:
g++ -std=c++11 modify.cpp /home/lu/new10g/sda3/dyninst-9.3.1/dyninstAPI/libdyninstAPI.so
運行例子:
先運行 ./test_dynamic
再運行 ./a.out test_dynamic [pid] (注意:該pid爲./test_dynamic中輸出的pid)