逆向知识第十二讲,识别全局变量,静态全局变量,局部静态变量,以及变量.

 

         逆向知识第十二讲,识别全局变量,静态全局变量,局部静态变量,以及变量.

一丶认识全局的 (静态变量 全局变量)

高级代码:

  

int RetInt()
{
    int n = 0;
    scanf("%d",&n);
    return n;
}
static int g_Number = RetInt(); 
int main(int argc, char* argv[])
{
    g_Number = 3;
    scanf("%d",&g_Number);
    return g_Number;
}

我们的静态局部变量 g_Number 会通过一个函数进行赋值初始化

VC6.0调试查看.

 

我们发现通过栈回朔会调用4个函数

调用顺序:

  _cinit()

  _initterm()

  $E2()

  #E1();

首先讲解一下, _cinit函数是初始化函数,其中里面有个_initterm用来初始化全局变量的(不管是静态的全局变量,还是局部的全局变量,还是全局变量)

E1() E2()函数,这里的两个函数涉及到一个设计的问题.要理解这个问题,我们看下调用_initterm里面是做的什么.

_initterm()

 

 

可以看到内部,函数指针遍历,建立了一个表来查询,然后调用这个函数指针.

这个函数指针就是E2() 为了保证参数一致,返回值一致,所以调用了E2函数,当做一个固定接口

那么E1函数就是具体做事情的

E2函数中查看E1函数调用:

所以说E2只是为了 _initterm的表的接口.

E1函数内部:

 

所以真正工作的函数是在E1内部,因为我们知道,在main函数之前定义全局变量,它会优先于main函数的开始进行初始化,怎么初始化的,就是通过_initerm遍历全局变量表,E2做接口,调用E1函数,进行初始化的.

上面属于Debug下的汇编

Release下的汇编

  PS: Release下的汇编会做优化,有可能你看不到E2这个代理函数了.

找的方法同上,优先于main函数之前找_cinit 然后找到_initterm(注意有多个,不确定是哪个,可以看下入口点特征,前几讲已经说过)

  然后看_initterm的参数,指向的是那个函数指针,我们跳过去即可.

IDA

 

所以有时我们会看到一个.

二丶认识局部静态变量

高级代码:

  

int main(int argc, char* argv[])
{
    static number = argc;
    scanf("%d",&number);
    return number;
}

注意我是初始化给的变量,常量的话优化会直接优化了.很简单,不讲解.

Debug下的汇编代码

 

我们说过,静态局部变量,其实也是一个全局变量,只不过限制了作用域,但是限制的前提是什么,前提就是加标记,所以我们才会看到一个跳转.判断标记的.

 

识别局部变量和参数

这个很简单了,因为一直在用,  一般来说,局部变量都是使用ebp或者esp寻址, 如果碰到ebp-xxx,也就是减量的时候就是访问局部变量,如果变为增量的话就是寻找参数.

 

posted @ 2017-11-28 22:05  iBinary  阅读(2181)  评论(0编辑  收藏  举报