进main分析代码
printf("input the flag:");
__isoc99_scanf("%20s", s2);
if ( !strcmp(&flag, s2) )
return puts("this is the right flag!");//提示用户输入 flag。
else
return puts("wrong flag!");//读取用户输入的字符串,最多读取 20 个字符。
}
strcmp
是 C 语言标准库中的一个函数,用于比较两个字符串。它的原型定义在<string.h>
头文件中,其功能是比较两个字符串的字典顺序
函数原型
int strcmp(const char *str1, const char *str2);
参数
str1
:第一个字符串的指针。str2
:第二个字符串的指针。
返回值
- 如果
str1
和str2
完全相同,返回0
。- 如果
str1
在字典顺序上小于str2
,返回负数。- 如果
str1
在字典顺序上大于str2
,返回正数。
就是我们输入个字符串s2符合条件就是s2跟flag完全相同,就是我们找的flag
向上看
int __cdecl main(int argc, const char **argv, const char **envp)
{
int stat_loc; // [rsp+4h] [rbp-3Ch] BYREF
int i; // [rsp+8h] [rbp-38h]
__pid_t pid; // [rsp+Ch] [rbp-34h]
char s2[24]; // [rsp+10h] [rbp-30h] BYREF
unsigned __int64 v8; // [rsp+28h] [rbp-18h]
v8 = __readfsqword(0x28u);
pid = fork();
if ( pid )
{
waitpid(pid, &stat_loc, 0);
}
else
{
for ( i = 0; i <= strlen(&flag); ++i )
{
if ( *(&flag + i) == 105 || *(&flag + i) == 114 )
*(&flag + i) = 49;
}
}
1. **函数签名**:
- `int __cdecl main(int argc, const char **argv, const char **envp)`:这是 `main` 函数的声明,它接受命令行参数和环境变量。
2. **变量声明**:
- `int stat_loc`:用于存储子进程的退出状态。
- `int i`:循环索引。
- `__pid_t pid`:用于存储 `fork` 调用的结果,即子进程的 PID。
- `char s2[24]`:用于存储用户输入的字符串。
- `unsigned __int64 v8`:用于存储从 FS 段寄存器读取的值,用于安全检查。
3. **进程创建**:
- `v8 = __readfsqword(0x28u)`:读取 FS 段寄存器的值,用于安全检查,防止栈溢出攻击。
- `pid = fork();`:创建一个新进程,返回值 `pid` 表示子进程的 PID。如果 `fork` 失败,返回 `-1`。
4. **进程同步**:
- 如果 `pid` 非零(即父进程),调用 `waitpid(pid, &stat_loc, 0)` 等待子进程结束。
- 如果 `pid` 为零(即子进程),执行循环,修改全局变量 `flag` 中的特定字符。
for ( i = 0; i <= strlen(&flag); ++i )
{
if ( *(&flag + i) == 105 || *(&flag + i) == 114 )
*(&flag + i) = 49;
}
把代码修改下:
for (i = 0; i < strlen(flag); ++i) {
if (flag[i] == 'i' || flag[i] == 'r') {
flag[i] = '1';
}
}
遍历一个名为
flag
的字符串,并检查每个字符的 ASCII 值。如果字符的 ASCII 值等于 105(对应字符 'i')或 114(对应字符 'r'),则将该字符替换为 ASCII 值 49(对应字符 '1')。可以去查下ascii表
大概的代码逻辑知道了,去找s2字符串
把i和r改为1就是我们要输入的符合代码逻辑的字符串了