逆向 string.h 函数库 memset、strcpy、strcmp 函数
memset 函数
- 函数原型:void *memset(void *str, int c, size_t n)
- 主要功能:复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符
- C/C++ 实现:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char ** argv)
{
char str[20] = "AAAAAAAAA";
memset(str, 'v', 10);
cout << str << endl;
return 0;
}
- 以上程序的作用是循环复制 10 个字符 ‘v’ 到 str 所指向的字符串,执行结果:

- 函数运行步骤:

- 逆向分析:这个函数的作用主要是将特定的字符覆盖规定的字符串,所以首先需要取出传入 memset 函数的三个参数,并且判断第三个和第二个参数是否为 0。如果第三个参数为 0,则直接返回第一个参数所指向的字符串的首地址;如果第二个参数为 0 且第三个参数小于 100,则程序继续往下执行,反之跳出函数进行错误处理

- 之后判断第三个参数是否小于 4,为什么要进行这个判断呢,这个先不说答案在下面。然后判断参数一传入的字符串地址是否数据对齐,如果没有对齐就对其进行对齐操作

- 对齐判断后就开始复制字符串了,值得注意的是这里复制字符串的方式并不是循环复制 1 个字节,而是 4 个字节 4 个字节的复制,最后剩余的再每次 1 个字节的循环复制。比如我要复制 10 个字节,先循环两次复制 8 个字节,最后循环两次每次复制 1 个字节,还记得上面判断第三个参数为什么小于 4 吗,因为小于 4 的话就不必要每次 4 个字节的复制了,直接跳转到每次复制 1 个字节处即可


- 最后将覆盖完的字符串首地址放入 eax 中,函数返回

- 总结:memset 流程图

strcpy 函数
- 函数原型: char *strcpy(char *dest, const char *src)
- 作用:把 src 所指向的字符串复制到 dest
- C/C++ 实现:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char ** argv)
{
char str[20] = "AAAAAAAAA";
strcpy(str, "BBBBBB");
cout << str << endl;
return 0;
}
- 以上程序的主要作用是将 “BB…” 复制到 str 字符串中,运行结果如图所示

- 函数运行步骤

- 逆向分析:首先取出传入 strcpy 函数的第一个和第二个参数


- 之后判断第二个参数所指向的字符串是否数据对齐

- 由于 0040121B 并不是 4 的倍数,显然数据没有对齐,从而发生跳转,进行数据对齐操作

注:对第二个参数的字符串是如何进行数据对齐操作的呢?方法简单,每次从第二个参数取出一个字符存入第一个参数指向的字符串的地址,并且第二个字符串指针加一,之后再次判断第二个参数的字符串地址是否数据对齐,如果还没有对齐就循环上述操作,直到数据对齐完毕
- 进行完数据对齐操作之后,将第二个参数所指向的字符串循环每次复制 4 个字节到第一个参数所指向的字符串 + 2 的地址中(因为进行了对齐操作),直到这 4 个字节当中不包含 00 标志(00 表示字符串结尾)

- 由于下面 4 个字节包含 00 字符,所以只是复制了一次

- 最后计算出 00 字符处于 4 个字节的哪一个位置,如图所示处于第 4 个位置,故发生跳转

- 之后把 00 字符串传入 edi 所指向的内存地址

- 寄存器状态和内存分布如图所示:


- strcpy 函数的流程图:

strcmp 函数
- 函数原型:int strcmp(const char *str1, const char *str2)
- 函数功能:把 str1 所指向的字符串和 str2 所指向的字符串进行比较(按字符的 Ascii 码进行比较)
- C/C++ 实现:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "AAAaaa");
strcpy(str2, "AAaaaa");
ret = strcmp(str1, str2);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str1 大于 str2");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
- 以上程序的功能十分简单,比较 str1 和 str2 的大小,并且打印出结果。运行结果如图所示:

- strcmp 函数运行步骤:

