c语言逆向学习笔记 day 1

本文详细介绍了C语言中__declspec(naked)修饰符的应用,包括裸函数的基本概念、不同应用场景下的框架示例,并通过具体实例展示了如何使用裸函数实现特定功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c语言 __declspec(naked)裸函数

1、什么是裸函数

就是编译器不会为这个函数生成代码,想用汇编怎么写就怎么写,如果什么都不写,一定会报错,因为没有生成ret

2、裸函数框架

一、裸函数模板

int _declspec(nacked) Function(int x,int y,int z)
{
    _asm
    {
        ret
    }
}

二、无参数无返回值框架

void __declspec(naked) Function()  					
{					
	__asm				
	{				
		push ebp			
		mov ebp,esp			
		sub esp,0x40			
		push ebx			
		push esi			
		push edi			
		lea edi,dword ptr ds:[ebp-0x40]			
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
					
		pop edi			
		pop esi			
		pop ebx			
		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}

三、有参数有返回值的函数框架

int __declspec(naked) Function(int x,int y)  					
{					
	__asm				
	{				
		push ebp			
		mov ebp,esp			
		sub esp,0x40			
		push ebx			
		push esi			
		push edi			
		lea edi,dword ptr ds:[ebp-0x40]			
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
					
		mov eax,dword ptr ds:[ebp+8]			
		add eax,dword ptr ds:[ebp+0xC]			
					
		pop edi			
		pop esi			
		pop ebx			
		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}

四、带局部变量的函数框架

int __declspec(naked) Function(int x,int y)  					
{					
	__asm				
	{				
		push ebp			
		mov ebp,esp			
		sub esp,0x40			
		push ebx			
		push esi			
		push edi			
		lea edi,dword ptr ds:[ebp-0x40]			
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
		mov dword ptr ds:[ebp-4],2			
		mov dword ptr ds:[ebp-8],3			
					
		mov eax,dword ptr ds:[ebp+8]			
		add eax,dword ptr ds:[ebp+0xC]			
					
		pop edi			
		pop esi			
		pop ebx			
		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}					

五、裸函数实例

用__declspec(naked)裸函数实现下面的功能

int plus(int x,int y,int z)			
{			
	int a = 2;		
	int b = 3;		
	int c = 4;		
	return x+y+z+a+b+c;		
}	

裸函数实现(这里我用的是visual studio2017版生成的)

#include "stdio.h"

int __declspec(naked) plus(int x, int y ,int z) {
	//int a = 1;
	//int b = 2;
	//int c = 3;
	//return a + b + c + x + y + z;
	__asm
	{
		//保留调用前堆栈栈底
		push        ebp 
		//提升堆栈 					
		mov         ebp,esp  					
		sub         esp,0E4h  
		//保护现场					
		push        ebx  					
		push        esi  					
		push        edi
		//往缓冲区填充数据  					
		lea         edi,[ebp-0E4h]  					
		mov         ecx,39h  					
		mov         eax,0CCCCCCCCh  					
		rep stos    dword ptr es:[edi]
		//函数实现功能  										
		mov         dword ptr [a],1  					
		mov         dword ptr [b],2  					
		mov         dword ptr [c],3  					
		mov         eax,dword ptr [a]  					
		add         eax,dword ptr [b]  					
		add         eax,dword ptr [c]  					
		add         eax,dword ptr [x]  					
		add         eax,dword ptr [y]  					
		add         eax,dword ptr [z]
		//恢复现场  					
		pop         edi  					
		pop         esi  					
		pop         ebx  					
		add         esp,0E4h  									
		mov         esp,ebp  					
		pop         ebp  					
		ret  
	}
}

int main(int argc, char* argu[]) {
	int x;
	x = plus(4, 5, 6);
	printf("%d", x);
}

常见的几种调用约定

调用约定参数压栈顺序平衡堆栈
__cdecl从右至左入栈调用者清理栈
__stdcall从右至左入栈自身清理堆栈
__fastcallECX/EDX传送前两个,剩下:从右至左入栈自身清理堆栈

1、int __cdecl Plus(int a, int b)

{				
	return a+b;			
}				
				
push        2				
push        1				
call        @ILT+15(Plus) (00401014)				
add         esp,8				

2、int __stdcall Plus(int a, int b)

{				
	return a+b;			
}				
				
push        2				
push        1				
call        @ILT+10(Plus) (0040100f)				
				
函数内部:				
				
ret         8		

3、int __stdcall Plus(int a, int b)

{
return a+b;
}

push 2
push 1
call @ILT+10(Plus) (0040100f)

函数内部:

ret 8

4、int __fastcall Plus4(int a, int b,int c,int d)

{					
	return a+b+c+d;				
}					
					
push        4					
push        3					
mov         edx,2					
mov         ecx,1					
call        @ILT+5(Plus) (0040100a)					
					
函数内部:					
					
ret         8	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值