以下内容由原面试题 PDF 整理为网页存档,题目本身未附答案。
本次面试题分为简答题、实践题、自选题和问答题:
- 简答题要求理解问题并回答。
- 实践题需要按照要求编写 C 语言代码。
- 自选题考查 CTF 不同方向的基础知识,只需选择一个方向作答。
- 问答题需要按照题目叙述作答。
简答题
0x00|自增符的使用(难度:1)
请讲解前缀自增 ++i 和后缀自增 i++ 的区别。
0x01|包含头文件(难度:1)
请简述 #include <stdio.h> 和 #include "stdio.h" 这两种写法的区别。
0x02|简单的递归(难度:1)
分析如下代码,简述其运行原理及递归的原理:
void printnum(long num)
{
if (num < 0)
{
putchar('-');
num = -num;
}
if (num / 10)
{
printnum(num / 10);
}
putchar("0123456789"[num % 10]);
}
0x03|2B 的运算符(难度:2)
分析如下代码并给出合理解释:
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
if (a+++b)
if (a*!~b)
b++;
else
a++;
printf("%d %d %d\n", a, b, a++-+-+-+-++b);
return 0;
}
0x04|静态变量和全局变量的区别(难度:2)
请简述在 C 语言中静态变量与全局变量之间的主要区别。
0x05|静态变量(难度:2)
请测试以下代码,并讲解输出结果产生的原因:
#include <stdio.h>
void func()
{
static int count = 0;
int local = 0;
count++;
local++;
printf("count = %d, local = %d\n", count, local);
}
int main()
{
for (int i = 0; i < 3; i++)
{
func();
}
return 0;
}
// output
// count = 1, local = 1
// count = 2, local = 1
// count = 3, local = 1
0x06|结构体内存对齐(难度:3)
根据以下 C 语言结构体定义回答问题。在 GCC 编译器默认配置下,不考虑优化及 #pragma pack 等影响内存对齐的指令。
struct MyStruct
{
char a; // 1 字节
int b; // 4 字节
char c; // 1 字节
double d; // 8 字节
short e; // 2 字节
};
- 该结构体在 32 位和 64 位系统上的大小分别是多少?请解释原因。
- 如果希望优化该结构体的内存布局,应该如何重新排列这些字段?重新排列后的结构体在 32 位和 64 位系统上的大小分别是多少?
- 解释结构体对齐的原则,以及为什么需要进行结构体对齐。
0x07|指针(难度:4)
请测试以下代码,分析程序错误的原因并修正错误:
#include <stdio.h>
#include <stdlib.h>
void process(int *ptr, int size)
{
// 动态分配一个整型数组,大小为 size
int *array = (int *)malloc(size * sizeof(int));
// 初始化数组
for (int i = 0; i < size; i++)
array[i] = i * i;
// 将 ptr 指向动态分配的数组
ptr = array;
}
int main()
{
int *ptr = NULL;
int size = 5;
process(ptr, size);
// 打印 ptr 指向的数组元素
for (int i = 0; i < size; i++)
printf("%d ", ptr[i]);
free(ptr);
return 0;
}
实践题
0x08|求平均数(难度:1)
实现一个函数,该函数接收一个整数数组和数组大小作为参数,返回数组中所有元素的平均值。
详细要求:
- 函数名为
average。 - 函数的参数为一个整数数组
arr和一个整数size,表示数组大小。 - 函数返回一个
double类型的值,即数组元素的平均值。 - 考虑整数除法的问题,计算平均值时请确保结果为小数。
- 编写一个简单的
main函数测试average函数。
0x09|温度转换器(难度:2)
编写一个 C 程序,实现一个简单的温度转换器,将摄氏温度转换为华氏温度。程序应从命令行接收一个摄氏温度值,并打印对应的华氏温度值。
详细要求:
- 程序应从命令行读取一个浮点数,表示摄氏温度。
- 使用公式
华氏温度 = (摄氏温度 × 9 / 5) + 32进行转换。 - 打印转换后的华氏温度,保留两位小数。
- 如果输入不是有效的浮点数,程序应打印错误信息并退出。
- 编写一个简单的
main函数测试温度转换器。
0x0A|文本加密器(难度:3)
实现一个简单的文本文件加密器。
详细要求:
- 编写一个程序,实现简单的文本文件加密功能。
- 程序应从命令行接收两个参数:源文件名和目标文件名。
- 加密算法使用凯撒加密,对字母进行加密。
- 程序应能正确处理文件读写错误等情况。
- 编写一个简单的
main函数测试加密器。
方向自选题
以下方向只需选择一个作答。
Pwn
请简述段和节的区别和联系。
Reverse
阅读以下汇编代码,可借助 AI 等工具,结合注释提示,将汇编代码大致翻译为对应的 C 语言代码。
push rbp
mov rbp, rsp ; 以上两句为标准函数头
sub rsp, 30h ; 开辟局部变量的栈存储空间
call __main ; 忽略
mov [rbp+i], 0 ; [rbp+i] 为循环变量 i
jmp short Label1 ; 可忽略 short
Label2: ; CODE XREF:main+2F↓j
mov eax, [rbp+i]
mov edx, eax ; edx 存储第一个参数
lea rcx, add ; rcx 存储第二个参数
call printf ; 以上四条指令为函数调用
add [rbp+i], 1
Label1: ; CODE XREF:main+14↑j
cmp [rbp+i], 4
jle short Label2
mov eax, 0
add rsp, 30h ; 恢复局部变量的栈存储空间
pop rbp
retn ; 以上两句为标准函数尾
Crypto
简述 RSA 加密过程。
Misc
如果题目附件是一张图片,你有什么做题思路?
Web
文件上传中 %00 截断的原理是什么?利用的前提条件是什么?
问答题
- 在 Kerberos 安全认证流程中,客户端依次向哪三方进行了请求?
- 什么是网络端口?常见的端口有哪些?
- IP 地址与域名的关系是什么?
- 简述进程、线程和协程的区别。
- 什么是渗透测试?简述渗透测试的几个步骤。
- 简述什么是“近源攻击”。
- 网卡有哪些工作模式?简述这些工作模式。
- 简述模糊测试(Fuzzing)的原理,并解释它属于黑盒测试、白盒测试还是灰盒测试。
