由爱到痛
有道云笔记是个好东西,在认识它之前,我一直使用Windows记事本来保存 上摘抄的文档资料和学习心得体会。某天朋友推荐了有道云笔记,我安装后就不可收拾的爱上了它。那种感觉,就好比一夜之间手扶拖拉机换成了奥迪Q7,从此驶上了码字界的康庄大道。
可就在我对它的爱如火如荼的进行中时,一件痛心疾首的事情发生了。
没过两天,于2016年9月26日,有道云笔记客服就给我发来了邮件,说这是一个已知的问题,将在后续版本中进行修复。我心里顿时有了一丝愉悦,觉得 易的这波办事效率,还是可以的。于是我便在等待的过程中,继续用麻烦的办法,将复制来的文字一句一句改成宋体。
但接下来结果,让我从期待变成了失望,最终演变成了愤怒。
2016年10月24日,时隔近一个月,总算等来了有道云笔记的更新,而且这次是大更新,版本 直接从4.12变成了5.0。我满心欢喜的下载更新了新版本,然而测试结果却给了我当头一棒,这个微软雅黑的BUG依然存在。
我不灰心,我是一只打不死的小强,我继续反馈,不过与上次反馈不同,这次反馈后并没有收到邮件回复,我不放心,除了在 页上反馈,我还给其之前回复我的邮箱发送了一封邮件。
2016年12月13日,在苦苦的等待与煎熬中,终于又迎来了有道云笔记的一次更新,版本 从5.0变成了5.5。依然是满怀期待的下载更新,然而又吃了当头一棒,微软雅黑的BUG依然存在。
在接来下的日子里,我不停在问题反馈页面、邮箱、在线客服三种渠道上反复反馈该BUG,希望能引起重视,因为这真的很影响使用。
结局是悲催的,尽管后来又有一些更新,但这个BUG,直到2017年4月22日的今天,依然没有修复。
不放弃不抛弃
在这期间多次想过和它分手,但是试用了其它同类产品,如为知笔记、印象笔记,都有让人不如意的地方。依然继续用有道云笔记,每次复制粘贴弄的想发火的时候,都对自己说,咬咬牙,再忍一忍,说不定明天会更好呢。而且不知不觉在有道上积累了大量的文章,想搬迁也不容易了。
很久以前我一直觉得,不要试图去改变一个人,要么改变你自己,要么离开。
直到我有了生命中的第一个女朋友,她是一个漂亮、可爱,充满阳光的女孩子,和她在一起每天都对生活充满希望,看着她走在我前面蹦蹦哒哒开心的样子,一切烦恼都烟消云散。
尽管我们的兴趣爱好有很大不同,性格上也有一些差异,尽管我们身上都有彼此讨厌的一些缺点。但我一直记着她说的那句话:
没有天生合适的两个人,需要的是彼此包容理解与改变。
是的,我们既要为彼此做出改变,也要帮助对方塑造一个更好的自己,这样不是很好么。
现在的我不会轻易说离开。
停止抱怨,冷静分析
抱怨是解决不了问题的,既然要做出改变,就要静下心来分析问题根源所在,并寻找解决方案。
思考一下有没有什么变通的方法实现我要的效果,实际上我想要的效果就是,无论哪里来的内容,统统给我粘贴为纯文本,不要乱改我设置好的字体,我设置的是什么字体格式,粘贴后的文本字体格式就保持和当前上下文一致。
既然有道云笔记的粘贴为纯文本功能有BUG,那么直接使用粘贴功能,能不能实现我要的效果呢p>
当然可以,只是要进行一个额外操作,先把 页上复制的内容粘贴到Windows记事本里,然后再复制一遍,再粘贴到有道云笔记里。这样文本在Windows记事本里过了一遍,格式就丢掉了。
好想法,那么只要编写一个小程序,监听剪贴板,一旦发现我从 页上复制了带格式的新内容,就对其进行处理,去掉格式,这样我在有道云笔记中Ctrl+V的时候,就是纯文本了。
这个思路可以是实现我要的效果,但是会影响到其它软件,比如你想带格式粘贴到Word中时怎么办这样一来你这台电脑上,再也无法复制粘贴带格式的文本了,严重影响其它软件的使用。剪贴板不是你一个人的,电脑上其它软件也要用,不能乱改剪贴板的内容。
是的,不能影响全局,剪贴板是大家的。那么我有没有办法只让有道云笔记这个软件读剪贴板的时候,永远读到的都是不带格式的纯文本的内容,这样Ctrl+V就是纯文本了。而其它如Word的软件是正常的,剪贴板里是什么就读到什么。
当然可以,使用API HOOK就可以实现,Hook住有道云笔记读剪贴板的API,改掉内容就行了。
这么搞好像游戏外挂一样,注入DLL、API HOOK、改内存之类的操作,让我想到了变速齿轮,它就是Hook了获取时间相关的API,给目标程序提供了错误的时间,让目标程序以为世界都变快了。
是的,善意的谎言让它的世界更美好。
思路已定,那简单了,直接祭出大杀器API Monitor,简单粗暴,快速有效。直接分析有道云笔记在粘贴为纯文本时调用了哪些WindowsAPI,设置过滤器只关注和剪贴板相关的API,分析如下:
当粘贴带格式的文本到有道云笔记时:
一经对比,很快就能找出不同之处。有道云笔记注册了名为”HTML Format“的剪贴板格式,实际上这是一种使用HTML表示富文本的通用格式,从浏览器中拷贝出来的文本正是这种格式。
对比两次粘贴,当粘贴带格式的文本时,有道云笔记询问操作系统关于剪贴板的内容:
RegisterClipbardFormatW(“HTML Format”)
我要注册”HTML Format”这种格式
49381
注册好了,ID是49381,拿去吧
IsClipboardFormatAvailable(49381)
现在剪贴板里面的东西是“HTML Format”这种格式吗p>
TRUE
是的
GetClipboardData(49381)
我要获取剪贴板里“HTML Format”这种格式的内容
0x0d42bd18
好的,获取了,存在这个地址处了
当粘贴不带格式的纯文本时,有道云笔记是这样和操作系统对话的:
RegisterClipbardFormatW(“HTML Format”)
我要注册”HTML Format”这种格式
49381
注册好了,ID是49381,拿去吧
IsClipboardFormatAvailable(49381)
现在剪贴板里面的东西是“HTML Format”这种格式吗p>
FALSE
不是
IsClipboardFormatAvailable(CF_TEXT)
那好吧,那现在剪贴板里面的东西是CF_TEXT(纯文本)这种格式吗p>
TRUE
是的
GetClipboardData(CF_UNICODETEXT)
那好吧,我要获取剪贴板里的纯文本内容,以CF_UNICODETEXT(Unicode文本)形式给我
0x0d3d01d8
好的,获取了,存在这个地址处了
区别在于:
当剪贴板中是带格式的文本时,IsClipboardFormatAvailable(49381)返回了TRUE
当剪贴板中是不带格式的纯文本时,IsClipboardFormatAvailable(49381)返回了FALSE
那好办!我们只需要写一个DLL,注入到有道云笔记进程中,Hook IsClipboardFormatAvailable这个API,当有道云笔记询问是不是“HTML Format”这种格式时,我们就用于告诉它,不是!!这样一来,它永远都只会去获取纯文本,从而,我们Ctrl+V粘贴到有道云笔记中的文本,永远都是纯文本!
是的,但最好让用户可以控制,设置一个开关,当开启时,会改变有道云笔记,让它读剪贴板读到的永远是纯文本,当关闭开关时,一切恢复正常,带格式的就是带格式,粘贴后依然带格式。让用户自主选择更棒,因为像我这样的用户,基本上永远都只会粘贴为纯文本, 页上拷贝过来的格式,几乎都要去掉的,否则怎么融入到我文章上下文中,但是Ctrl+Shift+V用起来很不顺手(何况目前还有微软雅黑的BUG),只用Ctrl+V多方便。
是的,我们可以在注入的DLL的DllMain中启动一个线程,使用RegisterHotKey注册一个热键,比如Ctrl+Q,然后启动消息循环来接收WM_HOTKEY消息,启用或关闭API Hook来实现上述的开关。
行动
明确本次行动的目标:
- 修复纯文本粘贴就变成微软雅黑字体的BUG
- 增加功能,加一个开关,开启后粘贴的内容永远是纯文本,不管是从哪里复制来的
思路有了,解决问题的办法也想出来了,只差行动了,我们不能做思想上的巨人,行动上矮子,既然是男人,说干就干!准备好趁手的工具,直接开车!
DLL注入方式使用远程线程注入,这种方式比较经典、简单。
API HOOK技术使用IAT HOOK,这种Hook方式多线程下稳定可靠。API HOOK库我选择的是《Windows核心编程》的随书示例代码中的CAPIHook。也可以使用强大的WinAPIOverride或微软的Detours等。当然手写Inline Hook也是可以的,代码超简短,由于有道云笔记访问剪贴板时不存在多线程并发访问情况,Inline Hook也是没有问题的。
新建一个Win32动态库项目取名YNotePatch,关键代码如下:
新建一个Win32应用程序项目取名YNoteStarter,写一个EXE作为启动器,用于启动有道云笔记主程序后注入DLL:
访问 Github https://github.com/charlessimonyi/YNotePatch 查看src和bin
总结
是的,在没有程序源码的情况下要给一个已经编译好的Native程序修复BUG,增加、修改功能往往就是这么做的。把我们的代码编译成DLL注入进去执行,这种方式称为打内存补丁。也可以在目标进程中分配内存,直接用WriteProcessMemory把机器码写进去让它执行,也可以把整个DLL复制到这块内存中,不过需要处理导入表和重定位,比较麻烦。当然也可以打文件补丁,直接修改它的PE文件,不过只改几行指令还好,如果要大量注入代码,也是比较麻烦的,而且万一目标EXE有加壳有压缩或者有完整性校验,就走不通了。注入DLL其实是最简单的,注入后我们就可以在它的进程空间内为所欲为,动它的窗口,拦截和修改它的窗口消息,改内存,改变量的值,改目标代码的跳转流程,替换目标代码,配合VirtualProtect,没有什么是不能动的。当然最大难点还是在于该改什么,什么能改什么不能改,改什么才能实现想要的效果,需要花时间慢慢分析。
新生活
至此,总算可以舒服的使用有道云笔记了,使用YNoteStarter启动有道云笔记,任何文本内容,不管从哪里复制来的,Ctrl+V后都是纯文本,实在是爽哉。使用过程中按Ctrl+Q关闭补丁,恢复本色,带格式的文本粘贴后就是带格式的。
好景不长
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!