首页
社区
课程
招聘
[旧帖] [求助]对弹出窗口内容的拦截 0.00雪花
发表于: 2008-1-17 22:54 12538

[旧帖] [求助]对弹出窗口内容的拦截 0.00雪花

2008-1-17 22:54
12538
先在这里声明,俺是一个初哥、不折不扣的初哥、如假包换的初哥。对汇编有一点朦胧的美好

印象(因为有N多年没有用了,这里N >= 5)、对软件逆向工程的了解  = 对OD的了解、

对数据加密的知识 也 = 对OD的了解,而对OD的了解, 仅限于最近两周在看雪的恶补,所以在

帖子中的外行,请各位大侠帮忙、指点

   这个帖子一方面是求助各位老虾,另一方面想将俺的实现艰难历程记录下来

   先说俺的目标:
       
   俺这里有一个软件Xsoft(抱歉这里不提软件名字了,请大虾们原谅),在每次双击左键选择 “XYZ功能”了以后,都会弹出一个页面

   XYZ(标题名称)

     ABC指标:XXXX  
     BCD指标:XXXX
     DEF指标:XXXX
 
     这些指标时刻在变,可以看到,但是不能保存下来,但是俺现在又灰常灰常灰常想把他们保存

下来,怎么办涅?

   俺就用C写了一个软件可以,将 Xsoft 的TCP/IP 报文拦截了下来。通过WPE,确定了ABC、

BCD、DEF指标存放在那个报文中

   然后、然后
 
     问题就来咧,俺怎么将这些指标值从报文里面解出来涅?

   最后思来想去、想来思去,Baidu了N次、Google了N+1 次,找到看雪来了,这一来,就仿佛

多年在外的游子,总算找到了家、又仿佛失散多年的党员,最终找到了组织。

   在看了N+M天的帖子以后,俺根据看雪里面各位大虾的做法,确定了一个伟大而艰巨的目标

   用OD 作逆向工程

   哦的亲娘诶

   这就算踏上不归路了
   
   先看汇编 ,生成了一头雾水

   在看OD  ,又生成了一头雾水

   今天看了坛子里头Wrong兄弟的大作(ollydbg只要知道窗口标题或窗口类名下断的方法)

   总算初步有了一点眉目,俺按照里头的做法

   1、启动OD
 
     2、将Xsoft打开

   3、运行XSoft,暂停

   4、进入windows子窗口,可以看到XYZ功能的定义是一个button

   5、进入CPU 窗口,Ctrl+G, 输入 CreateWindowExA 

    6、进入Code 窗口,Shift + F2 ,输入 [esp+12]==XYZ功能 (这里XYZ功能代表Xsoft

软件的中文标题)

   还真找到了一个入口,底下还有 12 条入栈指令(联想到俺要找的那些数字也正好是 12 个,

难道还真是俺一直寻找的东东吗?)

   

    现在想跟各位老虾请问一下:

  1、在这里设置的条件断点,找到的是否确实就是俺要找的那个button 的结果(因为俺在windows子窗口中,看到父窗口下,有好几个子button 哦,以上步骤,能否就是俺在寻找的真正入口呢?如果还不是,该怎样往下呢?)
   
  2、因为俺的目标是解密算法,这样的话,就需要进行逆推

      因为俺已经可以在显示的页面中知道准确值,在OD中,用甚么指令,可以找到内存中这个准确值的存放地址呢?
 
  3、用甚么指令,可以在这个地址被写入的时候,被中断掉呢?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (29)
雪    币: 203
活跃值: (184)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
OD有搜索内存的功能.
找到那块数据存放在内存后,直接下内存写入断点.(注意你多运行几次看看每次写入的是不是同一块内存地址,如果是就可以在这里下内存写入断点)

如果找不到这几个命令,建议先看看OD帮助.
2008-1-18 09:07
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
借用 JingUlong 前辈写的一篇文章

--------------------------------------------------------------------------------
标 题: 几种典型程序Button处理代码的定位
作 者: jingulong
时 间: 2006-01-04,15:33
链 接: http://bbs.pediy.com/showthread.php?t=20078

首先
1 od 下运行程序,F12 暂停;
2 View菜单中选击Windows项,在打开的窗口中可以从Title栏看到目标按钮,从而找到它的Handle(xxxxxxxx) ;

