readfsqword

__readfsqword(0x28u)——canary 保护机制,防止调试

  • 程序开始时,定义 v6 = __readfsqword(0x28u)

  • 程序结束时,通过异或或者其他手段检测 v6 的值是否发生改变

  • 若该值发生改变,则程序终止运行


alarm

unsigned int alarm(unsigned int seconds)——设置信号传送闹钟,干扰调试

  • 用来设置信号 sigalrm 在经过参数 seconds 秒数后发送给目前的进程
    如果未设置信号 sigalrm 的处理函数,那么 alarm() 默认处理终止进程

  • 如果在 seconds 秒内再次调用了 alarm 函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代
    当参数 seconds 为 0 时,之前设置的定时器闹钟将被取消,并将剩下的时间返回


read

ssize_t read(int fd, void *buf, size_t count)——用于从文件描述符对应的文件中读取数据

参数意义
fd文件描述符, 从command line获取数据时,为 0
buf读出数据的缓冲区
count每次读取的字节数(是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移)
  • 返回值:

    1. 成功:返回读出的字节数
    2. 失败:返回 -1,并设置 errno。如果在调用 read 之前到达文件末尾,则这次 read 返回 0
  • read 函数可以取代 scanf 从 command line 读取数据


fread

size_t fread(void *ptr, size_t size, size_t count, FILE *stream)——从指定的文件中读取一定数量的数据,并将其存储到指定的内存位置

参数意义
ptr指向要存储读取数据的内存块的指针
size要读取的每个数据项的大小(以字节为单位)
count要读取的数据项的数量
stream文件指针,指向要从中读取数据的文件
  • fread() 函数可用于二进制文件和文本文件。对于文本文件,由于可能存在换行符和不可见字符,使用 fread() 函数读取时需要小心,以免导致错误的结果

  • 需要确保读取的数据 count 不超过目标数组的大小,以避免溢出。

  • 返回值:
    fread() 函数返回实际成功读取的数据数目,如果返回值小于 count,可能已经达到文件末尾或发生了错误


write

ssize_t write(int fd,const void *buf,size_t count)——用于将数据写入到文件描述符对应的文件

参数意义
fd文件描述符(输出到 command line,就是 1)
buf通常是一个字符串,需要写入的字符串
count每次写入的字节数
  • 返回值:

    1. 成功:返回写入的字节数
    2. 失败:返回 -1,并设置 errno
  • write 函数可以代替 printf,往 command line 打印输出


memset

void *memset(void *str, int ch, size_t n)——用于非常量的内存空间初始化

  • 复制字符 ch(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符

  • str 中当前位置后面的 n个字节 用 ch 替换并返回 strch 只有最低的字节起作用

  • 作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作


atoi

int atoi(const char *str)——把参数 str 所指向的字符串转换为一个整数(类型为 int 型)

  • 该函数返回转换后的长整数,如果没有执行有效的转换,则返回零

  • 示例:
    CTF - Reverse_IDA——C伪代码知识1.png

  • 结果:
    CTF - Reverse_IDA——C伪代码知识2.png


atol

long int atol(const char *str)——把参数 str 所指向的字符串转换为一个长整数(类型为 long int 型)

  • 该函数返回转换后的长整数,如果没有执行有效的转换,则返回零

setvbuf

int setvbuf(FILE *stream, char *buffer, int mode, size_t size)——定义流 stream 应如何缓冲,把缓冲区与流相关

  • 如果成功,则该函数返回 0,否则返回非零值

errno_location

int *__errno_location(void)——返回当前线程的变量地址

  • 这个函数的返回值是一个函数指针,这个指针指向线程自己的 errno 的位置,通过对这个指针解引用,就可以访问线程唯一的 errno

  • errno 是 error number 的缩写,意味系统调用错误码
    如果系统调用返回成功,errno 有可能但不一定会置 0;而系统调用出错时,errno 必定会被设为对应的错误编号


malloc

void *malloc(size_t size)——分配所需的内存空间,并返回一个指向它的指针

  • size 为内存块的大小,以字节为单位

  • 该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL


calloc

void *calloc(size_t nitems, size_t size)——分配所需的内存空间,并返回一个指向它的指针

参数意义
nitems要被分配的元素个数
size元素的大小
  • 该函数返回一个指针,指向已分配的内存。如果请求失败,则返回 NULL

  • malloccalloc 之间的不同点:
    malloc 不会设置内存为零;而 calloc 会设置分配的内存为零


gmpz_init_set_str(等同于 mpz_init_set_str)

int mpz_init_set_str (mpz_t rop, char *str, int base)——将 str 字符数组以 base 指定的进制解读成数值并写入 rop 所指向的内存

GMP 又叫 GNU 多精度算术库,是一个提供了很多操作高精度的大整数、浮点数运算的算术库,几乎没有什么精度方面的限制,功能丰富

  • 这三个参数分别是:
参数意义
rop多精度整数变量
str字符串
base进制
  • 示例:
    mpz_powm(op1,op2,op3,op4); // 求幂模函数,即:op1 = op2 ^ op3 mod op4

gmpz_powm(等同于 mpz_powm)

void mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod)——计算 base 的 exp 次方,并对 mod 取模,最后将结果写入 rop 中

  • 运算的过程和 RSA 的加密过程一样

  • 示例:
    mpz_init_set_str(b, “200000”, 10); // 即:b=200000,十进制


