汇编中使用命令行参数

这个纠结了有一两个小时的样子没搞定,后来实在没办法了就自己用c语言写了一个带命令行参数的简单程序然后再进行反汇编,经过大多数次的反汇编再调试后终于明白了如何在使用汇编语言的情况下取得命令行的参数,下面先给出程序然后再慢慢说

这样我们主要看下这几行代码
mov eax,[ebp+4*4]
add eax,4
mov eax,[dword eax]
首先我们是从栈中取出数据,我们可以猜一下我们栈中都有哪些数据
这里我以一个c语言的简单程序做参考

从这个c语言程序中我们可以看出程序在执行后会将main函数的参数入栈,我们就从这里开始看
入栈后栈内大概是这个样子的,前面的是argv,后面的是argc,这时栈顶指针esp在参数argc的上面(理论上,暂时我们这样看),所以我们要想取得argv的首地址的话就要将esp向下移动两个单位,首先从argc尾地址移动到argc首地址,而argc的首地址即表示为argv的尾地址,所以还需要移动一个单位,而在32位系统下我们需要移动的偏移数就是4*2=8,好了,我们再回到我们的程序中来,首先我们的程序在取得argv首地址时是这样的
mov eax,[ebp+4*4]
所以前面说esp暂时理论上是指向argc尾的,现在我在程序的一开始又压入了两个数据,至于是为了什么,我就不说了,我相信你也应该能够理解,当然不理解的话也没关系,以后你在实践中自然会慢慢明白的,我压入的两个数据,再加上argv相对一开始程序进入点栈的偏移位置,所以这里取得argv的首地址的偏移地址应该esp+4*4,我这里将esp的值复制给了ebp了,现在我们取得了argv的首地址,好的开始哦,然后我们再看
add eax,4
我想你应该知道程序的第一个参数是什么吧,对是argv[0],所以这时候我们的eax中保存的是一个指向argv[0]的指针,我想你应该知道指针其实就是一个整形变量,所以我们想要得到命令行的第一个参数也就是argv[1]的话就要移动这个指针,于是我们移动4个字节,这样现在我们的eax是一个指向argv[1]的指针,注意,它是一个指向指针的指针,一开始这里我也有些蒙了,在反汇编几次后我才注意到,从现在来说我们已经得到了命令行的第一个参数,然后我这个程序的目的是调用c语言库函数输入我们的命令行第一个参数,而printf函数接受的参数是一个指针,但是我们的eax是一个指向指针的指针,所以我们需要取得eax的内容,即指向命令行第一个参数的指针,所以
mov eax,[dword eax]
现在我们将eax作为参数传递给printf函数后就可以正确显示了,如果你没有将指向argv[0]的指针eax向后移动4个字节的话,这时你的就是你的程序名,如果你后面还有参数的话这个指针还要向后移动4个字节才能取得第二个参数

–阅读次数(36)

发表评论

电子邮件地址不会被公开。

*