对不同平台生成的程序,分别处理:

一、VB, Delphi, CBuilder 程序:
3 在CallWindowProcA入口下条件断点: [esp+8]==xxxxxxxx && [esp+0c]==202;
4 F9继续程序,点击目标按钮,程序中断;
5 Alt+F4,在代码段(.text)上下访问断点;
6 F9执行程序,程序中断,
   1). VB程序中断在下面代码
     PUSH DWORD PTR DS:[EAX+EBX]              ; yyyyyyy
     上面[EAX+EBX]的值(yyyyyy)就是我们要找的位置。

   2). Delphi, CBuilder 的程序
     程序直接断在我们要找的位置。

借moon一句,这姑妄称作CallWindowProcA条件断点加上code段内存断点法吧。

二、VC程序
又分MFC和Win32两种情况,二者相同之处:
3 在IsDialogMessageW入口下条件断点: [[esp+8]]==xxxxxxxx && [[esp+8]+4]==202
4 F9继续程序,点击目标按钮,程序中断;
5 Alt+F4,在代码段上下访问断点;
6 F9执行程序,程序中断, 注意这里虽然中断在code段,但却不是处理Button点击事件的代码处
  这时:
  对Win32程序,只需要按几下F7,当回到User32.dll领空后再重复一次第 5、6步就可以了;
  而对于MFC程序,我们不得不多次重复这样的操作:单步回到MFC领空,再第 5、6步。好在已经看到大陆啦!

类比,这就叫IsDialogMessageW条件断点加上code段内存断点法了。

俺现在的操作步骤如下:
1、用PEID检测,这是一个 aspack 2.12 加的衣服,已经用 waspack 脱去了衣服
2、用PEID检测,MultiScan、Task Viewer 等菜单上面一行的文本框中,显示 Microsoft Visual C++ 6.0 ,这里是否是说,这是一个用MSVC++ 6.0 作为开发工具的?是否要遵从
JingUlong前辈写的   二、VC程序 的跟踪方法?
3、对于VC程序,如何区分是MFC还是Win32这两种情况呢?
4、目前说跟踪的这个button ,是在主窗口中,通过双击左键(也就是鼠标左键的dbclick )触发的,JingUlong 前辈里面说的方法,好像不太适用。各位大侠有没有甚么建议呢?
5、windtrace 兄弟的 【求助】消息驱动型的弹出窗口的破解问题  帖子中,有大菜一号同学的答复:
    SendMessage函数,下断吧
这个办法如何呢?
2008-1-18 09:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
对弹出窗口内容的拦截用卡巴或火狐浏览器就可以了!
2008-1-18 11:25
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
按是想通过对窗口的拦截,了解它的算法亚
2008-1-18 11:31
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6




按是想通过对窗口的拦截,了解它的算法亚
2008-1-18 11:32
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
下API对话框断点!
2008-1-18 19:11
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
已经尝试在CPU中,CTRL+N,进入 user32.translatemessage ,shift + f4 设置消息中断

MSG==WM_LBUTTONDBLCLK

但是实际结果是

OD将所有的消息中断都拦截下来了,而不是在鼠标双击的时候才中断的

论坛中一个前辈试图这样处理,据他描述,说鼠标左键双击是在directx 中处理的,所以这里不能拦截下来

程序实际运行过程如下:

1、主程序启动
2、创建主界面
3、创建要拦截的子类
4、进入子界面
5、在主界面中,鼠标双击左键,弹出菜单。可以通过这个菜单进入显示界面(俺想拦截的就是这个)

根据坛子里面另外一位前辈的帖子,尝试用 exescope ,试图通过菜单ID进行跟踪。
但是运行EXEscope 提示 : 无法识别的结构定义。 根据后面兄弟的说法,使用 fixresdemo进行修补,重新运行exescope 提示: 程序已经被压缩  仍然无法提取菜单ID
2008-1-18 21:51
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
由于在实际使用中,实际显示的值是知道的,所以现在正在尝试如下做法

1、根据显示的结果,在CPU窗口,Search for -> all constans -> 界面显示的值 对指定数进行搜索,结果

References in Special:.text to constant 156D, item 0
Address=00C7F03C
Disassembly=CALL DWORD PTR SS:[EBP+F4D]
Comment=(Initial CPU selection)

   在结果上双击,进入实际指令

