吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11575|回复: 36
收起左侧

[原创] 心明眼亮之JPEGView近视修复手术

  [复制链接]
无瑕黑心肠 发表于 2019-9-12 19:34
本帖最后由 无瑕黑心肠 于 2019-9-12 19:37 编辑

1、软件简介
      JPEGView是一款小巧快速的全屏图片浏览器和编辑器,支持JPEG,BMP,PNG,GIF和TIFF格式的图像。并支持调整图像锐度、色彩平衡、对比度、局部过渡。


2、回到正题
      JPEGView的确是一款非常不错的看图软件,小巧而且打开速度快,但是某些功能不能自定义是用户很苦恼的事情,如下图:
      


      图片100%显示是正常的,但是你一旦放大就会变成:
      


      图片就变模糊了(Windows自带看图放大是不会模糊处理图像的),这对于普通用户可能没什么太大的影响,但是对于设计或在意细节的朋友来说可不太友好,举个例子,你想查看两张图片的不同处,然而两张图片都是模糊的,你炸不楞一看两张图片都是一样的,但实际上两张图片不一样,此时心里会有一万只那啥四条腿的在奔腾。恰巧,这个放大会模糊处理的设置参数里没有,也就是说你不能决定图片放大后进不进行模糊处理,身为一个吾爱3年多的老用户,怎能轻易放过它,于是我操起了我的手术刀(x64dbg、Cheat Engine)


3、手术开始
      用x64dbg分析了一下JPEGView,发现使用GDI+绘制图片的,那就好说了,直接Hook GDI的模糊处理不就可以了嘛?(真这么做莫非是个疯子),先从功能找找有没有图片放大后图片不模糊的操作,果不其然:
      


      JPEGView的透视校正不会使用模糊处理,而且不管图片怎么缩放都是很清晰的,那么我们如何知道JPEGView用没有用模糊处理呢?以下是我的思路:
      既然透视校正打开后图片不论怎么缩放都不会使用模糊处理,那么我们可以去跟踪一下这个透视校正打开后缩放是如何处理的,然后找到模糊处理的代码,把它修改成我们想要结果。但是如何知道模糊处理的代码是在什么地方呢?一般思路肯定是下个鼠标滚轮的消息断点,然后返回到程序领空,这样肯定就是处理缩放的地方,缩放图片肯定会处理图片的模糊......打住,今天用一种奇葩的方法,用Cheat Engine:
      打开Cheat Engine,把透视校正功能打开,用Cheat Engine搜索1,功能关闭搜索0,最后会有两个结果:
      


      但是其中有一个正确的,验证方法也很简单,只要把其中一个数值改成1,另一个改成0,如果缩放不模糊,那就是正确的数值。
      找到正确的数值后,我们看看是什么读取了这个内存数据:
      


      发现有两处地方读取了这个值,接下记录这两处的地址,用x64dbg跟一下汇编代码,这两处都这是读取透视校正功能是否打开然后返回给上一层:
      


      最主要知道的还是上一层的代码是用这个值来干了些什么,经过我的一番筛选,果然有一处是与模糊处理相关的:
      


      如果直接把功能判断直接 nop 掉其实我们目的就已经达到了,即使透视校正功能是关闭的,图片缩放也是清晰的,不会进行模糊处理:
      


      但是,再次打开看图会发现:
      


      WTF,bro?这黑丝......这线条是什么个情况?经过一番排查,原来是透视校正功能中显示网格自动裁剪校正后的图像保持画面比例裁剪默认是开启的,这相当于我把这些功能全部打开了,但是我就只要它不进行模糊处理就好了,如果要完美实现这个功能,办法只有一个,把它初始化赋值给干掉,也就是把显示网格自动裁剪校正后的图像保持画面比例裁剪三个功能关掉,ok,现在要做的就是找到室哪里给这三个功能打开了,以下是我的思路:
      要知道功能开是1,功能关是0,用Cheat Engine搜索显示网格功能,搜素一番发现只有一处读取了这个内存数据:
     