- 逆向分析:首先进入 strcmp 函数,之后会取出传入 strcmp 函数的两个参数,也就是 str1 和 str2,取完参数之后判断 str1 字符串是否数据对齐,数据对齐就是 str1 字符串的首地址是否为 4 的倍数,如果 str1 字符串没有数据对齐,那么就会跳转到 0x7571938C 的地方进行数据对齐操作,在数据完成对齐后会 jmp 到 0x7571934E 的地址继续往下执行

- 从寄存器可以看出 ecx 储存的是 str2 字符串的首地址,而 edx 储存的是 str1 字符串的首地址

- 接下来取 str1 字符串的头四个字节放在 eax 中,之后按一个字节的大小分别与 str2 字符串相应的字符做大小比较,如果不相等就发生跳转,需要注意的时,这里比较的是 ascii 码的大小,比如 ‘A’ 字符 ascii 码为 41,而 ‘a’ 字符 ascii 码为 61,这样的话 ‘a’ 就会比 ‘A’ 字符大

- 由于 str1 是 ‘AAAaaa’,而 str2 是 ‘AAaaaa’,所以在第三个字符比较时由于 A != a,故发生了跳转,如果前四个字节都相等的话,会将 str1 和 str2 的指针都向后指 4 个字节,在循环以上过程进行比较

- 值得注意的是如果字符判断相等之后,如果发现 str1 对应的字符为 0(字符串结尾标志),就都会跳转到 0x75719380 这个地址,并且函数返回 0,表示字符串相等
- 比如 str1 为 ‘Aaa’,str2 为 ‘Aaaaaa’,由于 str1 的第四个字符为 0,而前面的字符又和 str2 相等,所以判断 str1 等于 str2;但是如果 str1 为 ‘Aaaa’,而 str2 为 ‘Aaa’ 的话,则 str1 大于 str2,因为进行结尾比较的是 str1 而不是 str2,所以 str1 大于 str2

- 最后根据 CF 标志位,以 sbb 计算的结果作为函数的返回值,如图所示 eax 的值为负数,根据 strcmp 函数的返回值文档可以看出如果函数返回值小于 0,则表示第一个参数字符串小于第二个参数字符串,也就是 str1 小于 str2

- 为什么通过 sbb 操作指令和 CF 标志位能判断出字符串的大小呢,比如 str1 = ‘AAAA’,而 str2 = ‘AAAaaaBB’,由于前三个字符相等所以比较第四个字符,str1 的第四个字符为 A(ascii:41),而 str2 的第四个字符为 a(ascii:61),所以比较的指令就为 cmp 41,61,而 cmp 指令是根据两个操作数相减去影响标志位的,所以 41 - 61 就为负数,导致数据溢出位 CF 变为 1,而 sbb eax,eax 指令就相当于 eax - eax - CF,所以也就能比较字符的大小了
- 那就有人问了,假如大于的话,CF 就为 0 了,岂不是两个字符串相等了吗,其实不会这样的因为在最后使用了 add eax,0x1 的操作,所以只要是大于的话返回值就会为 1,避免了和 0 之间的冲突(shl eax,1 也是同样的道理,为的是避免 add eax,0x1 在负数加一之后和 0 引发冲突)