00C7F03B   50               PUSH EAX
00C7F03C   FF95 4D0F0000    CALL DWORD PTR SS:[EBP+F4D]
00C7F042   8985 26040000    MOV DWORD PTR SS:[EBP+426],EAX
00C7F048   8BF8             MOV EDI,EAX
00C7F04A   8D5D 5E          LEA EBX,DWORD PTR SS:[EBP+5E]

      鼠标右键,设置断点
    Memory , on access
      Memory , on write

      但是接下来F9 执行,没有在这里被中断! 程序一直在运行

请问那位大侠是否我哪里作错?
2008-1-18 22:02
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
刚才在程序运行的情况下,多次根据 all_constants 对显示出来的值进行查找,但是好像每次查找到的地址都是不一样的!

为什么呢?

那位大侠能够帮忙一下吗?
2008-1-18 22:44
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
俺下载了一个类名查找器,已经可以将被调用窗口的类名、句柄找到了

请问该用甚么办法,找到被调用的地址呢?
2008-1-18 23:27
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
调用类名查找器,结果是

类名: Afx:400000:300b
句柄:1770048
2008-1-18 23:28
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
发觉bpx 设置断点是个好方法
我的步骤:
1、先用 bpx ShowWindow
     但是这些断点没有拦截到目标,说明目标不是通过Windows 来显示结果的
2、再用 bpx SetFocus
     在双击左键显示菜单、选择菜单项后进入显示界面,都没有被拦截 说明不是通过设置相关 windows 的 focus 进行的
3、拦截GDI 也没有用
4、假定每次双击鼠标左键,都会重新载入菜单 ,所以设置断点 bpx LoadMenuA ,然后一步一步进入,最终确定入口在  004256BE  ,如果在 004256BE   不设置断点,就可以显示菜单 如果在该处设置断点,程序就会被拦截下来!

   

     总算向胜利接近了一下步
   

004256BC  |. 74 25          JE SHORT _UnPacke.004256E3
004256BE  |. E8 7E1F3600    CALL _UnPacke.00787641
004256C3  |. 3BC5           CMP EAX,EBP
004256C5  |. 74 09          JE SHORT _UnPacke.004256D0
004256C7  |. 8B10           MOV EDX,DWORD PTR DS:[EAX]
004256C9  |. 8BC8           MOV ECX,EAX
2008-1-20 14:30
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
目前已经尝试的方法:
1、尝试使用 Exescope 打开要跟踪的程序,试图通过相应菜单的ID 进行跟踪 (很郁闷,如果没有用 fixresdemo 修复,会提示不能识别的内部结构,用 fixres 修复,会提示程序已经被压缩),故此方法失败
2、bpx ShowWindow ,这种方法只能在程序创建时候可以拦截,程序载入以后,双击左键,不能拦截菜单,说明菜单不是通过创建专用的菜单显示进程进行的。这是一个进步
3、bpx LoadMenuA ,这种方法比上面的要好一点,在鼠标左键双击以后,会被拦截,但是跟踪来跟踪去,最后发现这种方法进入了迷宫,绕来绕去,还是回到了原点
4、试图对方法 1 进行改正, 从网上找到了一个类名查看器(带有源码),想对源码进行修改,设置鼠标的全局钩子,通过拦截 WM_MENUSELECT 显示菜单的ID,这种方法因为对delphi 的了解不多,所以又作罢了
5、继续google ,网上的兄弟提到了bp recv 和bp WASRect 。bp recv 好像不是很有效,但是 bp WASRect 设断以后,程序经常被 pause 下来,联想到俺的目的:

   数据加密算法破解

   ^_^,俺可能在靠近目标了

   经历了千难万险,走过了千山万水,希望曙光就在前方哦
2008-1-22 09:05
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
呵呵,已经确认,这东东不是很管用
2008-1-22 09:06
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
Call stack of main thread
Address    Stack      Procedure / arguments                 Called from                   Frame
0012FAC8   71A42EA3   <JMP.&WS2_32.WSARecv>                 wsock32.71A42E9E              0012FAF0
0012FACC   00000258     Socket = 258
0012FAD0   0012FAE8     pBuffers = 0012FAE8               这是堆栈指针地址
0012FAD4   00000001     nBuffers = 1                             这是甚么字段? 为什么总是 1 呢?
0012FAD8   0012FB00     pReceivedCount = 0012FB00   这又是甚么字段呢?
0012FADC   0012FAFC     pFlags = 0012FAFC
0012FAE0   00000000     pOverlapped = NULL
0012FAE4   00000000     Callback = NULL

