浅析SMC技术

今天让我们来看Win32ASM里面的高级一点的技术——SMC(当当当当……)!!!

SMC是什么意思?它的英文名叫“Self Modifying Code”,顾名思义,就是“代码自修改”(?)(不好意思,小弟的英语六级还没过,只能翻译成这样啦……)

“代码自修改”?哇,好高深啊!其实不然……

我们知道,Win32应用程序是运行在保护模式下的,每个Win32应用程序都有相互独立的4GB地址空间,并且已经摒弃了16位时代的把代码分为Data、Code等段的内存模式的做法;现在它们只有一种内存模式,即FLAT模式,意思是“平坦”的内存模式——再也没有烦人的64KB的段大小限制啦。如此一来,所有的Win32应用程序都能各自运行在一个连续、平坦、巨大的4GB空间中,作为程序员,也不用再跟段寄存器打交道,您可以用任意的段寄存器寻址任意的地址空间,是不是很方便呢?

不过且慢,Win32时代的编程虽然比之Win16时代已经方便了不止一个数量级,但是毕竟还有一些规则是需要遵守的。最明显的之一就是不能在程序运行的过程中随便更改代码段!

(咦?刚刚不是说了Win32里面没有段的概念了吗?怎么这里又来了一个“代码段”了?别急,请听我细细道来……)

虽然Win32下已经没有了“段”,但是您还是可以给自己的程序分成不同的“段”,一个“分段”的开始即是上一个“分段”的结束。Win32只有两种性质的分段:Data和Code。

实际上,在Win32里面的分段并不是像DOS下一样,为不同的段分别指出不同的段寄存器,因为Windows下只有一个4GB的段,Windows程序中的分段表现在当程序装载时,赋予不同的段不同的属性,比如说当你的程序加载时,对于Ring3程序来说,.code段是不可写的,而.data段是可写的,如果你尝试像在DOS下一样写自己的代码部分,你将会得到一个“很cool”的蓝屏错误。

怎么样?头晕了吗?如果没有的话,让我们继续!^_^

上面已经提到代码段是不能在程序运行途中更改的了,那么怎么又来了一个“SMC”技术呢?它是如何实现的?

其实关键就在于链接时的参数,只要指定了代码段的属性是可写的,那么就OK啦!(默认的参数是不可写的)。也就是说,我们在编译、链接带有SMC的Win32ASM时应该这样做:

ml /c /coff %1.asm
link /subsystem:windows /section:.text,RWE %1.obj


怎么样?明白了吗? /section:.text,RWE 这句指定了代码段(.text)的属性是RWE,含义是:R(ReadAble),W(WriteAble),E(ExecuteAble),也就是“可读可写可执行”。这样我们的程序就可以在运行途中自己改写自己的代码段啦,怎么样?是不是很爽呢?

下面给出了一个完整的带有SMC技术的Win32ASM例子,很容易理解的,记得要用上面的方法来编译和链接哦!

;***********************************************
;程序名称:演示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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA基础--程序是顺序执行的

