首页 > 其他分享 >C语言逆向——预处理之宏定义、条件编译与文件包含

C语言逆向——预处理之宏定义、条件编译与文件包含

时间:2023-08-02 18:32:37浏览次数:30  
标签:定义 包含 int 之宏 C语言 编译 预处理 define

预处理之宏定义、条件编译与文件包含

预处理一般是指在程序源代码被转换为二进制代码之前,由预处理器对程序源代码文本进行处理,处理后的结果再由编译器进一步编译。

预处理功能主要包括宏定义、文件包含、条件编译三部分。

宏定义

简单的宏:#define 标识符 字符序列

#define FALSE 0


#define NAME "LUODAOYI"

#define __IN
#define __OUT

极端例子:

#define NAME "LUODAOYI"


#define A int method() {


#define B char buffer[0x10];

#define C strcpy(buffer,NAME);

#define D return0;}

#define E method();
 
// use
A
B
C
D
 

int main()

{
 E

return0;

}

 

练习下,可以看到,编译器直接替换完了!

C语言逆向——预处理之宏定义、条件编译与文件包含_宏定义

 

 

 

带参数的宏:#define 标识符(参数表) 字符序列

#define MAX(A,B)((A)>(B)?(A):(B))
 

int method()

{

int x = 1;


int y = 2;


int z = MAX(x,y);


return0;

}
多行定义,'\' 后不可有空格

#define A for(int i=0;i<length;i++)\

{\

 printf("%d \n",arr[i]);\

}\
 

int method(int arr[],int length)

{
 A

return0;

}

int main()

{

int arr[] = {1,2,3,4,5,6,7,8,9,0};


 method(arr,10);

}
直接使用宏定义函数

#define MYPRINT(X,Y) for(int i=0;i<(Y);i++)\

{\

 printf("%d \n",(X)[i]);\

}\

return0;\

 

int main()

{

int arr[] = {1,2,3,4,5,6,7,8,9,0};


 MYPRINT(arr,10);

}

使用宏定义函数和普通函数的区别:使用宏比较节省空间,因为使用宏定义函数,没有堆栈提升操作,也就是不会作为函数调用而是直接内联到代码内。

宏定义的注意事项

  1. 只做字符序列的替换工作,不做任何语法检测,在编译前处理
  2. 宏名标识符与左圆括号之前不允许有空白符,应紧接在一起
  3. 为了避免出错,宏定义中给形参加上括号
  4. 多行声明时,回车换行前要加上字符'\',注意字符'\'后要紧跟回车键,中间不能有空格或其他字符
  5. 末尾不需要分号

条件编译与文件包含

条件编译,就是当满足条件时才会要求编译器进行编译;如下代码当if成立则变异printf,否则就不编译:

int main()

{

#if0


 printf("--------")

#endif

return0;

}
应用场景:

#define DEBUG 0

 

int main()

{

#if DEBUG


 printf("--------")

#endif

return0;

}

可以通过反汇编代码来看一下:

C语言逆向——预处理之宏定义、条件编译与文件包含_条件编译_02

可以看见printf根本没有进行编译。

if define之类的,我们都称之为预处理指令,如下是常用的。

预处理指令:条件编译是通过预处理指令实现的

指令

用途

#define

定义宏

#undef

取消已定义的宏

#if

如果给定条件为真,则编译下面代码

#endif

如果前面的#if给定条件不为真,当前条件为真,则编译下面代码

#else

同else

#endif

结束一个#if…#else条件编译块

#ifdef

如果宏已经定义,则编译下面代码

#ifndef

如果宏没有定义,则编译下面代码

#include

包含文件

文件包含

文件包含有两种格式,分别是 #include "file" 和 #include <file>

使用双引号:系统首先到当前目录下查找被包含的文件,如果没找到,再到系统指定的包含文件目录(由用户在配置环境时设置)去找
使用尖括号:直接到系统指定的包含文件目录去查找

所以系统文件用 <> 尖括号,自己定义的文件用 "" 双引号

