循环和变量

循环

do…while

do…while 代码定式,debug和release差不多

while_begin:
...                  
...                  ;中间部分为循环体
...
JXX  while_begin     ;注意这里为上跳

示例

int main(int argc, char* argv[])
{
    int nSum = 0;
    int i = 0;
    do
    {
        nSum = nSum + i;
        i++;
        printf("HelloWorld");
    } while (i <= argc);

    printf("HelloWorld");
    printf("HelloWorld");
    printf("HelloWorld");


    return argc;
}

在这里插入图片描述

while

release while 代码定式

//优化成 if条件里面嵌套一个do...while
IF 判断条件			;if
jxx while_end       ;判断为相反的条件下跳
while_begin:		;do
...                  
...                  ;中间部分为循环体
...
JXX  while_begin     ;while 注意这里为上跳循环

while_end

示例

int main(int argc, char* argv[])
{
    int nSum = 0;
    while (argc <= 100)
    {
        printf("%d", nSum);
        argc--;
    }
    return argc;
}

在这里插入图片描述
debug版 while
在这里插入图片描述

for

DEBUG版 for循环 代码定式

FOR_INIT:
	int i=0;
	jmp FOR_CMP
FOR_SETP:
	++i;
FOR_CMP
	i>argc
	jxx FOR_END
FOR_BODY:
	nSum=nSum+i;
	jmp FOR_SETP
FOR_END

示例

int main(int argc, char* argv[])
{
    int nSum = 0;
    int i = 0;
    for (i = 0; i < argc; i++)
    {
        nSum = nSum + i;
        i++;
        printf("%d\n", i);
    }
    return argc;
}

在这里插入图片描述
release版 for循环 代码定式

//优化成if  do...while 形式
//如果判断条件简单可能会出现代码外提( i < argc / 7 ),把 argc / 7的结果提到外面
//判断条件如果是与函数返回值比较则不会外提( i < strlen("hello") ),函数返回值优化不了,因为返回值是未知的
//强度削弱,如果循环体内代码简单,可能会将除法优化成加法执行
int main(int argc, char* argv[])
{
    int i = 0;
    int nSum = 0;
    for (i = 0; i <= argc; ++i)
    {
        nSum = i*100;
        printf("%d\n", nSum);
    };
}

在这里插入图片描述

release版 for循环 累加优化

  • 出现场景:在循环中出现累加
  • 优化形式:编译器可能会视情况将其分为不大于4部分累加
  • 优势:可以减少循环的次数
    代码案例
int main(int argc)
{
    int nSum = 0;

    for (int i = 0; i < 50; i++)
    {
        nSum += i;
    }

    printf("%d", nSum);

    return 0;
}

在这里插入图片描述

变量

全局变量和静态全局

  • 全局变量和静态全局特征 :函数内会通过立即数间接寻址操作变量

初始化位置定位

  • 下断点查找
    main函数下断点找函数调用堆栈,找第二个_initterm(第一个用于初始化std库,第二个保存了初始化全局变量的函数指针)针对不同编译器可以自己写程序调试,观察具体赋值的API
  • 利用od查找
    全局位置下硬件写入断点
    断点来的时候就是初始化的位置

代码示例

/*
_initterm的两个参数存的是函数指针的范围,如这个程序的RetInt函数指针就放在这个范围中
通过遍历这个范围来调用函数指针来在main函数之前初始化
*/

int RetInt()
{
	int n = 0;
	scanf("%d", &n);
	return n;
}
int g_nNumber = RetInt();

int main(int argc)
{
	g_nNumber = 3;
	scanf("%d", &g_nNumber);
	return 0;
}

可以通过IDA找到这个函数,然后找到参数,通过参数获取函数指针数组,依次查找到对应的函数指针,去查看这个函数功能
在这里插入图片描述

局部变量和块变量

局部变量和块变量特征
1.EBP定位

  • EBP + val(>4) 访问的就是参数
  • EBP - val 访问的就是局部变量

2.IDA定位

  • r(返回地址) 上面的是变量

静态局部变量

静态局部变量特征
1。进函数后,初始化过程会有一个条件判断

  • 取标志位判断是否初始化过
  • 未初始化过则进行初始化
  • 已初始化过会直接跳转至初始化结束位置

2.如果是高版本IDA,则会存放在TLS段内,每个线程内独享

代码示例

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

vc6.0
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值