Option ExplicitPrivate Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
Private Sub Command1_Click()
    Dim strP As String
    Dim lngStartAdd As Long     '进程内存起始地址
    Dim lngWindowHwnd As Long         '进程句柄
    Dim lngPID As Long
    Dim lngP As Long
    Dim lngProcessHwnd As Long
    Dim strValue As String * 20
On Error GoTo errSub
    lngStartAdd = LoadLibrary("c:\windows\system32\calc.exe")       '读取软件内存起始地址
    lngWindowHwnd = FindWindow(vbNullString, "计算器")                    '找到窗口句柄
    lngP = GetWindowThreadProcessId(lngWindowHwnd, lngPID)                '取得进程PID
    lngProcessHwnd = OpenProcess(PROCESS_ALL_ACCESS, False, lngPID)           '读取进程句柄
    lngP = ReadProcessMemory(lngProcessHwnd, lngStartAdd, strValue, 20, ByVal 0)
    Exit Sub
errSub:End Sub我通过这段代码想查看一下计算器的内存地址的值,lngStartAdd、lngWindowHwnd、lngProcessHwnd都能取得,但就是ReadProcessMemory失败!返回值lngP=0。 我仔细查阅了ReadProcessMemory的使用方法,觉得没有错误。现在我怀疑我的lngStartAdd的读取有问题,百度了一下,并没有找到如何读取exe的起始地址的方法。不知道我的读取内存起始地址的方法是否正确?
lngStartAdd = LoadLibrary("c:\windows\system32\calc.exe")       '读取软件内存起始地址

解决方案 »

  1.   

    LoadLibrary是取得载入的DLL的内存基址,至于能否取得EXE的基址,这个不知道了。
      

  2.   

    怎么没有定义结构 MEMORY_BASIC_INFORMATION
    参考一下下面地址的读取或写入指定地址lAddr的函数ReadWriteMemory:http://topic.csdn.net/u/20110329/10/78f7baa9-d526-4a6f-8e23-6141d9bb76d3.html
      

  3.   

    lngProcessHwnd 名字应该叫ProcessHandle,hwnd是窗口句柄的意思(handle of window)物理内存的起始地址需要读页表,不是能够在用户模式办得到的,而且它也不一定存在于物理内存可以得到虚拟地址,使用EnumProcessModules
      

  4.   

    谢谢指教!
    如果获取的虚拟地址,那么该怎么才能获取物理地址?没有物理地址,还是不能使用ReadProcessMemory读取数据啊。
      

  5.   

    ReadProcessMemory用的是虚拟地址,如果要得到物理地址,编写驱动程序读取对应的页表项
      

  6.   

    windows使用扁平寻址模式,你平常所说的内存地址都是指虚拟地址,很少直接用到物理地址
      

  7.   

    api 声明改成这样就行了:
    Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long,byval  lpBaseAddress As long,byval lpBuffer As string, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    还有就是那些理论派人士也真够可以的,说的天花乱坠的干嘛啊
      

  8.   

    这个不是声明的问题,如果是ByRef Any,调用时加上Byval 就行了
      

  9.   

    查阅了很多资料,都没有介绍如何编程获取进程的内存地址。下载了一个叫:OllyDBG 1.1的软件,反汇编分析。倒是能得出一堆地址,但我不会看。纠结的很啊。
      

  10.   

    想读取鲁大师这个软件的CPU温度
      

  11.   

    是一个好办法,但获取文本存在一定的错误概率。如果能找到这个地址,那么就能彻底解决这个问题了。
    我分析过鲁大师的所有DLL文件,就是没有找到它的读CPU温度的函数。所以就想到了从内存着手的办法。我再折腾一下吧,希望能有收获。。呵呵
      

  12.   

    就是找到鲁大师这个软件中,CPU温度的存储地址。。
      

  13.   

    先用 SPY++ 查看一下这个CPU温度有些什么特点,比如:控件类名,控件句柄等信息,如能找到,那就好办了,用子类化就能解决。 
      

  14.   

    还是想办法自己去获得cpu温度
      

  15.   

    唉,其实我想的这个办法已经很极端了,一般的常规方法不是不行就是获取的CPU温度是恒定的。我就纳闷了,为什么专业的软件能获取?它到底用了什么方法?是不是读取了某一个硬件地址(这个硬件地址存储了CPU的温度)
      

  16.   

    ...
    哥们,没有这么悲剧吧?
    如果我能得到地址,不管它是内存地址,还是端口地址,我都可以读取啊
    比如,如果是内存地址,我可以使用CopyMemory读取,如果是端口地址,我可以使用WinIo.dll的GetPortVal来读取。现在的关键是我无法获取地址。不过,我知道这个想法的确有些剑走偏锋了。谢谢您的热心帮忙!
      

  17.   

    呵呵
    汇编学过一点皮毛
    但毕竟VB不能内嵌汇编对我而言,如果这条路走不通,我就干脆使用Hook方式截取鲁大师的警告消息,毕竟我只是要知道CPU温度过高了,然后关闭调一些不必要的功能而已。
      

  18.   

    全汇编
    我只能向往了。。唉,这个就是一个费力不讨好的事情,如果实在不行,我就在CPU的散热风扇上面给他贴上一个热电阻,搞一个温度传感器,我就不信了!呵呵我使用DLL分析器看了鲁大师的所有DLL文件,没有看出个什么结果。可能是它做了隐藏了。
      

  19.   

    这个应该用了驱动程序,你去看一下有无sys文件
      

  20.   

    要在Timer事件不断地获取,才是动态的!
      

  21.   

    这个的确不是那么容易的事情,需要和底层打交道。
    和底层打交道当然是汇编最好了,但汇编对于绝大多数人来说是很难的如果真的能找到这个“地址”,即便是物理地址 使用象WinIo.dll或inpout.dll是能够完成这个任务的。难度不小啊。既然要借用鲁大师,考虑一下图片验证,它的图形规则。做起来成功率应该比较高。