【滴水逆向笔记】C语言参数、变量及if逆向


一、全局变量与局部变量

程序在运行时,会把内存分为如下区域
在这里插入图片描述
代码区:函数的一些功能,可读可执行的,cpu可以把数据读出来,我们写的程序比如if,else,while都在这里面,我们平时的push ebp啥的就是代码区

堆栈:参数,局部变量,临时数据(比如两个数运算的中间结果)。函数不执行的时候数据是不会放到堆栈里的,调用函数后才会把参数放到内存,也就是放到堆栈里,函数执行完毕后,这些曾经放的数就变为垃圾了,比如push ebp的代码执行后就把ebp的值存到堆栈了

堆:比如int arr[10],这个数组,要存很多个整数,不确定存多少个,要动态的往里面存东西,就要用到堆。动态申请的,大小可变的,可读,可写的

全局变量区:比如int x,全局变量区,可读、可写的

常量区:只读的,不可改的,只能把数据读出来(比如内存不让写入啥的)

局部变量

#include “stdafx.h”




void Plus()
{
    int x =10;
    printf("%d",x);
}
void Plus2()
{

    printf("%d",x);
}
int main(int argc, char*argv[])
{
    plus();
}

这个x就是只能大括号里面可以用的,称为局部变量,在plus2中不能打印出来这个就是在正向代码中的局部变量

局部变量特点:
局部变量在程序在程序编译完成后没有分配固定的地址
在所属方法没有调用时,局部变量不会分配内存地址,只有堆栈中分配内存
局部变量方法执行完成后,局部变量的内存将变成垃圾
局部变量只能在方法内部使用,函数A无法使用B的函数变量
函数变量的反汇编识别:[ebp-4],[ebp-8],[ebp-0x4c]

全局变量

#include “stdafx.h”


int x = 10void Plus()
{
    int x =10;
    printf("%d",x);
}
void Plus2()
{

    printf("%d",x);
}
int main(int argc, char*argv[])
{
    plus();
}

这样就可以在plus2打印,就是全局变量
如果把局部变量改成11

#include “stdafx.h”


int x = 10void Plus()
{
    int x =11;
    printf("%d",x);
}
void Plus2()
{

    printf("%d",x);
}
int main(int argc, char*argv[])
{
    plus();
    plus2();
    return 0;
}

输出为1111,因为11改变了全局变量的值

全局变量的特点:
在编译时地址就已经确定,只要程序启动,就会给它分内存,当exe关闭,这个值才会退出,如果没有写值,那就默认是0,重新编译后,才会变地址
全局变量的值可以被所有函数修改,里面存储最后一次修改的值
全局变量的内存会一直存在,直到整个进程结束
全局变量反汇编识别:mov 寄存器,byte/word/dword ds:[0x12345678]
全局变量就是所谓的基址

全局与局部变量总结

如图[ebp-4],[ebp-8]就是局部变量
而下面把两个的值放到eax寄存器,就是对全局变量的操作,而再下个arr的其实是dword ptr,就是把eax移到一这个arr括号里的地址
在这里插入图片描述

二、参数

在这里插入图片描述

参数传递未必通过堆栈还可能通过寄存器
比如:fastcall

push ebx
push eax
mov ecx,dword ptr ds:[]
mov ecx,dword ptr ds:[]
push 45
push 33
call 函数地址

或者有时候函数调用的代码无法查看,参数是把值从函数外面传进来给函数里面用,所以我们要看右边是寄存器的
在这里插入图片描述
比如右00401069的代码,我们要看的就是是不是有内存给edx赋值,函数里面没有给edx赋值,所以我们可以断定edx一定是参数

三.一堆数组的使用

要一个变量存储很多个数,要这样写int arr[10] = {1,3,7,2,8,11,5,23,22,10}

要把值取出来
如果我们这样写



void Function()
{
   printf("%d\n",arr);
}

输出的是4354848
如果我们要把数取出来,代码如下

#include “stdafx.h”

void Function()
{
   printf("%d\n",arr[0]);
   printf("%d\n",arr[1]);
   printf("%d\n",arr[2]);
   printf("%d\n",arr[3]);
   printf("%d\n",arr[4]);
   printf("%d\n",arr[5]);
}

int main(int argc, char*argv[])
{
    Function();
}

打印

1
3
7
2
8
11

找数

int x = arr[9];
printf("%d\n",x);

输出了10

四.分支语句

if语句

要打印出x和y哪个大

#include “stdafx.h”


int x = 10;
int y = 20;

void Function()
{
    if(x>y)
    {
        printf("%d\n",x);
    }
    else
    {
        printf("%d\n",y);
    }    
}


int main(int argc, char*argv[])
{
    Function();
}

如图,打印20
还有elseif

#include “stdafx.h”


int x = 10;
int y = 10;

void Function2()
{
    if(x>y)
    {
        printf("%d\n",x);
    }
    else if(x=y)
    {
        printf("%s\n",'相等');
    }    
    else
    {
        printf("%s\n",'y')
    }
}


int main(int argc, char*argv[])
{
    Function();
    return 0;
}

这种情况输出“相等”

if语句逆向分析

++++++++++++在这里插入图片描述
cmp:减法,根据值修改标志寄存器
所以cmp等修改标志寄存器,紧接着底下一个jcc命令就是我们说的if语句,eax小于或者等于后面那个,(但C语言写的是大于),就跳转到那个地址(C语言里就是不执行,直接跳转了),表达式不成立,才会执行下面的代码

如果写大于等于
在这里插入图片描述
也就是数学逻辑上的非

ifelse语句逆向

在这里插入图片描述
如果cmp下面的jcc指令跳,则跳转到ifelse的语句,给全局变量赋值,如果不跳进入下一次jmp直接跳到清理堆栈,跳转的到的上一行都是jmp,这些jmp跳转的地方都是清理了,如果某个分支没有判断,就是else
在这里插入图片描述
在这里插入图片描述

五.函数内部功能分析

海哥给的例题
在这里插入图片描述

确定上述要素后,看中间白块就行
在这里插入图片描述
返回值:eax里面的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值