【文章标题】: 用汇编语言给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的更多相关文章

  1. WebStorm 编辑器 关闭自动保存功能及添加*星星标记

    WebStorm 关闭自动保存功能添加*星星标记为什么要关闭自动保存?      ​ 在前端项目工作当中,往往会采用自动化环境(Gulp.webpack等)当文本发生变化的时候就会自动编译代码.在we ...

  2. PyCharm 去掉自动保存功能

    PyCharm 4.5.4 环境配置 1.去掉"自动保存功能" pycharm默认是自动保存的,习惯自己按 ctrl + s 的可以进行如下设置: 菜单File -> Set ...

  3. 第四十一篇-android studio 关闭自动保存功能

    此方法不可用. 第一步:取消自动保存功能 File > Settings > Appearance & Behavior > System Settings > Syn ...

  4. Intellij IDEA 开启自动保存功能

    IntelljJ IDEA关于文件自动保存功能主要有两种方式: 切换到其他应用时保存变化(默认使能) 设置路径:Settings >> Apperance & Behavior & ...

  5. 【工具】Sublime Text 自动保存功能

    经常需要所以要频繁用到"ctrl+s"保存还是挺麻烦的,所以有的人需要用到失去焦点自动保存功能,这里简单记录下 1.点击"Preferences"里的设置-用户 ...

  6. 关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能;可能和其他插件有冲突)

    关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能:可能和其他插件有冲突)

  7. 在Word中为标题样式添加自动编号功能

    原文地址:http://blog.chinaunix.net/uid-16685753-id-2738270.html 摘要: 本文可以帮助你在Office 2007中为Word标题样式添加和设置自动 ...

  8. C#实体图片下载与批量下载(自动保存功能)

    新工作,第一个小任务,制作一个点击下载图片的功能.并提供批量下载操作.图片是字节流的形式,存放在数据库中的. 为了避免直接从数据库中,下载失败,会在本地保存一份. 进行压缩的是SharpZip这个压缩 ...

  9. DynamicsCRM中的自动保存

    DynamicsCRM的自动保存功能 在DynamicsCRM2013开始,引入了自动保存功能. 保存一条记录 在新建一条记录的时候, 你必须在左上角手动点击保存按钮.如下图: 当保存完后,会发现,左 ...

随机推荐

  1. linux 网卡配置文件详解

    配置文件位置:/etc/sysconfig/network-scripts/ifcfg-eth0 1. DEVICE=eth0 网卡的名字 2. HWADDR=00:0c:29:90:89:d9 HW ...

  2. 【56.74%】【codeforces 732B】Cormen --- The Best Friend Of a Man

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. 利用WPF建立自己的3d gis软件(非axhost方式)(三)矢量数据显示控制

    原文:利用WPF建立自己的3d gis软件(非axhost方式)(三)矢量数据显示控制 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPew 密 ...

  4. 【MySQL案例】error.log的Warning:If a crash happens thisconfiguration does not guarantee that the relay lo

    1.1.1. If a crash happens thisconfiguration does not guarantee that the relay log info will be consi ...

  5. VS2017 Linux 上.NET Core调试

    调试Linux 上.NET Core Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Stud ...

  6. element-ui 的 日历 datetimerange 日期格适化 , 适合1版本

    这家伙把我坑坏了 , 本来吧数据准备好了 , 一掉接口居然不好使 ,日期总是有偏差 , 结果一看是提交的数据有问题 , 后台直接接受的字符串 new 的Date , 2017-12-24T16:00: ...

  7. TabHost两种实现方式

    第一种:继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.只要定义具体Tab内容布局就行了. <?xml version="1.0 ...

  8. Win7 32bit下一个hadoop2.5.1源代码编译平台的搭建各种错误遇到

    从小白在安装hadoop困难和错误时遇到说起,同时,我们也希望能得到上帝的指示. 首先hadoop更新速度非常快,最新的是hadoop2.5.1,因此就介绍下在安装2.5.1时遇到的各种困难. 假设直 ...

  9. uwp - ContentDialog - 自定义仿iphone提示框,提示框美化

    原文:uwp - ContentDialog - 自定义仿iphone提示框,提示框美化 为了实现我想要的效果花费了我很长时间,唉,当初英语不好好学,翻官网翻了半天才找到,分享给刚入门的新手. 首先看 ...

  10. OpenCV实现朴素贝叶斯分类器诊断病情

    贝叶斯定理由英国数学家托马斯.贝叶斯(Thomas Baves)在1763提出,因此得名贝叶斯定理.贝叶斯定理也称贝叶斯推理,是关于随机事件的条件概率的一则定理. 对于两个事件A和B,事件A发生则B也 ...