逆向 memset、strcpy、strcmp 函数到此结束,如有错误,欢迎指正
逆向 string.h 函数库 memset、strcpy、strcmp 函数的更多相关文章
- 实现字符串函数,strlen(),strcpy(),strcmp(),strcat()
实现字符串函数,strlen(),strcpy(),strcmp(),strcat() #include<stdio.h> #include<stdlib.h> int my_ ...
- numpy函数库中一些常用函数的记录
##numpy函数库中一些常用函数的记录 最近才开始接触Python,python中为我们提供了大量的库,不太熟悉,因此在<机器学习实战>的学习中,对遇到的一些函数的用法进行记录. (1) ...
- 逆向 string.h 函数库 strlen、memchr、strcat 函数
strlen 函数 主要功能:返回字符串的长度 C/C++ 实现: #include <iostream> #include <stdio.h> #include <st ...
- 逆向 time.h 函数库 time、gmtime 函数
0x01 time 函数 函数原型:time_t time(time_t *t) 函数功能:返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位.如果 se ...
- C语言中的string.h中的内存字符串处理函数
转载请注明出处:http://blog.csdn.net/zhubin215130/article/details/8993403 void *memcpy(void *dest, const voi ...
- 自己实现字符串操作函数strlen(),strcat(),strcpy(),strcmp()
1.strlen()函数是求解字符串的有效长度的 1)非递归实现 size_t my_strlen(const char *str) { assert(str != NULL); //断言,保证指针 ...
- Mysql 常用函数(10)- strcmp 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html strcmp 的作用 比较两个字符串的顺序是否完全 ...
- 使用c函数库的两个函数strtok, strncpy遇到的问题记录
1. strtok 问题背景: 解析形如 “1,2,3,4,5”字符串到整数数组 (1)计算个数 char* delim = ","; int count = 0; int *nu ...
- 13-C语言字符串函数库
目录: 一.C语言字符串函数库 二.用命令行输入参数 回到顶部 一.C语言字符串函数库 1 #include <string.h> 2 字符串复制 strcpy(参数1,参数2); 参数1 ...
随机推荐
- 常见 git 需求整理(持续更新中)
首发于 语雀文档 突然感觉自己对 git 还是挺熟悉的,因为团队里新来的七八号应届生来问我 git 问题,基本没有答不上的情况,但为了能更好地对知识进行整理,还是记录一下为好. (希望能)持续更新.. ...
- Redis工具收费后新的开源已出现
作者:三十三重天 博客: zhouhuibo.club 引言 Redis工具哪家强,中国山东找蓝翔.哎呀,串台了. 众所周知,开源的最终还是收费. Reids Desktop 秉承了这一理念,苦逼的程 ...
- JAVA使用Collator对中文排序
首先创建一个集合 public static List<String> init() { List<String> list = new ArrayList<String ...
- 【odoo14】第三章、创建插件
现在我们已经有了开发环境并了解了如何管理实例及数据库,现在让我们来学习下如何创建插件模块. 本章内容如下: 创建和安装模块 完成manifest文件 组织模块文件结构 添加模型 添加菜单及视图 添加访 ...
- 15款NOSQL数据库
1.MongoDB 介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.主要解决的是海量数据的访问效率问题,为WEB应用提供可扩展的高性能数据存储解决方案.当数据量达到50GB以上 ...
- 练习使用Unicorn、Capstone
Unicorn是一个轻量级的多平台,多体系结构的CPU仿真器框架.官网:http://www.unicorn-engine.org/ Capstone是一个轻量级的多平台,多体系结构的反汇编框架.官网 ...
- ArrayList这篇就够了
提起ArrayList,相信很多小伙伴都用过,而且还不少用.但在几年之前,我在一场面试中,面试官要求说出ArrayList的扩容机制.很显然,那个时候的我并没有关注这些,从而错过了一次机会.不过好在我 ...
- Amundsen在REA Group公司的应用实践
REA Group是一家专门面向房地产与实业资产的跨国数字广告公司. 他们主要为消费者提供房地产购买.出售与租赁服务,同时发布各类房产新闻.装修技巧以及生活方式层面的内容.每一天,都有数百万消费者访问 ...
- 在M1芯片的Mac系统上做.net core开发靠谱吗?
作为一个7年老.NET程序员,最近几年苹果慢慢接替微软,成为我心中最酷的科技公司. 为什么我会选择Mac os作为我的开发环境? 很多做.net的同学都使用Windows系统作为自己的开发环境,我其实 ...
- 基于react hooks,zarm组件库配置开发h5表单页面
最近使用React Hooks结合zarm组件库,基于js对象配置方式开发了大量的h5表单页面.大家都知道h5表单功能无非就是表单数据的收集,验证,提交,回显编辑,通常排列方式也是自上向下一行一列的方 ...