文件包含可能会存在重复包含的情况,我们可以使用条件编译、前置声明的方式避免。

标签:定义,包含,int,之宏,C语言,编译,预处理,define
From: https://blog.51cto.com/u_11908275/6941599

相关文章

  • C语言逆向分析——Switch语句,为何大多数情况较if语句更高效?就是因为查找表
    Switch语句Switch语句也是分支语句的一种,其语法如下:switch(表达式){case常量表达式1:语句;break;case常量表达式:语句;break;case常量表达式:语句;break;......default:语句;break;}需要注意如下几点:表达式结束不能是浮点数case后的常量......
  • C语言逆向——数组和结构体,数组多维只是一个编译构造的假象,本质会转成一维数组,结构体
    数组数组是C语言中非常重要的一个概念,学习C语言主要就是两个知识点:数组、指针,学好这两个,那么你的C语言一定也会很好。什么是数组?或者说什么情况下我们需要使用数组,比如说我们需要定义一个人的年龄,我们可以定义一个变量来表示,但是如果我们需要定义三个人的年龄呢?那就需要三个变量来......
  • C语言学习笔记
    C语言入门写代码流程写C代码1、创建工程2、创建项目.cpp-c++文件.c-源文件.h-头文件head3、写代码1、main主函数,程序的入口,有且仅有一个//包含一个叫stdio.h的文件//std-标准standardinnputout标准输入输出,所以函数中有输入、输出语句都要包含这个文件#in......
  • c语言作业之求两个数的最大公约数
    intmain()//最大公约数{ intn=0; intm=0; intr=0; printf("请输入两个数字:"); scanf("%d%d",&n,&m); while(n%m)//n取模m { r=n%m; n=m; m=r; } printf("最大公约数为:%d\n",m); return0;}......
  • 【C语言基础】分支和循环
    目录一、分支语句1.1if语句1.2switch语句二、循环语句2.1while语句2.2for语句2.3dowhile语句一、分支语句1.1if语句语法结构if(表达式1)//如果表达式1为真,执行语句1;如果为假,不执行。语句1;if(表达式1)//如果表达式1为真,执行语句1;如果为假,执行语句2。语句1;else语句2;//多......
  • 我的第八次C语言练习
    今天原本还想多学点,结果代码打到一半突然没保存到,导致只能重新打,浪费了很多时间,也就没学什么。//intmain(void)//{// floata;// a=3.1415926;// printf("%fcanbewritten%e\nalsocanbewritten%a",a,a,a);// return0;//}今天学的是浮点数,其中%f,%e,%a分别指的......
  • C语言, 字符串
    #include<stdio.h>#include<stdlib.h>#include<string.h>char*tt3="web数学算法";intstr_comparer(){//字符串是个指向字符串开头的指针char*tt1="aac";char*tt2="aa";//字符串可以直接转换成整数,前面加......
  • C语言学习笔记
    C语言程序设计求100-500的质数#include<stdio.h>intmain(){inti,j,n,f=1;for(i=100;i<=500;i++){f=1;for(j=2;j<i/2;j++){if(i%j==0){f=0;}}if(f==1){printf(&......
  • 【C语言】调试的运用,代码出现错误如何自己解决
    1.了解调试。什么是调试?_当我们发现程序中存在的问题的时候,那下⼀步就是找到问题,并修复问题。_这个找问题的过程叫称为调试,英⽂叫debug(消灭bug)的意思。_调试⼀个程序,⾸先是承认出现了问题,然后通过各种⼿段去定位问题的位置,可能是逐过程的调试,也可能是隔离和屏蔽代码的⽅式,找到问......
  • 【C语言】双引号中使用宏定义
     目录快速答案详细讲解举个例子方法及代码参考资料 快速答案使用星号占位符(*)printf("%*d",-4,"12");//或printf("%-*d",4,"12");//得到的输出:"12"(12后面有两个空格) 详细讲解举个例子通常,我们为了保证输出格式美观,会使用下面的方式......