以前一直用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,哈哈,注册码就出来了! 掌握知识的感觉真棒,尤其是底层的知识!谁说电脑是冷冰冰的? “知其然,亦须知其所以然。” 嗯,古人果然诚不我欺也。
http://blog.csdn.net/Toyix/archive/2008/07/07/2621757.aspx
- [mess] 正确,博主继续加油啊~ 09/25 14:29
- [mess] 正确~ 09/25 14:28
- [游客] 不关心这些个东西,走了。 02/05 15:35
- [游客] 朴实的情感,才能真正体现出生命的真谛。 02/05 14:49
- [stategrid] 确实挺不容易的。中国人就是病不起,一场大病就可以毁了一个家庭 02/05 10:38
- [younggay] com 01/19 16:26
- [mouselove] Donald Knuth说:“语言持续演进,那是必要的。不论现在流行什么语言,你都可以肯定十年二十年 01/19 13:57
- [tomato] It's right! 01/08 10:39
- [ppt] 呵呵 01/06 17:22
- [ppt] 这是检测题详解吗? 01/06 17:22
- [fairyhuang] 博主这边很多时事呀@@ 11/17 13:48
- [mwh1987] 谢谢你的回答!呵呵 11/16 15:56
- [jinge] 做个朋友吧! QQ:419645753 05/06 18:08