用汇编语言给XP记事本添加“自动保存”功能 good
【文章标题】: 用汇编语言给XP记事本添加“自动保存”功能
【文章作者】: newjueqi
【作者邮箱】:zengjiansheng1@126.com
【作者QQ】:190678908
【使用工具】: OD, LordPE,eXeScope
【操作平台】: XP-SP2
【作者声明】: 本人平时一般的文字处理都是用记事本(用Word好像大材小用了),电脑自从拿去大修后有时候会莫名其妙的重启,弄得经常重写(本人常常忘记保存^-^),于是想给记事本增加类似于Word的自动保存功能,以图个方便。失误之处敬请诸位大侠赐教!
具体的思路:其实自动保存功能就是程序隔一段时间保存一次,而记事本程序是自带了保存功能的,所以只要编程安装一个记时器,每隔一段时间模拟点击“保存菜单”,就能实现自动保存,最后退出时把记时器撤销。
首先,用eXeScope给记事本增加两个菜单项“自动保存”“关闭自动保存”,如图1所示:
图1
其中,“自动保存”的菜单ID是8 ,“关闭自动保存” 的菜单ID是13。
完成后的菜单选项如图2所示:
图2
本次修改要用到3个window API函数: SetTimer, KillTimer , SendMessageA, 这3个API没包括在记事本的输入表里,所以要用LordPE在输入表里增加这3个API。
用LordPE打开记事本程序,依次选择Direction->输入表的“…”按钮->点击右键->add import,出现如图3的界面,就可以在输入表里增加新的API
图3
完成后就新增了一个区段Slivana如图4,放的就是新的IID数据,如图4所示
图4
添加完新的API后又有一个新的问题了,那就是要确定新的API地址,这个在PEDIY的过程中是要自己解决的,而平时是编译器帮忙的。获得API地址有两个方法:
(1) 直接查看新增的IID数据,载入程序后在命令行打入d 1013000,如图5所示:
图5
从IAT与INT的对应关系可得
SetTimer的地址=[0101302C ]
MessageBoxA的地址=[ 01013030]
KillTimer的地址=[01013034 ]
(2) 在OD中,按Ctrl+N组合键,就能看到API地址的位置,如图6的红框部分所示
图6
由于PEDIY一般都是在默认的窗口过程前先处理我们定义的消息,所以接下来分析一下记事本程序的流程,看看记事本的窗口过程地址。众所周知,在一个标准的窗口程序中,必须要注册窗口类,函数原型如下:
ATON RegisterClassEx(CONST WNDCLASSEX *Ipwcx);
其中WNDCLASSEX *Ipwcx是个结构体指针,定义如下:
WNDCLASSEX STRUCT DWORD
cbSize DWORD ?
style DWORD ?
lpfnWndProc DWORD ?
cbClsExtra DWORD ?
cbWndExtra DWORD ?
hInstance DWORD ?
hIcon DWORD ?
hCursor DWORD ?
hbrBackground DWORD ?
lpszMenuName DWORD ?
lpszClassName DWORD ?
hIconSm DWORD ?
WNDCLASSEX ENDS
lpfnWndProc就是窗口过程的地址,所以我们只需要在RegisterClassEx下中断,就能知道窗口过程的地址,在OD中如图7所示:
图7
从图7可看到1003429就是系统默认的窗口过程的地址。
在开始写代码前我们先简单回顾一下的windows的窗口过程函数和一般函数调用的过程,因为我们在后面的实际编码过程中必须要对这两个方面的知识有一定的了解。
窗口过程的原型为
wondowPrco proc hwnd,uMsg, wParam, lParam
hwnd: 窗口的句柄,可通告CreateWindowEx函数的返回值获取
uMsg: 消息的标识,一般以WM开头
wParam, lParam: 消息的两个参数
当我们点击某个菜单后就产生了WM_COMMAND消息,对于菜单引发的的WM_COMMAND消息, lParam 的值为0,wParam的低16位是命令ID,高16位是通知码,菜单消息的通知码是0。
当调用一个_stdcall函数的时候,首先是函数的参数按从右到左的顺序入栈,然后是函数的返回地址入栈,一般函数调用的开始有“push ebp mov ebp,esp”这句,所以我们进入窗口过程后就能得到类似于图8的堆栈结构
图8
0006FDE0 /0006FE0C ; ebp的值
0006FDE4 |77D18734 ; 返回到 user32.77D18734,返回地址值
0006FDE8 |00100618 ;窗口的句柄
0006FDEC |00000111 ;WM_COMMAND的16进制值,可查阅WinUser.h文件获得
0006FDF0 |00000008 ;wParam,“自动保存”的菜单ID是8
0006FDF4 |00000000 ;lParam,
由此可知,[ebp+c]是消息的类型,[ebp+10]是wParam参数,获取菜单的
ID就需要知道wParam参数。
另外还有一个问题要解决,SetTimer和KillTimer这两个API函数的参数中必须要传入窗口句柄作为参数,但窗口句柄怎么找呢?我们知道,在用CreateWindowExW函数创建窗口后会返回一个窗口句柄,在OD里对CreateWindowExW下断点,中断后代码如图9:
图9
从红框部分可知,窗口句柄保存在地址[1009830]。
我们要模拟点击“保存”菜单,可以通过SendMessageW函数向窗口过程发送菜单消息,SendMessageW的原型如下:
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
参数:
hWnd就是窗口句柄,从上面分析可知,保存在[1009830]地址上。
Msg是要发送的消息类型,查阅WinUser.h文件可知,WM_COMMAND为0x111
wParam的低16位是命令ID,高16位是通知码,菜单消息的通知码是0,通过eXeScope可查知“保存”的菜单ID 为3,所以wParam参数为3。
lParam,对于菜单消息来说,为0。
接下来就是实际的代码,本人选择在0100874F处添加代码,所以要把图7红框部分的1003429改为0100874F。
下面是写入的代码
0100874F . 55 push ebp
01008750 . 8BEC mov ebp, esp
01008752 . 60 pushad
01008753 . 817D 0C 11010>cmp dword ptr [ebp+C], 111 ;先比较消息的类型,看是否WM_COMMAND, 如果是WM_COMMAND的话再检查wParam参数进一步确定是哪个菜单的消息
0100875A . 75 0C jnz short 01008768 ;如果不是WM_COMMAND消息的话就检查是否WM_TIMER或WM_CLOSE消息
0100875C . 837D 10 08 cmp dword ptr [ebp+10], 8 ;比较菜单的ID号,看是否“自动保存”的菜单ID
01008760 . 74 1C je short 0100877E ;不是的话就跳去检查其它的消息类型
01008762 . 837D 10 0D cmp dword ptr [ebp+10], 0D ;比较菜单的ID号,看是否“关闭自动保存”的菜单ID
01008766 . 74 48 je short 010087B0 ;不是的话就跳去检查其它的消息类型
01008768 > 817D 0C 13010>cmp dword ptr [ebp+C], 113 ;比较消息的类型是否是WM_TIMER消息,响应定时器消息
0100876F . 74 5F je short 010087D0 ;不是的话就跳去函数的结束清场工作
01008771 . 837D 0C 10 cmp dword ptr [ebp+C], 10 ;比较消息的类型是否是WM_CLOSE消息,闭关时要先撤销定时器
01008775 . 74 39 je short 010087B0 ;不是的话就跳去函数的结束清场工作
01008777 > 61 popad
01008778 . 5D pop ebp
01008779 .^ E9 ABACFFFF jmp 01003429 ;跳回原来记事本的消息循环
0100877E > C605 20890001>mov byte ptr [1008920], 1 ;标记已使用自动保存功能
01008785 . 6A 00 push 0 ; /Timerproc = NULL
01008787 . 68 60EA0000 push 0EA60 ; |Timeout = 60000. ms
0100878C . 6A 01 push 1 ; |TimerID = 1
0100878E . FF35 30980001 push dword ptr [1009830] ; |hWnd = [1009830],在CreateWindowExW后保存窗口句柄的地址
01008794 . FF15 2C300101 call dword ptr [<&user32.SetTimer>] ; /SetTimer
0100879A . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
0100879C . 68 00DB0001 push 0100DB00 ; |Title = "Note"
010087A1 . 68 10DB0001 push 0100DB10 ; |Text = "AutoSave Start!"
010087A6 . 6A 00 push 0 ; |hOwner = NULL
010087A8 . FF15 30300101 call dword ptr [<&user32.MessageBoxA>>; /MessageBoxA ;提示已使用自动保存功能
010087AE .^ EB C7 jmp short 01008777 ;跳去函数结束清场
010087B0 > 803D 20890001>cmp byte ptr [1008920], 0 ;先比较是否已启动定时器
010087B7 .^ 74 BE je short 01008777 ;如果没启动定时器就跳去函数结束清场
010087B9 . C605 20890001>mov byte ptr [1008920], 0 ;把启动定时器的标记恢复
010087C0 . 6A 01 push 1 ; /TimerID = 1
010087C2 . FF35 30980001 push dword ptr [1009830] ; |hWnd,在CreateWindowExW后保存窗口句柄的地址
010087C8 . FF15 34300101 call dword ptr [<&user32.KillTimer>] ; /KillTimer,撤销定时器
010087CE .^ EB A7 jmp short 01008777 ;跳去函数结束清场
010087D0 > 6A 00 push 0 ; /lParam = 0
010087D2 . 6A 03 push 3 ; |wParam = 3 ,“保存”菜单的ID号
010087D4 . 68 11010000 push 111 ; |Message = WM_COMMAND
010087D9 . FF35 30980001 push dword ptr [1009830] ; |hWnd ,在CreateWindowExW后保存窗口句柄的地址
010087DF . FF15 40120001 call dword ptr [<&USER32.SendMessageW>; /SendMessageW ;发送点击菜单“保存”的信号给记事本窗口,实现保存功能。
010087E5 .^ EB 90 jmp short 01008777 ;跳去函数结束清场
下载修改好的记事本地址
http://download.csdn.NET/source/1109397
http://blog.csdn.net/newjueqi/article/details/3992084
用汇编语言给XP记事本添加“自动保存”功能 good的更多相关文章
- WebStorm 编辑器 关闭自动保存功能及添加*星星标记
WebStorm 关闭自动保存功能添加*星星标记为什么要关闭自动保存? 在前端项目工作当中,往往会采用自动化环境(Gulp.webpack等)当文本发生变化的时候就会自动编译代码.在we ...
- PyCharm 去掉自动保存功能
PyCharm 4.5.4 环境配置 1.去掉"自动保存功能" pycharm默认是自动保存的,习惯自己按 ctrl + s 的可以进行如下设置: 菜单File -> Set ...
- 第四十一篇-android studio 关闭自动保存功能
此方法不可用. 第一步:取消自动保存功能 File > Settings > Appearance & Behavior > System Settings > Syn ...
- Intellij IDEA 开启自动保存功能
IntelljJ IDEA关于文件自动保存功能主要有两种方式: 切换到其他应用时保存变化(默认使能) 设置路径:Settings >> Apperance & Behavior & ...
- 【工具】Sublime Text 自动保存功能
经常需要所以要频繁用到"ctrl+s"保存还是挺麻烦的,所以有的人需要用到失去焦点自动保存功能,这里简单记录下 1.点击"Preferences"里的设置-用户 ...
- 关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能;可能和其他插件有冲突)
关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能:可能和其他插件有冲突)
- 在Word中为标题样式添加自动编号功能
原文地址:http://blog.chinaunix.net/uid-16685753-id-2738270.html 摘要: 本文可以帮助你在Office 2007中为Word标题样式添加和设置自动 ...
- C#实体图片下载与批量下载(自动保存功能)
新工作,第一个小任务,制作一个点击下载图片的功能.并提供批量下载操作.图片是字节流的形式,存放在数据库中的. 为了避免直接从数据库中,下载失败,会在本地保存一份. 进行压缩的是SharpZip这个压缩 ...
- DynamicsCRM中的自动保存
DynamicsCRM的自动保存功能 在DynamicsCRM2013开始,引入了自动保存功能. 保存一条记录 在新建一条记录的时候, 你必须在左上角手动点击保存按钮.如下图: 当保存完后,会发现,左 ...
随机推荐
- Crystal Report - 水晶报表导出文件的格式设置
水晶报表中自带的导出和打印功能用起来确实很方便,只不过有时候需要导出的文件并不需要那么多种类型,在网上找到一些朋友的代码总结了一下,可以通过代码实现自定义导出文件类型 首先需要定义一个枚举: publ ...
- 【43.26%】【codeforces 732C】Sanatorium
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- Mac 开发PhoneGap 应用,怎样加入插件 barcodescaner
搞了两天,最终悟出来了 PhoneGap 与 Cordova 的关系了,有人说是WebKit 与 Chrome 的关系,但我个人理解,两个东西再干一件事情,另外 PhoneGap 被Apache 收购 ...
- 华为如何实现基于Git的跨地域协同开发
跨地域开发的需求其实由来已久,在IT/互联网发展的早期就已存在,只不过限于当时网络环境的因素,无法在线上有效的完成协同工作,所以没法实际开展.而随着近十年网络的快速发展,跨地域协同开发线变得可能而且越 ...
- Arcgis api for javascript学习笔记(4.5版本) - 点击多边形(Polygon)并高亮显示
在现在的 arcgis_js_v45_api 版本中并没有直接提供点击Polygon对象高亮显示.需要实现如下几个步骤: 1.点击地图时,获取Polygon的Graphic对象: 2.对获取到的Gra ...
- 权限控制方案之——基于URL拦截
概述: 在系统开发过程中需要考虑的一个重要的问题就是权限问题,权限问题也是安全问题的一个范畴,我们要求在用户登录系统之后,要控制用户可以访问的系统资源,使得用户只可以访问到系统事先分配好的资源:这里的 ...
- 使用Adorner显示WPF控件的边界点
原文:使用Adorner显示WPF控件的边界点 当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在WPF控件所围成的矩形区域的四个边界点上作一个特殊的记号(比如圆点).如下图: 在Wi ...
- 对std::string和std::wstring区别的解释,807个赞同,有例子
807down vote string? wstring? std::string is a basic_string templated on a char, and std::wstring on ...
- Webx框架:Pipeline基本介绍
Pipeline. 它是管道的含义.一个管道阀门可以安装非常多.有许多可能的分支.它是用来控制页处理.它需要在被定义pipeline.xml文件.该文件是为每个阀的标签.该文件可以放一些简单的控制语句 ...
- python_matplotlib cannot import name _thread on mac
最后的2行错误信息是 from six.moves import _thread ImportError: cannot import name _thread 1 2 发现是six出现了问题,用pi ...