首页
社区
课程
招聘
[Win32汇编]对于一个函数(proc)里面定义的局部变量的取地址
发表于: 2015-2-10 23:28 6224

[Win32汇编]对于一个函数(proc)里面定义的局部变量的取地址

2015-2-10 23:28
6224
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcFile	proc
		local	@hFile,@hFileNew,@dwBytesRead
		local	@szNewFile[MAX_PATH]:byte
		local	@szReadBuffer[512]:byte

;********************************************************************
; 打开文件
;********************************************************************
		invoke	CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ,0,\
			OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
		.if	eax ==	INVALID_HANDLE_VALUE
			invoke	MessageBox,hWinMain,addr szErrOpenFile,NULL,MB_OK or MB_ICONEXCLAMATION
			ret
		.endif
		mov	@hFile,eax
;********************************************************************
; 创建输出文件
;********************************************************************
		invoke	lstrcpy,addr @szNewFile,addr szFileName
		invoke	lstrcat,addr @szNewFile,addr szNewFile
		invoke	CreateFile,addr @szNewFile,GENERIC_WRITE,FILE_SHARE_READ,\
			0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
		.if	eax ==	INVALID_HANDLE_VALUE
			invoke	MessageBox,hWinMain,addr szErrCreateFile,NULL,MB_OK or MB_ICONEXCLAMATION
			invoke	CloseHandle,@hFile
			ret
		.endif
		mov	@hFileNew,eax
;********************************************************************
; 循环读出文件并处理每个字节
;********************************************************************
		xor	eax,eax
		mov	@dwBytesRead,eax
		.while	TRUE
			lea	esi,@szReadBuffer
			invoke	ReadFile,@hFile,esi,sizeof @szReadBuffer,addr @dwBytesRead,0
			.break	.if ! @dwBytesRead
			invoke	_FormatText,esi,@dwBytesRead,@hFileNew
		.endw
		invoke	CloseHandle,@hFile
		invoke	CloseHandle,@hFileNew
		invoke	wsprintf,addr @szReadBuffer,addr szSuccees,addr @szNewFile
		invoke	MessageBox,hWinMain,addr @szReadBuffer,addr szSucceesCap,MB_OK
		ret

_ProcFile	endp

以上代码摘自
Windows.环境下32位汇编语言程序设计(第2版)附属光盘\Chapter10\FormatText
★疑问点的是以下这两句为什么要先用lea取得地址放在esi里面 然后在invoke函数里面调用
为什么不用 直接在invoke函数里面 用 addr @szReadBuffer???

lea        esi,@szReadBuffer
invoke        ReadFile,@hFile,esi,sizeof @szReadBuffer,addr @dwBytesRead,0

★我也查了一个资料,找到了如下的答案,但是以上的情况应该不属于这种情况才对啊
这个问题困扰我很久,以致让我对于win32汇编的局部变量的地址的取法有些困扰,到底什么时候
可以用addr 什么时候又必须用lea取呢?

——————————————网络摘取答案开始-----------------------------

addr 局部变量名和全局变量名

当addr后跟全局变量名的时候,用法和offset是相同的;

当addr后面跟局部变量名的时候,编译器会自动用lea指令先把地址取到eax中,然后用eax来代替变量地址使用。

注意addr伪操作符只能在invoke的参数中使用,不能用在类似于下列的场合:
mov eax,addr 局部变量名   ;注意:错误用法

假设在一个子程序中有如下invoke指令:
  invoke  Test, eax, addr szHello
其中Test是一个需要两个参数的子程序,szHello是一个局部变量,会发生什么结果呢?编译器会把invoke伪指令和addr翻译成下面这个模样:
lea    eax,[ebp-4]
push   eax    ;参数2:addr szHello
push   eax    ;参数1:eax
call   Test
发现了什么?到push第一个参数eax之前,eax的值已经被lea eax,[ebp-4]指令覆盖了!也就是说,要用到的eax的值不再有效,所以,当在invoke中使用addr伪操作符时,注意在它的前面不能用eax,否则eax的值会被覆盖掉,当然eax在addr的后面的参数中用是可以的。


——————————————网络摘取答案结束-----------------------------

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
[QUOTE=ifbeyu;1352961];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcFile        proc
                local        @hFile,@hFileNew,@dwBytesRead
                local        @szNewFile[MAX_P...[/QUOTE]


OD 调试一下不就知道了
invoke  ReadFile,@hFile,addr @szReadBuffer,sizeof @szReadBuffer,addr @dwBytesRead,0 这样写也是没有问题的...

老罗使用lea这种写法可能是他的个人习惯...
上传的附件:
2015-2-11 02:00
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢回复
但是我这边的确试过了 运行出错了 所以才认为改掉不行
请看下图


另外附件就是Chapter10\FormatText的源码
帮忙看一看吧,多谢了

下面这张图是用OD里面的状况
上传的附件:
2015-2-11 11:06
0
雪    币: 290
活跃值: (41)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
定址习惯
OFFSET 是 "假指令" --->给编译器看的---静态
lea 是 "8086 指令" ---->程式运行时作用的----动态

若位址固定时用 OFFSET-----可减少程序运行时间
若位址有可能不确定时用 lea

副程序整个移位时.....OFFSET 能找到位址吗????
2015-2-11 11:30
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我刚才添加了一个OD载入的图
你能解释下一个能成功一个失败的原因吗?
2015-2-11 11:42
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=ifbeyu;1353037]感谢回复
但是我这边的确试过了 运行出错了 所以才认为改掉不行
请看下图


另外附件就是Chapter10\FormatText的源码
帮忙看一看吧,多谢了

下面这张图是用OD里面的状况
[/QUOTE]

感觉你还没发现问题所在呀?  我都看出来了
你崩溃也跟  addr 这个写法无关...   是还有地方没有修正
你下面一个esi改过来了吗?  你下面一个esi 不换成addr @szReadBuffer吗?  不换的话  那你esi的值哪里来? esi的值来源不确定,不崩溃才怪!
2015-2-11 11:42
0
雪    币: 290
活跃值: (41)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
??????
一个成功一个失败,表示 OFFSET ADDR 充满了不确定
何必执着呢?
就算此次没问题,难保在别的机子运行出问题
2015-2-11 11:50
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
8
跟这个没有关系,他下面的esi没有改过来...esi的值的不确定性才导致了  我的机器成功,他的机器失败...

我环境XP,他WIN7
2015-2-11 12:21
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
粗心大意啊
惭愧啊惭愧
谢谢啊谢谢
2015-2-11 15:15
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不执着我就不找答案了
不找答案我永远也不懂。
不过我现在不用执着了
因为我开始懂了,也谢谢你的回答
2015-2-11 15:19
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
11
,很正常,粗心大意是人之常情~
2015-2-11 16:11
0
游客
登录 | 注册 方可回帖
返回
//