/section:.text,RWE 这句指定了代码段(.text)的属性是RWE,含义是:R(ReadAble),W(WriteAble),E(ExecuteAble)!
;*********************************************** ;程序名称:演示SMC原理 ;作者:罗聪 ;日期:2002-10-2 ;出处:http://laoluoc.yeah.net(老罗的缤纷天地) ;注意事项:如欲转载,请保持本程序的完整,并注明: ;转载自“老罗的缤纷天地”(http://laoluoc.yeah.net) ;*********************************************** .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib ShowMessage proto ReplaceMent proto .data szMsg1 db "这是未执行SMC之前的代码!", 0 szMsg2 db "SMC已经执行!", 0 szCaption db "SMC demo by LC, 2002", 0 Replace_Len dd 0 .code main: ;第一次执行子程序ShowMessage,此时还没执行SMC操作 invoke ShowMessage lea eax, ReplaceMentEnd ;标号ReplaceMent的结束 lea edx, ReplaceMentStart ;标号ReplaceMent的开始 sub eax, edx ;标号ReplaceMent的长度 mov Replace_Len, eax ;把长度储存起来 ;关键代码!!!!!!!!! lea esi, ReplaceMentStart ;标号ReplaceMent的开始 lea edi, ShowMessageStart ;原程序ShowMessage的标号的开始 mov ecx, Replace_Len ;标号ReplaceMent的长度 rep movsb ;这里是最关键的语句!!!执行SMC操作! ;第二次执行子程序ShowMessage,此时已经执行了SMC操作。 ;换句话说,ShowMessage的内容已经不是第一次运行时的内容了: invoke ShowMessage invoke ExitProcess, 0 ShowMessage proc ;这里用“::”的话,就能够使标号成为全局性的 ShowMessageStart:: invoke MessageBox, NULL, addr szMsg1, addr szCaption, MB_OK ShowMessageEnd:: ;用nop来预留空间,以便后面的SMC能够成功执行; ;否则如果空间不够,将有可能产生不可预测的错误: nop nop nop nop nop nop nop nop ret ShowMessage endp ReplaceMent proc ;将要用来SMC的代码: ReplaceMentStart:: ;invoke MessageBox, NULL, addr szMsg2, addr szCaption, MB_OK or MB_ICONINFORMATION push MB_OK or MB_ICONINFORMATION lea eax, szCaption push eax lea eax, szMsg2 push eax push NULL lea eax, MessageBox call eax ReplaceMentEnd:: ret ReplaceMent endp end main