[Asm] 纯文本查看 复制代码
000000013FF86770 | 4C:894C24 20                 | mov qword ptr ss:[rsp+20],r9                     |
000000013FF86775 | 4C:894424 18                 | mov qword ptr ss:[rsp+18],r8                     |
000000013FF8677A | 48:895424 10                 | mov qword ptr ss:[rsp+10],rdx                    |
000000013FF8677F | 53                           | push rbx                                         |
000000013FF86780 | 56                           | push rsi                                         |
000000013FF86781 | 57                           | push rdi                                         |
000000013FF86782 | 48:81EC 80000000             | sub rsp,80                                       |
000000013FF86789 | 4C:8BC2                      | mov r8,rdx                                       |
000000013FF8678C | 48:8D5424 60                 | lea rdx,qword ptr ss:[rsp+60]                    |
000000013FF86791 | 48:8BF9                      | mov rdi,rcx                                      |
000000013FF86794 | E8 87000000                  | call jpegview-js.13FF86820                       |
000000013FF86799 | 8BB424 C8000000              | mov esi,dword ptr ss:[rsp+C8]                    |
000000013FF867A0 | 0FB65F 30                    | movzx ebx,byte ptr ds:[rdi+30]                   | 显示网格
000000013FF867A4 | 48:8BCF                      | mov rcx,rdi                                      |
000000013FF867A7 | 83E6 FB                      | and esi,FFFFFFFB                                 |

      想要知道初始值是哪里赋值的,则必须要找到显示网格的来源,下面是详细跟踪的汇编代码:
      
[Asm] 纯文本查看 复制代码
00000000025B0FE0 | 48:B9 F0FB280000000000       | mov rcx,28FBF0                                   | rcx 来源是 0x28FBF0

00000000025B0FEA | 48:B8 30BCF43F01000000       | mov rax,jpegview-js.13FF4BC30                    |

00000000025B0FF4 | FFE0                         | jmp rax                                          |

000000013FF4BC67 | 48:8BF9                      | mov rdi,rcx                                      | rdi 来源是 rcx

000000013FF4BC94 | 48:8BCF                      | mov rcx,rdi                                      | rcx 来源是 rdi

000000013FFA89E3 | 4C:8BF1                      | mov r14,rcx                                      | r14 来源是 rcx

000000013FFA8E97 | 49:8B8E 20020000             | mov rcx,qword ptr ds:[r14+220]                   | rcx 来源是 r14

000000013FF86791 | 48:8BF9                      | mov rdi,rcx                                      | rdi 来源是 rcx

000000013FF867A0 | 0FB65F 30                    | movzx ebx,byte ptr ds:[rdi+30]                   | 显示网格

      可以看出最后 rcx 的来源是 0x28FBF0 但是这个句汇编代码的地址明显不是程序领空,那应该是动态分配的,所以还得往上一层下一个断点然后重载程序,果然每次的内存地址都是不一样的:
      
[Asm] 纯文本查看 复制代码
00000000002B0FE0 | 48:B9 10FA140000000000       | mov rcx,14FA10                                   |
00000000002B0FEA | 48:B8 30BC0C3F01000000       | mov rax,jpegview-js.13F0CBC30                    |
00000000002B0FF4 | FFE0                         | jmp rax                                          |

      既然找到了显示网格功能数据的来源(显示网格 = [[[动态分配的RCX基址]+0x220]+0x30]),我们下个写入断点开始追踪就能找到初始赋值的地方了,首先找第一层指针赋值的地方([[动态分配的RCX基址]+0x220]):
      


      找到第一层指针后查看一下内存数据,发现显示网格功能已经被打开了,那么肯定是第一层指针赋值前就已经被初始化了,由于第一层指针是由 rax 赋值的,那么这个 rax 的来源call 就很可疑,跟进去看一哈儿:
      
[Asm] 纯文本查看 复制代码
000000013F3E65F0 | 48:8BF9                      | mov rdi,rcx                                      | rdi 来源是 rcx
000000013F3E6620 | 48:8BC5                      | mov rax,rbp                                      |
000000013F3E6623 | 4C:8BC8                      | mov r9,rax                                       |
000000013F3E6626 | 4C:8BC3                      | mov r8,rbx                                       |
000000013F3E6629 | 48:8BD6                      | mov rdx,rsi                                      |
000000013F3E662C | 48:8BCF                      | mov rcx,rdi                                      |
000000013F3E662F | E8 BC170000                  | call jpegview-js.13F3E7DF0                       | 关键赋值的call

