随想录(systemtap中的基本原理)


【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱: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数据段的属性了。就是这么简单。



你可能感兴趣的:(随想录(systemtap中的基本原理))