scanf汇编的实现过程

出于好奇,探究下scanf汇编怎么工作的,练习下思路。

// func_scanf.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
    char password[1024];
    printf("please input password:        ");
    scanf("%s\n",password);
    printf("what you input is %s",password);
    return 0;
}

关于怎么找main函数另一篇文章提到了寻找特征的方法…这里直接过
在这里插入图片描述
至此的操作是申请用于main函数的变量空间以及保存现场(push ebx,esi,edi),操作于此前文章一样的操作,不做过多赘述。。。
在这里插入图片描述
看注释,很明显对应我们源代码的:printf("please input password: ");不过这里是将字符串入栈,后面再call printf函数完成调用。函数调用方式之前也提到了,哈哈
做下细节,养成查看不太清楚的地址等的操作,跟随push的地址,再数据窗口,我们可以看到:
在这里插入图片描述
证实了我们的猜测,入栈的是printf函数调用的参数。printf函数的学习不是本文的主题,下图为call printf
在这里插入图片描述

调用的同时,入栈call下条指令的地址用于返回(执行完printf可以返回到这句执行,pop出这个地址),也就是下面这句:
在这里插入图片描述
将栈顶下降…接下来执行这句:
在这里插入图片描述
取[local.256]的地址给eax,这里估计是main申请的变量空间我们跟随下内存:
在这里插入图片描述
发现全是CC,我们猜测应该没错,此前对申请的空格键进行初始化,就是用的CC填充
接下来的指令是:
在这里插入图片描述
将EAX(即main申请到的变量空间地址)入栈,再push 了一个地址,我们再次跟进:
在这里插入图片描述

总体发现,其实也就对应了源代码中的: scanf("%s\n",password); 也就是我们的研究对象,scanf函数,call是还是一样,入栈add esp,0x8这条指令的地址,
我们F7步入该函数:
堆栈紫色对应call前下条指令地址:0040104C 往下则是scanf参数,一个是占位符%s,一个是用于存放字符串的地址估计scanf的函数原型需要一个指针作为参数

在这里插入图片描述
在这里插入图片描述
确实也是有个指针参数,哈哈。
进到scanf函数…:
在这里插入图片描述
看到了ebp入栈…更新ebp…抬高esp的操作…又是函数局部变量的申请…
后面的lea eax,[arg.2],跟随后发现其实就是之前入栈的空间地址…
在这里插入图片描述
接下来世这个,就是把取到的地址放到[local.1]里面,其实就是scanf函数前面申请的变量空间,(ebp-4)
在这里插入图片描述
cmp 指令加转移指令,很典型的条件控制跳转了,这里的[arg.1]是占位符%s的栈位置,和0进行cmp指令,很显然,Z标志位是0
后面的jnz指令检查的是Z标志位,当为0则跳转,我们跟随跳转:
在这里插入图片描述

首先操作的是清空ecx…又是组合指令条件判断跳转》。。
在这里插入图片描述
test ecx,ecx改变Z标志位为1,跳转仍然不成立,继续执行
在这里插入图片描述
把[local.1](存放main申请用来保存password变量的空间地址)付给edx:
在这里插入图片描述
占位符地址的赋给eax
在这里插入图片描述
这里不想跟了》。。大概是从键盘读取输入并存到内存空间(之前的地址参数)吧…再跟好累…
回到终端,输入…
在这里插入图片描述
输完,跟踪此前作为参数的地址参数,我们可以看到我们的输入写入到内存了…
在这里插入图片描述
在这里插入图片描述
执行完后,又回到main这边…至此scanf函数汇编讲解就到这里了,需要消化…其实也就是好奇工作原理…

猜你喜欢

转载自blog.csdn.net/weixin_43084928/article/details/88563037