反汇编的应用2-debug

下面是从汇编级别来看指针的操作,查看因指针操作而导致的问题。

#include "stdafx.h"
#include <stdlib.h>

void allocate(int *p)
{
	p = (int*)malloc(sizeof(int));
	*p = 5;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int* p = NULL;
	allocate(p);

	printf("p = %d\n", *p);
	system("pause");
	return 0;
}

按照上述的代码,在压栈操作时,将p的值0压入;并且p在主函数中的地址为0x0013ff60;

但是在函数内部,p的地址为0x0013fe8c;因为p作为局部变量,所以在栈上开辟;

由此可见,函数中对于p的赋值,不可能改变主函数中的值;

那么要进行修改的话,只要将p的地址传入即可,也即指针的指针。

void allocate2(int **p)
{
	*p = (int*)malloc(sizeof(int));
	**p = 5;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int* p = NULL;
	allocate2(&p);

	printf("p = %d\n", *p);
	system("pause");
	return 0;
}

经过上述的修改后,传入的是p的地址:0x13ff60,

 15: 	*p = (int*)malloc(sizeof(int));
0041145E 8B F4            mov         esi,esp 
00411460 6A 04            push        4    
00411462 FF 15 CC 82 41 00 call        dword ptr [__imp__malloc (4182CCh)] 
00411468 83 C4 04         add         esp,4 
0041146B 3B F4            cmp         esi,esp 
0041146D E8 E7 FC FF FF   call        @ILT+340(__RTC_CheckEsp) (411159h) 
00411472 8B 4D 08         mov         ecx,dword ptr [p] 
00411475 89 01            mov         dword ptr [ecx],eax (1)
    16: 	**p = 5;
00411477 8B 45 08         mov         eax,dword ptr [p] 
0041147A 8B 08            mov         ecx,dword ptr [eax] 
0041147C C7 01 05 00 00 00 mov         dword ptr [ecx],5

语句1将malloc申请空间的地址赋给13ff60地址空间,也即13ff60内存中存有指向内存空间的地址值,比如A;

00411477 8B 45 08         mov         eax,dword ptr [p] // eax = 13ff60;
0041147A 8B 08            mov         ecx,dword ptr [eax] // ecx = A;
0041147C C7 01 05 00 00 00 mov         dword ptr [ecx],5 // 将5赋给地址为A的内存;

后面的*p;因为传入的是13ff60地址,修改的也是这个地址的内存值,所以主程序中的p值存储的就是allocate2函数中申请的那个空间。

注:

在函数内部申请空间的做法,并且将回传的做法不好,因为申请空间的代码和释放空间的代码不在一个函数内,造成程序员的负担,很容易内存泄露;


下面又是一个查找错误的问题:

class useStr{
public:

	void setStr1(){
		pc = (char*)malloc(4);
		pc = "abc";
	}

	void setStr2(){
		char a[4] = "abc";
		pc = a;
		printf("in setStr2, %s\n", pc);
	}

	char* getStr(){
		return pc;
	}

private:
	char* pc;
};

int _tmain(int argc, _TCHAR* argv[])
{
	useStr us1, us2;

	us1.setStr1();
	printf("%s\n", us1.getStr());

	us2.setStr2();
	printf("%s\n", us2.getStr());

	system("pause");
	return 0;
}

上述的第一个输出为正确的abc,而后者输出则是乱码。

但奇怪的是后者在代码内进行输出时,却是正常的。可能的问题就是pc的值发生变化,或者pc所指向的内容发生变化。

经过ollydbg的调试,us2.setStr2()中p指向的”abc”设置在栈上,但是栈中的值在调用后续的us2.getStr()时,其中的内容被替换掉。因此造成最终的输出值发生改变。

具体改变”abc”值的代码主要是debug版本为调试在栈中添加的”CC”等特征码。然后在调用printf时,该栈处的内容又被修改。

有趣的是,当我们将版本设置为release版本后,上述的问题就不存在了,主要的原因是栈中的信息没有因为debug中的信息填充而被修改,或者因为其他函数的调用而被修改。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值