当前位置:C++技术网 > 资讯 > 霸王硬上弓,看我如何强制给别人程序添加新的功能

霸王硬上弓,看我如何强制给别人程序添加新的功能

更新时间:2017-05-11 11:48:00浏览次数:1+次

    工欲善其事,必先利其器,把工具程序改造得更加好用往往可以事半功倍。
EtherDetect是一款经典强大的抓包软件,是一个协议分析者的常用利器。 但它有缺少拖动文件到程序界面中打开的功能,把.cap文件关联到EtherDetect,双击时只能打开EtherDetect,而不能加载文件。 这样使用起来就不方便,这里,就说说我是怎么对它DIY的。

    先到http://www.etherdetect.com/ 下载  我下载的是1.4版。

     运行后, 测试拖动cap文件到界面上。 可以看到鼠标样式是禁止。 不能拖放。

     双击.cap文件  打开方式设置EtherDetect,打开后可以看到虽然EtherDetect运行了 但数据包文件没有打开。

      好了,现在开始DIY它吧,让它具有双击关联文件打开文件和拖动文件打开文件的功能。

    使用到的工具  Cheat Engine    简称CE  一款内存搜索工具

                  Ollydbg           简称OD    一款调试工具

    先找到它打开文件的方法,点击它的toolbar上的图标,会弹出一个文件选择框,好了,这就能定位到它打开文件的地方了。

      打开OD    文件,附加  选择EtherDetect的进程EtherD

      Bp GetOpenFileNameA    在这儿下断点。 然后点击打开图标。 可以看到 程序暂停到这个位置了。

    

     

    然后到这个函数结尾时下个断   大约在这个位置   然后运行。

    7632333E    5E              pop esi

    7632333F    5B              pop ebx

    76323340    C9              leave

    76323341    C2 0800         retn 0x8

     

    选择我们准备好的cap文件, 然后打开  

    

    

    

    可以看到程序暂停到我们刚刚设置的断点的地方。   OD上选择调试  运行到用户代码。  我们来分析以下这儿代码

     

     

    0040F103   > \6A 00         push 0x0

    0040F105   .  6A 04         push 0x4

    0040F107 68 A0524600   push EtherD.004652A0  

    0040F10C   .  E8 34A90300   call EtherD.00449A45

    上面4句是打开对话框 让用户选择是否需要使用滤镜。

     

    0040F111   .  33C9          xor ecx,ecx

    0040F113   .  83F8 07       cmp eax,0x7

    0040F116   .  0F94C1        sete cl

    0040F119   .  890D D8D74700 mov dword ptr ds:[0x47D7D8],ecx

    判断用户选择 把结果写到0x47D7D8位置

     

     

    0040F11F   .  E8 DB8E0400   call EtherD.00457FFF

    0040F124   .  8B48 04       mov ecx,dword ptr ds:[eax+0x4]

    0040F127   .  E8 522A0300   call EtherD.00441B7E

    0040F12C   .  8BCE          mov ecx,esi

    0040F12E   .  C68424 EC0100>mov byte ptr ss:[esp+0x1EC],0x3

    0040F136   .  E8 A5F4FFFF   call EtherD.0040E5E0       这是清除原来的显示内容,但需要一个this指钍 ECX   这是由ESI传入, 向上了几层,套路很深,决定不找了 用CE搜索它的值00AD3FE8  。 结果如图

    

    

    

    

    可以看到有两个全局变量保存了这个指针,我们就用0047D7E4吧 再向后看代码

    上面是清除原来的数据

    0040F13B   .  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]

    0040F13F   .  891D ECD74700 mov dword ptr ds:[0x47D7EC],ebx

    0040F145   .  E8 F6000000   call EtherD.0040F240

    0040F14A   .  8B7424 10     mov esi,dword ptr ss:[esp+0x10]

    0040F14E   .  51            push ecx

    0040F14F   .  83C6 F0       add esi,-0x10

    0040F152   .  896424 20     mov dword ptr ss:[esp+0x20],esp

    0040F156   .  8BFC          mov edi,esp

    0040F158   .  56            push esi

    0040F159   .  C68424 F40100>mov byte ptr ss:[esp+0x1F4],0x4

    0040F161   .  E8 4A2CFFFF   call EtherD.00401DB0

    0040F166   .  83C4 04       add esp,0x4

    0040F169   .  83C0 10       add eax,0x10

    这一段代码都是取出用户选择的文件路径的字符串指针

     

     

    0040F16C   .  68 207F4000   push EtherD.00407F20

    0040F171   .  8D4C24 1C     lea ecx,dword ptr ss:[esp+0x1C]

    0040F175   .  8907          mov dword ptr ds:[edi],eax

    0040F177   .  E8 74040000   call EtherD.0040F5F0

    加载文件

     

    0040F17C   .  8BF8          mov edi,eax

    0040F17E   .  E8 7C8E0400   call EtherD.00457FFF

    0040F183   .  8B48 04       mov ecx,dword ptr ds:[eax+0x4]

    0040F186   .  E8 1D2A0300   call EtherD.00441BA8

    这一段代码是把数据加载到listctrl

     

    0040F18B   .  3BFB          cmp edi,ebx

    0040F18D   .  75 0E         jnz XEtherD.0040F19D

    这是判断加载成功或者失败

     

    0040F18F   .  6A 00         push 0x0

    0040F191   .  6A 00         push 0x0

    0040F193   .  68 74524600   push EtherD.00465274                                  

    0040F198   .  E8 A8A80300   call EtherD.00449A45

     

    这4句和开始4句一样  是提示框 这儿是提示打开成功

     

     

     

    由于它打开文件不是一个独立的函数,所以我们没法调用,这就需要自己去打造一个打开文件的函数 方便调用。因为程序每个节后面都有很多空闲空间,足够我们写自己的代码了,拖动代码到这节的后面,找到空闲的地方。  先拖到最后,然后向上找到代码末。

     

     好了。 我们来构造自己的打开文件的函数  假设传入一个参数,是文件路径。

     下面就是我构造好的函数  方便理解 我在后面写了备注。

    

    我们先保存一下吧,用OD自带的DUMP插件。   左键---复制到可执行文件---所有修改---全部复制. 

    

    

    

    

    

     

    这时出现一个新的窗口,显示修改后的代码, 千万注意,这时文件还没保存。在新的窗口的右键, 选择保存文件, 就保存成原来的文件就行了。(原来的文件注意备份)

     

     

     

    好了 我们完成了第一段,下面来说说拖动文件打开的原理。 窗口要接受文件拖动的消息,必需在样式中含有WS_EX_ACCEPTFILES。我们可以通过修改窗口样式,来让他接受文件拖动消息。 在VS中 我看可以看到定义WS_EX_ACCEPTFILES的宏  #define WS_EX_ACCEPTFILES       0x00000010L。 

     

    修改了样式还不行,还得做消息处理。 当收到文件拖动的消息时,要自己去处理这个消息,好了 我们先写一个消息处理函数代替原来的proc.  

    先用SPY++  查看它窗口的主要信息,打开SPY++,拖动他的选择标记到主窗口的标题栏上。  注意,一定要是主窗口的标题栏,不然你很可能看到的是子窗口的信息。

    

    记住他的caption 和class  .   点确定

    

     

    记住它的proc。  Proc是一个窗口的处理消息的地方。

     

    好了  打造好了打开文件的函数后 我们来打造自己的proc.

     

    

    写完后 再复制到可执行文件。

     

    关于文件路径存放的位置。  XP以前的系统随便找个空闲区就可以存放数据,WIN10后,系统对数据要求就很严了。必需放在数据区,  每个程序都有启动参数 启动后就不用了,我们找到它 用它来存放文件路径。

    

    

    

     启动参数一般都在入口点使用。我们在OD上点调试  重新开始。  程序暂停在入口点,然后我们F8单步运行下去。 一会就看到

    

    

    

    它把启动参数保存在0x481280这个全局变量中,好了 我们就用它了。把上面我们乱写的地方改成0x481280, 注意:是两处。

     

    准备工作做完了 我们来修改窗口样式,让它接收文件拖动消息。  修改样式时不能太早,必需在它设置样式之后, 一般在ShowWindow以后比较合适,      因为ShowWindow是窗口已准备完成,显示给用户的时候, 这时我们修改了的样式  才不会被重置。

     

    好了开始找位置吧,  OD上 ---调试---重新开始。 停在入口点时, 我们在ShowWindow下断吧   bp ShowWindow。  然后F9运行。

    

    

    马上 就运行到ShowWindow了,程序暂停在这儿。注意看栈中的参数, 注意class  下面这个明显和我们用SPY++得到的不符合, 放走,F9运行 。

     

    

    

    有一个CLASS很象  但标题不符合,也不是。 F9继续

     

     

    就是它了  标题 类名都符合。 取消断点,运行到用户代码。

     

     

    

     

      劫持的地方要有三个必需条件:1 也就是程序设置样式后。 2 方便取窗口句柄。 3。这段代码最好只调用一次。  , 好了我们来验证一下这个地方会运行几次吧 。  下断, 重新运行。

     

    结果,发现 会多次停在这儿,其它窗口也有调用这个函数显示窗口的, 上面的地方不能用来劫持了,打劫嘛,肯定要在别人落单的地方最好,   我们再向上运行一级 。

     

    我们来到

    

     现在可以看下,下面他会调用UpdateWindow, 句柄已经装入寄存器edx了。   各种条件都满足了,,我们就在这儿打劫了。

    劫持的地方找好了,就去准备好劫持后的事,我们又到刚刚的自己的proc后面去写好劫持后的代码, 

    劫持后要做三件事   

       一 首先修改样式,增加WM_DROPFILES样式。

       二 修改程序的proc  方便长期打劫。

    三  查看启动参数,如果有打开文件的参数  就打开文件 

    

    然后我们来一件一件事吧 

    一  首先修改样式,增加WM_DROPFILES式。

    

     

     

    然后回到0041AF6A的地方, 去把进程劫持过来就OK了。

    改成

    

    保存可执行文件。 重新运行后, 我们拖动文件到窗口,可以看到鼠标样式不是禁止拖动的样式了, 现在是可以拖动了,第一件事测试成功 。。 

     放开文件,但这是没用的,还是不能打开,因为我们没有去做处理WM_DROPFILES的动作, 其实处理函数我们是写好了的,就是我们的proc, 我们还是用SetWindowLong去设置新的proc; 接着刚刚的函数POP ESI的位置   继续做第二件事。

    

      二 修改程序的proc  方便长期打劫。 

    接着上面  别忙pop esi 继续setwindowlong

    

     

      

    重新运行  OK , 没问题,拖个cap文件试试 ,文件打开了,成功!   

     

     三  查看启动参数,如果有打开文件的参数  就打开文件 

     还有一个功能 就是双击cap文件打开的功能。 要增加这个功能,就得到程序运行时判断启动参数,如果有多个的话,就打开第二个参数, 因为双击关联文件时,启动参数会是两个,第一个是这个程序的路径, 第二个是关联文件的路径 。 

    我们就在修改窗口样式后面读取参数吧,

    

     

     

     

      好了 复制到可执行文件   然后 双击.cap ,  系统会提示打开方式  你选择这程序就行,  可以看到,双击后 EtherDetect运行 了,  文件也加载了。