class Testa {public static void main(String[] args) {String aa"aaa";String bb"bbb"aa;aa"cccc";System.out.println(bb);} } 输出的是 “bbbaaa class Testa {public static void main(String[] args) {String aa"aaa";String …

Spring MVC拦截器示例

我以为是时候看看Spring的MVC拦截器机制了,这种机制已经存在了很多年,并且是一个非常有用的工具。 Spring Interceptor会按照提示进行操作:在传入的HTTP请求到达您的Spring MVC控制器类之前对其进行拦截,或者相反,在其…

Android 调用系统的分享[完美实现同一时候分享图片和文字]

android 系统的分享功能 private void share(String content, Uri uri){Intent shareIntent new Intent(Intent.ACTION_SEND); if(uri!null){//uri 是图片的地址shareIntent.putExtra(Intent.EXTRA_STREAM, uri);shareIntent.setType("image/*"); //当用户选择短信时…

团队行为守则—如果你们由我来领导

如果你是在我领导的团队里,有几个额外的事情我要告诉你。我深信这些行为守则是一个高效团队的润滑剂,我并不只是要求别人这样做,我自己也严格恪守。 只有三样事: 问:如果你对任务不清楚&#…

做短,但做对!

编写简洁,优雅,清晰的代码一直是开发人员的艰巨任务。 您的同事不仅会感谢您,而且您会惊讶地发现,不断期待着重构解决方案以更少的代码完成更多(或至少相同)的工作是多么令人兴奋。 曾经有人说好的程序员是…

math

莫比乌斯反演: $F(n) \sum\limits_{d|n} {f(d)} \Leftrightarrow \sum\limits_{d|n} {\mu (d)F(\frac{n}{d})} $ 其中 ${\mu (d)}$为莫比乌斯函数: 若$d$等于0 , 则${\mu (d)}$1 若$d {p_1}{p_2}{p_3}...{p_k}$ , ${p_i}$为互异质数,则${\mu (d)}$${( …

(笔试题)二进制1的个数相同的距离最小数

题目: 输入:整数A输出:整数B条件:A和B的二进制1的个数相同,且A和B之间的距离|A-B|最小。思路: 题目没有说明整数类型,这里认为是带符号的整数,即区分正负数。 根据题意,A…

Java Swing –日期选择器对话框

房子里有Swing开发人员吗? 对于使用Swing的用户来说,这是一个GUI组件,可能会对您的UI编码工作有所帮助。 我们的JCG合作伙伴之一提供了日期选择器小部件。 一探究竟: Java Swing –日期选择器对话框以选择日期 翻译自: https://…

Casperjs中fill提交表单遇到的问题

1.if you access internet with proxy please add --ignore-ssl-errorstrue --ssl-protocolany 2.casper.then* and casper.wait* 都是异步执行的 他们的调用,都是按堆栈中的顺序来执行;也就是说,其他同步执行的函数,…

Xuggler视频处理简介

注意:这是我们的“ Xuggler开发教程 ”系列的一部分。 随着互联网上视频的爆炸式增长,开发人员经常需要在其应用程序中操纵视频内容。 Xuggler是Java开发人员的免费开放源代码库,可用于实时解压缩,处理和压缩录制的视频或实时视频…

软件测试中条件覆盖,路径覆盖,语句覆盖,分支覆盖的区别

转:软件测试中条件覆盖,路径覆盖,语句覆盖,分支覆盖的区别 举个例子吧 if A and B then Action1 if C or D then Action2 语句覆盖最弱,只需要让程序中的语句都执行一遍即可 …

Spring_讲解

http://s,i,s,h,u,o,k.com/forum/blogPost/list/6174.html转载于:https://www.cnblogs.com/gisblogs/p/4579162.html

使用Spring AspectJ和Maven进行面向方面的编程

Spring框架附带AOP支持。 实际上,如Spring参考文档中所述 , “ Spring的关键组件之一是AOP框架。 尽管Spring IoC容器不依赖于AOP,这意味着您不需要使用AOP,但AOP是对Spring IoC的补充,以提供功能强大的中间件解决方案…

hadoop5--mapreduce设计模式

运行结果附图 本节课程主要内容为学习MapReduc设计模式,并编写java程序对日志文件进行处理。 课本上介绍的MapReduce的设计模式主要包含:计数(Counting),分类(Classification),过滤处理(Filtering),排序(Sorting),去重计数(Distinct Counting),相关计数(Cross-Corre…

ES5中新增的Array方法详细说明

http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/转载于:https://www.cnblogs.com/lmw425317/p/5339539.html

jqGrid,REST,AJAX和Spring MVC集成

两年多以前,我写了一篇关于两个如何在Struts2中实现优雅的CRUD的文章。 实际上,我必须就该主题写两篇文章,因为该主题如此广泛。 今天,我采用了一套更为流行的,完善的框架和库,采用了更为轻量级的现代方法。…

Java-马士兵设计模式学习笔记-代理模式--动态代理 修改成可以代理任意接口

一、概述 1.目标:把Proxy修改成可以代理任意接口及其任意方法 2.思路: (1)代理任意接口:把接口类型作为参数传给Proxy的newProxyInstance(Class interfze) (2)代理任意方法:用interfze.getMethods()取出所有方法,拼接实…

PTA习题

PTA习题 PTA浙大版《C语言程序设计(第3版)》 题目集5-6 水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。 本题要求编写两个函数,一个判断给定整数是否水仙花数,…

acdream 1409 Musical 状压DP

链接:http://acdream.info/problem?pid1409 题意:整个国家有n座城市,每座城市有三种粉丝。 第一种一周看一场音乐剧,挑选的音乐剧是已经在周围城市播放上演过的次数最多的音乐剧中的随机一个。 另外一种每天看一场音乐剧&#xf…

真正的模块化Web应用程序:为什么没有开发标准?

OSGI , SpringSource , Jboss模块 ,J2EE和清单永远不会结束。所有这些技术都向他们的最终用户/开发人员保证了相同的东西,或多或少是Java模块化Web应用程序(?)。 但是,我们当中有多少…