32位汇编学习的一点心得
2011-10-25 09:56
197 查看
以前一直用C/C++写程序;最近突然抽起了一条筋,祭出Win32ASM,想试试在汇编代码级别写32位程序的滋味,也因此明白了不少以前一直没彻底弄懂的东西。
先说说堆栈的使用。以前一直以为堆栈就是push、pop两个很基本的操作,只是用来暂时储存数据用的,现在发现这种观念已经过时了,因为到了32位编程的时代,堆栈的主要用途已经变为API函数调用时的参数放置处,例如:
push MB_OK
push offset Caption
push offset Text
push NULL
call MessageBoxA
有经验的C/C++程序员一眼就能看出,这是API函数MessageBox的调用方式,前面的那几个push就是用来把MessageBox的参数压入堆栈内,然后一个call就调用了MessageBox,上面的语句相当于C语言写的调用:
MessageBox(NULL, Text, Caption, MB_OK);
这是符合win32标准standard调用约定的,即函数入口参数按从右到左的顺序入栈,并由被调用者清理栈中参数,返回值放在eax寄存器中。
win32的一千多个API函数都是符合这种standard调用约定的,但只有一个函数例外,那就是wsprintf,这个函数是C约定的,因此在win32汇编中,你得这样写:
push ebp ;ebp入栈
mov ebp, esp ;因为esp是堆栈指针,无法暂借使用,所以得用ebp来存取堆栈
sub esp, 4*5 ;下面的wsprintf一共使用了5个参数,每个参数占用4个字节,所以要入栈4*5个字节
push 1111
push 2222
push 3333
push offset szFormat
push offset szOut
call wsprintf ;调用wsprintf
add esp, 4*5 ;堆栈使用完毕,“还”回4*5个字节给系统
...
mov esp, ebp ;恢复esp的值
pop ebp ;ebp出栈
ret
很好,看到这里,相信你已经明白了堆栈的使用方法。我忽然又想起了平时用SoftICE来crack一些软件的时候经常看到的东西:
push 00001111
push 00002222
call lstrcmp
test eax, eax
jne 00003333
......
以前我一直弄不明白前面那两个push是用来干吗的,于是只好跳过不看;现在我知道了它们是作为lstrcmp函数的两个参数后,直接打入d 00001111,哈哈,注册码就出来了!
掌握知识的感觉真棒,尤其是底层的知识!谁说电脑是冷冰冰的?
先说说堆栈的使用。以前一直以为堆栈就是push、pop两个很基本的操作,只是用来暂时储存数据用的,现在发现这种观念已经过时了,因为到了32位编程的时代,堆栈的主要用途已经变为API函数调用时的参数放置处,例如:
push MB_OK
push offset Caption
push offset Text
push NULL
call MessageBoxA
有经验的C/C++程序员一眼就能看出,这是API函数MessageBox的调用方式,前面的那几个push就是用来把MessageBox的参数压入堆栈内,然后一个call就调用了MessageBox,上面的语句相当于C语言写的调用:
MessageBox(NULL, Text, Caption, MB_OK);
这是符合win32标准standard调用约定的,即函数入口参数按从右到左的顺序入栈,并由被调用者清理栈中参数,返回值放在eax寄存器中。
win32的一千多个API函数都是符合这种standard调用约定的,但只有一个函数例外,那就是wsprintf,这个函数是C约定的,因此在win32汇编中,你得这样写:
push ebp ;ebp入栈
mov ebp, esp ;因为esp是堆栈指针,无法暂借使用,所以得用ebp来存取堆栈
sub esp, 4*5 ;下面的wsprintf一共使用了5个参数,每个参数占用4个字节,所以要入栈4*5个字节
push 1111
push 2222
push 3333
push offset szFormat
push offset szOut
call wsprintf ;调用wsprintf
add esp, 4*5 ;堆栈使用完毕,“还”回4*5个字节给系统
...
mov esp, ebp ;恢复esp的值
pop ebp ;ebp出栈
ret
很好,看到这里,相信你已经明白了堆栈的使用方法。我忽然又想起了平时用SoftICE来crack一些软件的时候经常看到的东西:
push 00001111
push 00002222
call lstrcmp
test eax, eax
jne 00003333
......
以前我一直弄不明白前面那两个push是用来干吗的,于是只好跳过不看;现在我知道了它们是作为lstrcmp函数的两个参数后,直接打入d 00001111,哈哈,注册码就出来了!
掌握知识的感觉真棒,尤其是底层的知识!谁说电脑是冷冰冰的?
相关文章推荐
- 32位汇编学习的一点心得
- 学习汇编语言的一点心得 推荐
- 学习maclean视频的一点心得
- 关于条件编译和预编译的一点学习心得
- 32位汇编语言学习笔记(37)--显示命令行参数
- C#开发ArcEngine的一点学习心得 (转)
- 学习一点缀数据结构的心得
- 网易公开课《Linux内核分析》学习心得-使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 如何学习机器学习的一点心得
- Windows系统内核模态和用户模态一点学习心得
- mysql存储引擎的一点学习心得总结
- 32位汇编语言学习笔记(43)-- 生成随机数
- 新手入门:学习Java的一点经验心得
- 学习Vim的一点心得
- 32位汇编语言学习笔记(23)--大小写转换程序2
- 关于NOSQL和MongoDB的一点学习心得
- 学习Android一点心得
- AChartEngine的一点学习心得
- 32位汇编语言学习笔记(31)--rep stosb指令
- 自己学习C语言的一点心得