浅述extern C的用法 和 无导入表PE的实现

一:extern C的用法

#ifdef __cplusplus  //如果下面的myFunc函数的实现是在c文件中,则当需要和cpp混编时这些代码是必不可少的
extern "C"
{
#endif
void	myFunc();
#ifdef __cplusplus 
}
#endif</span>

extern "C"包含双重含义,从字面上可以知道,首先,被它修饰的目标是"extern"的;其次,被它修饰的目标代码是"C"的。

extern是C/C++语言中表明函数和全局变量的作用范围的关键字,该关键字告诉编译器,其申明的函数和变量可以在本模块或其他模块中使用。


同时注意下面的语句:

extern int a; 仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出错。


二:无导入表PE的实现

步骤:

1、自定义入口点,代码如下:

#pragma comment(linker, "/subsystem:\"windows\"")
#pragma comment(linker, "/entry:\"mySun\"")

2、实现入口点函数,例如:

int mySun()
{
	//add your code here
	return 0;
}


3、用Release模式编译程序

4、这样就得到了一个没有导入表的程序,但是这个程序什么也做不了,而且可能还无法退出, 但这确实是合法的pe程序

如果你想实现一点功能,例如弹出一个窗口的函数MessageBox或者是让exe程序能够退出的函数ExitProcess(0),这样的话功能虽然有了,但是也带来了导入表。

5、去掉导入表

5.1、找到kernel32.dll在内存中的位置,下面的代码可以实现(不仅限于该代码):

__declspec(naked) DWORD get_k32()
{
	__asm
	{
		mov   eax, fs:[030h]	;	
		test  eax,eax		;  
		js    finished		;	
		mov   eax, [eax + 0ch]	;	
		mov   eax, [eax + 14h]	;	
		mov   eax, [eax]	;	
		mov   eax, [eax]        ;
		mov   eax, [eax + 10h]  ;
finished:
		ret
	}
}
再之后如下调用即可获得kernel32.dll的内存地址:

HMODULE hModuleBase = (HMODULE)get_k32(); 

 

5.2、实现一个自己的GetProcAddress函数,这里使用的是利用HASH的方法获取相应的API地址,大致思路如下:

      将想要获取的某个DLL中的导出函数名用某种算法获取其对应的HASH值,接着在相应的DLL中遍历每个到处函数,对其函数名用同样的算法获取HASH后进行比对,相同则获取其地址,具体方法请网上搜寻


5.3、用自己的GetProcAddress和已知的kernel32.dll的地址加载出一些关键函数如LoadLibraryA、ExitProcess。

5.4、用LoadLibraryA加载user32.dll,然后用GetProcAddress加载MessageBoxA

5.5、至此,所需要的函数都有了,可以实现了,更丰富的功能也都可以实现,无非是动态加载api函数罢了。


原则:所有需要用到的api函数都用LoadLibraryA和GetProcAddress来动态加载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值