能力值:
( LV13,RANK:460 )
|
-
-
2 楼
004F4429 |. 8D55 E8 lea edx, dword ptr [ebp-18] ; 100690
004F442C |. 8D45 F0 lea eax, dword ptr [ebp-10] ; 0
004F442F |. E8 400EFBFF call 004A5274 ; TfrmMain_FormKeyDown
lea 虽然是加载有效地址的汇编指令助记符,但多数情况用于算术运算,不过在上面的主调函数中,应该确实是
加载有效地址。
例如,将 [ebp-18]的地址加载到edx中,将 [ebp-10]的地址加载到eax中,这是为调用地址 004A5274 处的函数前,做好传递参数的准备,两个参数的地址现在位于edx与eax中,照理讲,还需要将2个参数压栈,即
push [edx]
push [eax]
这样,被调函数才能正确接收到参数,但是在楼主的输出信息中没有看到上面两条指令,可能是编译器出于性能优化的原因而省略了,
注意上面的 push [edx] ,这种格式为“存储器引用”,因为lea的关系,现在edx中保存的是注释中100690的地址,要取得该地址处的值,即100690,就需要存储器引用才能取值(如果你确定被调函数接收的参数确实是类似100690的值)
上面的汇编指令如果用 mov 来改写,应该如下:
mov edx, dword ptr [ebp-18] ; 100690
push edx ; 第二个参数先压栈
mov eax, dword ptr [ebp-10] ; 0
push eax ;第一个参数压栈
call 004A5274 ;TfrmMain_FormKeyDown
当然,由于新增了2条push 指令,call指令的地址不会是 004A5274 ,具体取决2条push指令的对应机器码字节长度。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
非常感谢,我先慢慢消化下~
|
能力值:
( LV3,RANK:20 )
|
-
-
4 楼
根据楼主的反汇编代码,可以初步看出是DELPHI编写的程序,根据DELPHI程序函数的调用约定,参数如果少于三个的话,是采用EAX,EDX,ECX来传递参数的,所以
004F4429 |. 8D55 E8 lea edx, dword ptr [ebp-18] ; 100690
004F442C |. 8D45 F0 lea eax, dword ptr [ebp-10] ; 0
004F442F |. E8 400EFBFF call 004A5274 ; TfrmMain_FormKeyDown
这段代码的意思就是 call 004A5274(eax,edx);
如果要写成MOV的意思,就是:
mov edx,ebp-18
mov eax,ebp-10
call 004a5274
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
[QUOTE=zbig;1353383]根据楼主的反汇编代码,可以初步看出是DELPHI编写的程序,根据DELPHI程序函数的调用约定,参数如果少于三个的话,是采用EAX,EDX,ECX来传递参数的,所以
004F4429 |. 8D55 E8 lea edx, dword ptr [ebp-18] ...[/QUOTE]
谢谢
这样写 mov edx,ebp-18 调试不通过
ebp-18 应该是个局部变量吧
是不是先计算出 ebp-18的值然后 mov 给eax
|
能力值:
( LV13,RANK:460 )
|
-
-
6 楼
根据ebp的负偏移来访问的栈地址,应该是局部变量没错.
这是个双字(4字节的局部变量) .即 dowrd ptr
[ebp-18]是一种叫做"存储器寻址"的操作数模式,
用于取得"栈底指针指向的地址处,偏移18h字节地址处的值",然后将该值复制到eax中
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
保持队型
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
[QUOTE=shayi;1353457]根据ebp的负偏移来访问的栈地址,应该是局部变量没错.
这是个双字(4字节的局部变量) .即 dowrd ptr
[ebp-18]是一种叫做"存储器寻址"的操作数模式,
用于取得"栈底指针指向的地址处,偏移18h字节地址处的值",然后将该值复制到eax...[/QUOTE]
如何自己定义2个变量,然后传给他
例如:
Var
S1,S2:STRING;
BEGIN
ASM
PUSHAD
lea edx, S1
lea eax, S2
call 004A5274
POPAD
END;
END;
不会弄~~
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
感谢解答,受益非浅
|
能力值:
( LV13,RANK:460 )
|
-
-
10 楼
假设变量s1,s2在main函数栈中分配,各为指向16字节长度字符串的起始字符地址的指针,main函数使用ebp寻址栈变量,两个字符串中的每个字符都占1字节,则有如下汇编代码(Intel & NASM风格)
******************
main函数序言部分
******************
push ebp
mov esp, ebp
sub esp, 24 ;由于下面要分配2个字符串,共32字节(等于16进制的20h字节)的空间,因
;此这里将esp,即栈顶,向内存低址方向,扩展24h字节,
;多余的4字节为索引
*****************
main函数主体
******************
mov ecx, [ebp-24] ;[ebp-24]处的4字节存储单元,作为索引寻址每个字符串中的字符,现
;在ecx作为索引
mov eax, [ebp-20] ;取得变量s1
mov ecx, 0 ;第一个字符索引为0
mov [eax+ecx*1], 0x61 ;将s1指向的字符串的第一个字符設为 'a',索引乘以字符大小1,即为偏移量,偏移量加上作为起始地址的eax,即能找到目标字符
mov edx, [ebp-10] ;取得变量s2
add ecx, 1 ;第二个字符索引为1
mov [edx+ecx*1], 0x62 ;将s2指向的字符串的第二个字符設为 'b'
mov eax, [ebp-10]
push eax ;s2,作为第2个参数先压栈
mov edx, [ebp-20]
push edx ;s1作为第1个参数后压栈
call 004A5274
add 8 ;由主调函数清除压栈参数
************
main函数尾声
************
xor eax, eax
add esp, 24 ;清除3个main的局部变量
leave
retn
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
太热心了,非常感谢! 估计我得消化一阵子!
我是在delphi里面调用这个call
等我移植到delphi试试
十分谢谢
|
能力值:
( LV13,RANK:460 )
|
-
-
12 楼
其实我这个例子是用2个16字节的局部"字符数组"来代替字符串,模拟的汇编代码,可能与真实的编译器生成的代码有所差异
你应该用高级语言编写操作字符串的例程,然后用delphi编译器编译成汇编文件,查看汇编文件中的内容,
这样就可以理解处理器是如何读写字符串的,后者说白了就是连续的相同大小的内存区域(每个ASCII字符占1字节,每个unicode字符占2字节),这块区域又叫缓冲区,通常,为了安全起见,假设程序员在编程时指定16字节空间,编译器实际分配的空间要大一些,通常是可以被4字节整除的缓冲区大小,如果读写这块缓冲区的函数没有检查用户输入的数据长度是否存在"数组越界",那么就给缓冲区溢出攻击创造了条件,例如strcpy()
如果delphi编译器不支持生成中间的汇编文件,那么用IDA PRO 加载并反汇编最终的可执行文件,查看汇编代码即可.
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
谢谢,谢谢,谢谢
测试完美通过!
自己总结一下:
lea edx, dword ptr [ebp-C0]
把一个变量的地址给edx
那么可以自己先定义一个变量
之后取这个变量的地址
在给edx
至于这个变量里面是什么内容,可以跟踪到,直接赋值即可
例如:delphi 里面 简单的写下,方便后面的人
var
s:STRING;
ADD:^INTEGER;
BEGIN
S:='1';
ADD:=@S
END
多谢指点,以后在遇到类似的,就可以应付了
非常感谢!
|
能力值:
( LV13,RANK:460 )
|
-
-
14 楼
[QUOTE=sunyesy;1353987]谢谢,谢谢,谢谢
测试完美通过!
自己总结一下:
lea edx, dword ptr [ebp-C0]
把一个变量的地址给edx
那么可以自己先定义一个变量
之后取这个变量的地址
在给edx
至于这个变量里面是什么内容,可以跟踪到,直接赋值即可
例如:delphi 里面 简单的写下,方便...[/QUOTE]
您太客气了,交流本来就是一个相互提高自身技术水平的过程.
像我就不懂delphi汇编语法,以后 遇到还得向你请教
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
我喜欢这里的氛围,尤其是你的指导方式,循循善诱,
在你的一点一点的提示下,终于弄通了,感觉非常棒!
而且每次回答的都能到点上
我按照您的提示,一点一点摸索,终于搞懂了~
新年快乐~
|
能力值:
( LV13,RANK:460 )
|
-
-
16 楼
happy new year
|
|
|