000000013F3E6759 | 48:8BC7                      | mov rax,rdi                                      | rax 来源是 rdi

      从汇编代码可以看出,rax 是来自 rdi 的,也就是说,[rdi+0x30] 就是显示网格数据了,把这个地址添加到Cheat Engine列表中,然后步过观察这个地址数据的变化,可以发现,当步过关键赋值的call时,这个地址的数据被改变了,可想而知这就是显示网格数据初始赋值的地方了,跟进去瞧瞧:
      


      终于真相大白了,现在,只要把这三个赋值的地方 nop 掉或者把赋值的值指向一个空值都可以达到默认关闭显示网格自动裁剪校正后的图像保持画面比例裁剪功能的目的。


4、手术结束,总结一下
      经过近1个小时的跟踪和分析,发现要找到这些功能的关键代码并不难,方法千千万只是方法怎么快怎么来的比较好。需要注意的一点事JPEGView这个软件有重定位,最后用PE工具抹除一下子,不然做了笔记重启软件又得重新跟踪一遍,写了这么多也就只是做了两件事“关闭JPEGView的缩放模糊处理”和“关闭显示网格、自动裁剪校正后的图片和保持画面比例裁剪功能”,软件依旧是可以正常使用的,不会有任何影响!!!


5、成品下载
      本想是学术交流,但我想万一有人刚好需要这个功能呢?以下是成品的链接:
      JPEGView 1.0.35.1:链接:https://pan.baidu.com/s/15HBbuB9hpGMT-VQrXDg2cg 提取码:jf79


      PS:压缩包内“JPEGView.exe.ORG”是原版的 JPEGView。
      大家有任何问题欢迎留言探讨!!!

免费评分

参与人数 13威望 +1 吾爱币 +17 热心值 +13 收起 理由
女萝岩 + 1 + 1 我很赞同!
lijingtong + 1 这个....... 弱弱的说下,JPEGview里面按下F3试试
Hmily + 1 + 6 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
bugof52pj + 1 + 1 谢谢@Thanks!
alicc + 2 + 1 前排,前排。
毛新航 + 1 热心回复!
ddwwtom + 1 + 1 谢谢@Thanks!
gaosld + 1 + 1 用心讨论,共获提升!
陈世界 + 1 + 1 热心回复!
笙若 + 1 + 1 谢谢@Thanks!
19970407 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
jafck + 1 + 1 我很赞同!
weiwei321 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

alicc 发表于 2019-9-13 16:13
前排没了,后排支援。  

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
无瑕黑心肠 + 1 + 1 没想到老哥会来捧场,让你见笑了

查看全部评分

 楼主| 无瑕黑心肠 发表于 2019-9-24 19:32
本帖最后由 无瑕黑心肠 于 2019-9-24 19:41 编辑
lijingtong 发表于 2019-9-24 13:55
这个.......
弱弱的说下,JPEGview里面按下F3试试

一看大哥你就是老用户,像我们这种新用户一言不合可能就拖进OD了[捂脸]

仔细看了下目录的文件,好吧还是发现了 热键映射表,不过我在 JPEGView.ini 中并没有找到默认关闭这个模糊(自动重新采样)的参数设置。最后还是很感谢大哥相知,不然我还不知道 JPEGView 还有这么多快捷键!!
lp1017 发表于 2019-9-12 19:42
w4858775 发表于 2019-9-12 19:51
感谢大佬提供思路
風的痕迹 发表于 2019-9-12 19:52
本帖最后由 風的痕迹 于 2019-9-12 19:55 编辑

感觉没啥效果呢? 用习惯了2345,不过还是谢谢分享!!
fq645122 发表于 2019-9-12 19:55
这是要动刀啊
 楼主| 无瑕黑心肠 发表于 2019-9-12 19:56
風的痕迹 发表于 2019-9-12 19:52
感觉没啥效果呢? 而且没有打印功能,不过还是谢谢分享!!

右键菜单中Print image...是可以打印图片的。它就一款小巧的看图软件,感觉挺不错的,Windows自带的太卡,别的看图太大,不然就是有捆绑广告什么的
超能小虎 发表于 2019-9-12 20:02
感谢分享
跌宕起伏 发表于 2019-9-12 20:14
我还以为软件能治疗近视你
249101999 发表于 2019-9-12 20:28
2345看图王即可解决,貌似那个的放大算法处理比ACDSEE还好
y_w_o 发表于 2019-9-12 20:29
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 06:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表