隨想錄(systemtap中的基本原理)
來源:程序員人生 發布時間:2014-10-06 08:00:01 閱讀次數:2349次
【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing @163.com】
systemtap中的probe功能非常令人著迷。這種類似hook的方法對于我們調試性能和分析問題非常有用,更重要的是它還不需要重新編譯,僅僅依靠幾個腳本就可以完成你想要的功能,這不得不說是非常神奇。
后來,我自己想了一下,這個功能應該不是很復雜。關鍵就是要做好probe函數的保護和恢復工作就可以了。想到這,我就在vc 6.0上仿真實現了這么一段代碼來說明問題。注意,如果在vs2010上運行,恢復地址那一行代碼修改為*(&data +3)=test即可。
#include <stdio.h>
#include <windows.h>
#define LEN 8
unsigned char save[LEN];
void test();
void stub();
// replace function
void stub()
{
unsigned int data;
unsigned char* p;
unsigned int index;
p = test;
// above is data, ebp and return address
// restore return address
*(&data + 2) = test;
// restore data
for(index = 0; index < LEN; index ++) {
p[index] = save[index];
}
printf("stub ");
}
//original function
void test()
{
printf(" china");
}
// content add is as follows
// __asm {
// lea eax, stub
// call eax
// }
void set_stub(unsigned char* p, unsigned int data)
{
*(unsigned short*)p = 0x058d;
*(unsigned int*)(p+2) = data;
*(unsigned short*)(p+6) = 0xd0ff;
}
int main()
{
unsigned char* p = (unsigned char*) test;
DWORD old;
DWORD tmp;
unsigned index;
// modify attribute of code segment
if(!VirtualProtect(p, LEN, 0x40, &old)){
exit(1);
}
for(index = 0; index < LEN; index ++){
save[index] = p[index];
}
// modify address
set_stub(p, stub);
// run test function
test();
// restore attribute of code segment
if(!VirtualProtect(p, LEN, old, &tmp)){
exit(1);
}
return 1;
}
這段代碼的內容不復雜,關鍵就是說強迫運行test函數之前一定要運行一下stub函數。首先,我們需要將test函數開始的代碼設置成可讀可寫的屬性;其次就是保存這一段原始代碼內容,因為之后還是需要恢復的;接著利用set_stub函數將test一開始的代碼設置成一段跳轉內容,這樣可以直接到stub執行;后面stub執行的時候,恢復ret地址和test開始處的data,這樣在stub返回的時候可以繼續到test函數執行;當然最后所有工作都完成的時候就可以恢復test數據段的屬性了。就是這么簡單。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