gmpz_cmp(等同于 mpz_cmp)

mpz_cmp(mpz_t num1, mpz_t num_2)——比较两个数

  • 示例:
    mpz_cmp(b, c); // 若 b 大于 c,返回1;若 b 等于 c,返回0;若 b 小于 c,返回-1

strcat

char *strcat(char *dest, const char *src)——把 src 所指向的字符串追加到 dest 所指向的字符串的结尾

参数意义
dest指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串
src指向要追加的字符串,该字符串不会覆盖目标字符串
  • 该函数返回一个指向最终的目标字符串 dest 的指针

time

time_t time(time_t *timer)——得到当前日历时间或者设置日历时间

  • 参数说明:
    timer = NULL 时得到当前日历时间(从1970-01-01 00:00:00到现在的秒数)
    timer = 时间数值 时,用于设置日历时间,time_t 是一个 unsigned long 类型
    如果 timer 不为空,则返回值也存储在变量 timer

  • 函数返回:当前日历时间


localtime

struct tm *localtime(const time_t *timer)——使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构,并用本地时区表示

  • timer 是指向表示日历时间的 time_t 值的指针

  • 该函数返回指向 tm 结构的指针,该结构带有被填充的时间信息

  • tm 结构的细节:

struct tm {
   int tm_sec;         /* 秒,范围从 0 到 59 */
   int tm_min;         /* 分,范围从 0 到 59 */
   int tm_hour;        /* 小时,范围从 0 到 23 */
   int tm_mday;        /* 一月中的第几天,范围从 1 到 31 */
   int tm_mon;         /* 月份,范围从 0 到 11 */
   int tm_year;        /* 自 1900 起的年数 */
   int tm_wday;        /* 一周中的第几天,范围从 0 到 6 */
   int tm_yday;        /* 一年中的第几天,范围从 0 到 365 */
   int tm_isdst;       /* 夏令时 */    
};

pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)——用来创建线程,在线程创建以后,就开始运行相关的线程函数

参数意义
pthread_t *thread新创建的线程 ID 指向的内存单元。pthread_t 是一种用于表示线程的数据类型,每一个 pthread_t 类型的变量都可以表示一个线程
const pthread_attr_t *attr用于手动设置新建线程的属性,例如线程的调用策略、线程所能使用的栈内存的大小等。大部分场景中,我们都不需要手动修改线程的属性,将 attr 参数赋值为 NULL,pthread_create() 函数会采用系统默认的属性值创建线程
void *(*start_routine) (void *)新创建的线程从start_rtn函数的地址开始运行。形参和返回值的类型都必须为 void* 类型
void *arg指定传递给 start_routine 函数的实参,当不需要传递任何数据时,将 arg 赋值为 NULL 即可
  • 如果成功创建线程,pthread_create() 函数返回数字 0,反之返回非零值
  • 各个非零值都对应着不同的宏,指明创建失败的原因,常见的宏有以下几种:
    1. EAGAIN:系统资源不足,无法提供创建线程所需的资源
    2. EINVAL:传递给 pthread_create() 函数的 attr 参数无效
    3. EPERM:传递给 pthread_create() 函数的 attr 参数中,某些属性的设置为非法操作,程序没有相关的设置权限

pthread_join

int pthread_join(pthread_t thread, void * * retval)——获取某个线程执行结束时返回的数据

参数意义
thread指定接收哪个线程的返回值
retval接收到的返回值。如果 thread 线程没有返回值,或者不需要接收 thread 线程的返回值,可以将 retval 参数置为 NULL
  • pthread_join() 函数会一直阻塞调用它的线程,直至目标线程执行结束(接收到目标线程的返回值),阻塞状态才会解除
  • 如果 pthread_join() 函数成功等到了目标线程执行结束(成功获取到目标线程的返回值),返回值为数字 0;反之如果执行失败,函数会根据失败原因返回相应的非零值,每个非零值都对应着不同的宏,例如:
    1. EDEADLK:检测到线程发生了死锁
    2. EINVAL:分为两种情况,要么目标线程本身不允许其它线程获取它的返回值,要么事先就已经有线程调用 pthread_join() 函数获取到了目标线程的返回值
    3. ESRCH:找不到指定的 thread 线程

fseek

int fseek(FILE *stream, long offset, int origin)——用于移动文件指针到指定的位置,从而在文件中进行随机访问或定位

参数意义
stream文件指针,指向要操作的文件
offset文件指针偏移量,即要移动的字节数
origin
指定参考位置,可以是以下常量之一:
SEEK_SET:从文件开头开始计算偏移
SEEK_CUR:从当前位置开始计算偏移
SEEK_END:从文件末尾开始计算偏移
  • fseek() 函数可用于二进制文件和文本文件。对于文本文件,由于可能存在换行符和不可见字符,使用 fseek() 函数移动文件指针时需要小心,以免导致错误的结果

  • 返回值:
    成功:fseek 函数将返回零
    失败:返回非零值