以上两个count ,那个是 BufSize  对应的呢?

目前进展,已经可以通过对WASRect 跟踪,进入堆栈了
在google中,好像找不到这些相关字段的解释
2008-1-22 09:09
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
Call stack of main thread
Address    Stack      Procedure / arguments                 Called from                   Frame
0012FAC8   71A42EA3   <JMP.&WS2_32.WSARecv>                 wsock32.71A42E9E              0012FAF0
0012FACC   00000258     Socket = 258
0012FAD0   0012FAE8     pBuffers = 0012FAE8
0012FAD4   00000001     nBuffers = 1
0012FAD8   0012FB00     pReceivedCount = 0012FB00
0012FADC   0012FAFC     pFlags = 0012FAFC
0012FAE0   00000000     pOverlapped = NULL
0012FAE4   00000000     Callback = NULL

这是buffer 指针

pBuffers = 0012FAE8


这是alt+M 进入内存窗口
Memory map
Address    Size       Owner      Section    Contains      Type   Access    Initial   Mapped as
00010000   00001000                                       Priv   RW        RW
00020000   00001000                                       Priv   RW        RW
000F1000   00001000                                       Priv   RW  Guar  RW
000F2000   0003E000                         stack of mai  Priv   RW  Guar  RW
00130000   00003000                                       Map    R         R
00140000   00063000                                       Priv   RW        RW
00240000   00006000                                       Priv   RW        RW
00250000   00003000                                       Map    RW        RW

大侠能否指教一下,为甚么内存窗口中找不到WASRecv 的buffer 亚? 如果要想找到WASRecv的buffer ,具体该怎样操作亚?

问题已经解决:

OD停在当前行

进入数据窗口
Ctrl+G
输入0012FAE8
回车

这里附带了一些我现在用的最多的快捷键
alt+f1 进入命令行窗口
alt+b  显示所有的断点
alt+k  显示堆栈

PS:
   本来想将本文作为一个学习比较兼交流的帖子

   大家在浏览帖子时候,也能够给一些评价,这样声望达到 15 的时候,就可以晋级为正式会员,有甚么问题可以向大家随时请教的

   但是好像没有人回应,提出来的所有问题也是自己 google 解决的,估计俺这种菜鸟大家也没有兴趣

   希望有能力的大侠,帮帮新进来的菜鸟亚
2008-1-22 09:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
嘿嘿,我又偷学了不少哦!
2008-1-22 11:51
0
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19
楼主不要因为到了看雪就认为解决问题必须的用到ASM,其实你的问题应该很有很简单的方法来处理,只要你能找到对应的窗口类,自己写一个程序,做个20ms的时钟,不停的去读那些窗口的caption,就能解决你的问题。
2008-1-22 14:08
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
现在重新转换思路

1、alt+f1 bp WSARecv (对Socket WSARecv 拦截)
2、alt+k  查看调用堆栈
3、进入数据窗口,根据  pBuffers 查找相应内容

Call stack of main thread
Address    Stack      Procedure / arguments                 Called from                   Frame
0012FAC8   71A42EA3   <JMP.&WS2_32.WSARecv>                 wsock32.71A42E9E              0012FAF0
0012FACC   00000270     Socket = 270
0012FAD0   0012FAE8     pBuffers = 0012FAE8
0012FAD4   00000001     nBuffers = 1
0012FAD8   0012FB00     pReceivedCount = 0012FB00
0012FADC   0012FAFC     pFlags = 0012FAFC
0012FAE0   00000000     pOverlapped = NULL
0012FAE4   00000000     Callback = NULL

4、根据 pBuffers 存放地址,重新进入Buffers
这是从网上文章 " 做外挂的一些原理 " 找到的一个描述

WSASend和WSARecv两个函数,他们的缓存结构如下:
typedef struct _WSABUF {
u_long len; /* the length of the buffer */
char FAR * buf; /* the pointer to the buffer */
} WSABUF, FAR * LPWSABUF;

