首页
社区
课程
招聘
[讨论][讨论]VB如何读取另一运行程序中寄存器的内容?
发表于: 2009-3-11 19:38 10485

[讨论][讨论]VB如何读取另一运行程序中寄存器的内容?

2009-3-11 19:38
10485
以下是运行NOTEPAD.EXE,在01001EDD处OD中断结果:
01001ED6  |.  8B3D 48120001 MOV EDI,DWORD PTR DS:[<&USER32.CheckMenu>; |USER32.CheckMenuItem
01001EDC  |.  50            PUSH EAX                                 ; |hMenu
01001EDD  |.  FFD7          CALL EDI                                 ; \CheckMenuItem

      用VB编写的程序A(原代码见后面)在01001EDD这个地方读出 EAX 里的数值(0x9868706A)与OD中断处EAX(0x1BD9051D)不一样,请教一下问题出在哪里?
    另外程序A退出后,发现NOTEPAD.EXE仍在进程中运行(没有窗口显示),如何终止NOTEPAD.EXE运行?

'===Vbcode===
Private Sub Command1_Click()
Dim idh As IMAGE_DOS_HEADER
Dim inh As IMAGE_NT_HEADERS
Dim ish As IMAGE_SECTION_HEADER
Dim pi As PROCESS_INFORMATION
Dim si As STARTUPINFO
Dim context As CONTEXT86
Dim ImageBase As Long, ret As Long, i As Long
Dim addr As Long, lOffset As Long, addr1 As Long
si.cb = Len(si)

sTarget = "C:\WINDOWS\NOTEPAD.EXE"
CreateProcess vbNullString, sTarget, 0, 0, False, CREATE_SUSPENDED, 0, 0, si, pi
SuspendThread pi.hThread
DebugActiveProcess pi.hProcess
WaitForDebugEvent DebugEv, 10
context.ContextFlags = CONTEXT86_INTEGER
GetThreadContext pi.hThread, context
ImageBase = VirtualAllocEx(pi.hProcess, ByVal inh.OptionalHeader.ImageBase, inh.OptionalHeader.SizeOfImage, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
context.Dr0 = &H1001EDC
context.Dr7 = BREAK_DR7_FLAG
SetThreadContext pi.hThread, context
rr = ReadProcessMemory(pi.hProcess, ByVal context.Eax, addr1, 4, 0)
ResumeThread pi.hThread
ContinueDebugEvent pi.hProcess, pi.hThread, dwContinueStatus
CloseHandle pi.hThread
CloseHandle pi.hProcess
Label1 = "进程:" & pi.hProcess & " 线程:" & Hex(pi.hThread) & _
  " 寄存器Eax:" & Hex(addr1) & " 读内存状态:" & rr
End Sub

Private Sub Command2_Click()
End
End Sub

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

收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 143
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
以前我好像也遇到过这个问题,后来怎么解决的,忘记了。。。。
2009-3-11 20:02
0
雪    币: 228
活跃值: (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
不清楚。。。。我看到有人用zwClose来关闭进程。。。。
2009-3-12 07:25
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
4
虽然不太懂VB,但那几个API还是认得的。

1.直接用DEBUG_PROCESS来CreateProcess,而不要用CREATE_SUSPENDED的CreateProcess后再DebugActiveProcess。这两种途径是不一样的,会改变进程的初始化。

2.设置CONTEXT86_INTEGER标志,并不能改变DebugRegister,所以断点没设置上。

3.寄存器EAX的值,直接从Context.Eax得到,而不是ReadProcessMemory

4.即使成功地在0x1001EDC设置了断点,也需要等断点触发后,再GetThreadContext,这样得到的context才是程序执行到这里时的。

5.CloseHandle后,调试器与被调试进程不再具有父子关系,也不再具有debugger与debuggee的关系,所以,程序退出后被调试进程并不退出。

我觉得楼主的问题是对SDK中的API用法不熟悉,我的问题是对VB的语法不熟悉。
2009-3-12 13:06
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
5
补充一:原来的代码中EAX中是一个句柄值,这个句柄通常是动态生成的,所以,每次运行可能不相同的。

补充二:要关闭记事本,要么显式地TerminateProcess,要么只要不CloseHandle,当调试器退出时被调试进程会强制关闭的。
2009-3-12 13:12
0
雪    币: 198
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
请问直接用DEBUG_PROCESS来CreateProcess后,用什么函数能在0x1001EDC设置了断点和等待断点触发,在Context.Eax得到寄存器EAX的值?
2009-3-12 19:44
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
7
跳下去 保存eax 跳回来 读取 不知道能不能达到效果..
2009-3-12 20:25
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
8
用DEBUG_PROCESS的参数来CreateProcess后,新创建的进程并没有开始运行。

循环WaitDebugEvent,可以得到诸如

CREATE_PROCESS_DEBUG_EVENT
UNLOAD_DLL_DEBUG_EVENT
LOAD_DLL_DEBUG_EVENT

等一系列调试事件,这些是进程初始化过程的调试事件,必须全部用DBG_CONTINUE来调用ContinueDebugEvent。

但是,根据这篇文章所讲,

http://www.nynaeve.net/?p=81


在进程初始化阶段,如果简单地修改DRx来设置硬件断点,在初始化完成后,DRx寄存器是会被冲掉,那么设置的断点也就无效了。。

所以,多数调试器的“停在入口点”,或者“停在main函数”等功能,通常是用Int3断点实现的。

实际上,第一次设置的断点,不管是在入口点还是在其它任意位置,比如0x1001EDC,最简单的方法是设置Int3断点。

当WaitForDebugEvent收到“调试异常”事件,即EXCEPTION_DEBUG_EVENT时,检查异常种类,如果是EXCEPTION_BREAKPOINT,说明被调试的进程触发了断点,如果确认了异常地址ExceptionAddress就是设置的断点地址,就可以GetThreadContext了,并且可以直接从返回的context得到寄存器(比如EAX)的值。

关于涉及到的API及相关数据结构,自己查MSDN,这是MSDN在线文件中关于DEBUG_EVENT结构的页面:

http://msdn.microsoft.com/en-us/library/ms679308(VS.85).aspx

关于调试器的工作原理,有兴趣的可以参考一下这个:

http://blogs.msdn.com/jacdavis/archive/2008/02/20/new-debug-engine-sample.aspx
2009-3-12 22:45
0
雪    币: 198
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
在0x1001EDC设置断点没,看来我只好改用设置Int3断点。

用DEBUG_PROCESS的参数来CreateProcess后,新创建的进程,用TerminateProcess关闭记事本时,我发现在Windows任务管理器中还有该进程存在,我用Windows任务管理器中的结束进程也无法关闭该进程,请问如何能解决?
2009-3-15 16:28
0
雪    币: 1632
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
做内存注册机吗
2009-3-15 16:37
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
11
这个问题我也是查了一些资料才搞明白。被调试进程死亡后,调试器会收到EXIT_PROCESS_DEBUG_EVENT等调试事件。应该将所有的调试事件都ContinueDebugEvent,然后关闭被调试进程的句柄,进程对象就会被内核释放了。

这个帖子可能会有帮助。
http://social.microsoft.com/Forums/en-US/vsdebug/thread/5af3213b-ee8b-4da5-9554-f14f5abb8a1f
2009-3-15 17:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
看看看看看看
2009-3-15 17:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
是这样,不错
2009-3-15 17:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
最近也在破个软件,
2009-3-15 17:57
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
继续努力贴子快到10啊,
2009-3-15 17:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
可一发主题了
2009-3-15 17:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
怎么有这个限制了呢?
2009-3-15 17:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
啥时开始的?
2009-3-15 17:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
最近吧,累!
2009-3-15 18:00
0
雪    币: 198
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
用DEBUG_PROCESS的参数来CreateProcess后,新创建的进程,运行ContinueDebugEvent正常,再用TerminateProcess关闭记事本,还是无法关闭结束进程,怎样解决呀?郁闷呀!!!
2009-3-16 21:31
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
21
先TerminateProcess,然后还有许多DEBUG_EVENT会收到,比如EXIT_PROCESS_DEBUG_EVENT,要把所有的调试事件都处理完成,进程对象才会被释放。
2009-3-17 00:17
0
游客
登录 | 注册 方可回帖
返回
//