所以可以确定如下:
0012FAE8  00 80 00 00(这是buffer长度) 9C 27 04 10(这是buffer地址)  .€..?

5、在Buffers 的第一、二个字节下 Access 硬件中断
6、取消原来的 WASRecv 中断,F9 重新运行
7、程序被 pause ,这就是以下的代码,俺用 F7 进行跟踪,确定了循环的运行顺序,俺猜测这是strcpy

10004262   8A142F           MOV DL,BYTE PTR DS:[EDI+EBP]             ; 14
10004265   33C9             XOR ECX,ECX                              ; 1
10004267   66:8B8E 51800100 MOV CX,WORD PTR DS:[ESI+18051]           ; 2
1000426E   889431 4A800000  MOV BYTE PTR DS:[ECX+ESI+804A],DL        ; 3
10004275   66:FF86 51800100 INC WORD PTR DS:[ESI+18051]              ; 4
1000427C   66:81BE 51800100>CMP WORD PTR DS:[ESI+18051],0FFFF        ; 5
10004285   72 13            JB SHORT channel.1000429A                ; 6
1000429A   66:8B86 51800100 MOV AX,WORD PTR DS:[ESI+18051]           ; 7    这里是否字符串长度?
100042A1   66:3B86 53800100 CMP AX,WORD PTR DS:[ESI+18053]           ; 8
100042A8   75 53            JNZ SHORT channel.100042FD               ; 9
100042FD   8B4424 0C        MOV EAX,DWORD PTR SS:[ESP+C]             ; 10
10004301   47               INC EDI                                  ; 11
10004302   3BF8             CMP EDI,EAX                              ; 12
10004304  ^0F8C 58FFFFFF    JL channel.10004262                      ; 13

那位大侠帮助解答一下:
   这里strcpy 中,复制以后的目的地址该怎么找出来呢?
2008-1-22 15:55
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
俺现在已经找到了窗口的类,但是需要找到菜单的ID,这样才能进一步跟踪亚
2008-1-23 11:05
0
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
我并没有看你后来得分析过程,根据你的第一贴我认为你就是要把屏幕上显示得动态字符串记录下来。所以我得意思是直接通过窗口得handle去取得那些窗口的caption,就可以满足你的要求了,不用再去decode数据包了。
当然如果要抓的文本是delphi的tlabel的,没有handle,那你可以hook drawtext来抓,不过要考虑repaint的影响。
2008-1-24 17:34
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
我现在要捉的是VC 6.0 编写的东东,我用OD 加载了以后,显示左键双击以后所显示的是一个button !

里面应该是通过tlable 或者tedit 显示的,但是对于大侠所说的直接通过窗口的handle去取得那些窗口的caption,因为还没有用过,所以具体操作不是很了解,大侠能否说的更详细一点呢?

不好意思,我是个菜鸟,所以请大侠帮帮忙
2008-1-25 10:56
0
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
第一次被人称为大侠,心里痒痒的,

GetWindowText就可以啊,不过如果不能跨进程去查询,最好再写个钩子挂到目标进程里去。
另外,TLabel是Borland的VCL里的东西,由于不是window control,没有handle,就不能直接通过这个API来走,可以注入到目标进程以后Hook DrawText,取得对应的显示的文本。

不过有一点,我说的这些方法首先要求你直接能从显示器上看到你要抓的内容才可以,如果那些东西没有显示出来,你就当我没说过。
2008-1-27 15:31
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
    呵呵,侠之一字,并不是单凭武功高下就能称的,这点金庸同学在很多文章中都有过阐述了

  俺这里码了这么多字,就只有兄弟热心帮我解答了,称一声大侠也不为过亚

    我要拦截的那个东东,就是M$ 的VC6.0 写的,不过很奇怪,我用 spy++ 来分析,显示信息的windows 也只有一级,底下就没有之类了! 所以用类名查看器也看不出来,这是甚么原因呢?

  记得以前曾经看过一些文章提到过刷屏的说法,是否这个东西就是通过显示一个图片,需要显示的 Text 就通过刷屏来实现的呢?

  如果这样,HooK drawtext 应该可以罢?
2008-1-28 09:58
0
游客
登录 | 注册 方可回帖
返回
//