有关内存读取的问题,每次读一字节正确,每次读五字节错误。为什么?!
写了个程序扫描内存,内含两个过程,也就两种方式:read1byte()每次读取一个字节,read5byte每次读五个字节,预先申请了缓存变量cstring存放读取内容,但一个一个地读和我用winhex显示的是一样的,每五个字节地读老显示“调试?”,后调整为读六字节,显示为“调试器”,为了方便跟踪,开了调试器。因为WINAPI要求变量的指针,用了VB函数取VFP下字符串变量的指针,怀疑是VFP自动维护分配变量内存导致变量地址改变,但基本都显示的是“调试器”三个字,求解。贴源码如下:一、函数申明,主环境设置
二、read1byte(),传递参数为窗口栏文字
三、read5byte(),传递参数为窗口栏文字
Declare Long VarPtr In msvbvm60.Dll String Pstr
Declare Long ReadProcessMemory In WIN32API Long hProcess,Long lpBaseAddress,Long lpBuffer,Long nSize,Long @lpNumberOfBytesWritten
Declare Integer OpenProcess In kernel32 Integer dwDesiredAccessas,Integer bInheritHandle,Integer dwProcId
Declare Integer GetSystemDirectory In kernel32 As GetSystemDirectoryA;
STRING @ lpBuffer,;
INTEGER nSize
Declare Integer FindWindow In user32;
STRING lpClassName,;
STRING lpWindowName
Declare Integer GetWindowThreadProcessId In user32;
INTEGER HWnd,;
INTEGER @ lpdwProcId
Declare Integer ShellExecute In shell32;
INTEGER HWnd,;
STRING lpOperation,;
STRING lpFile,;
STRING lpParameters,;
STRING lpDirectory,;
INTEGER nShowCmd
Declare Integer GetProcessHeap In WIN32API
Declare Integer HeapAlloc In WIN32API Integer hHeap, Integer dwFlags, Integer dwBytes
Declare Integer HeapFree In WIN32API Integer hHeap, Integer dwFlags, Integer lpMem
Declare Integer SendMessage In user32;
INTEGER HWnd,;
INTEGER Msg,;
INTEGER wParam,;
INTEGER Lparam
*************************************************************************以上为函数申明
****每次读取1字节
******************************************************READ1BYTE*******************************************************
Procedure read1byte
Lparameters cType&&type of machine
Public cmem,lpcmem,cyear,Cmonth,cday,ctitle
cmem=" "
lpcmem=varptr("cmem")
cyear=Alltrim(Str(Year(Date())))+"/"
Cmonth=Alltrim(Str(Month(Date())))
Cmonth=Iif(Len(Cmonth)=2,Cmonth,"0"+Cmonth)+"/"
cday=Alltrim(Str(Day(Date())))
cday=Iif(Len(cday)=2,cday,"0"+cday)+"]"
ctitle=cType+cyear+Cmonth+cday
Public hwindow,hpid,hprocess,PROCESS_ALL_ACCESS,lpnumread,mheap
hwindow=0
hpid=0
hprocess=0
PROCESS_ALL_ACCESS=0x1F0FFF&&right to open
lpnumread=0
hwindow=FindWindow(0,ctitle)
GetWindowThreadProcessId(hwindow,@hpid)
hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,hpid)
**处理字串
Local a,cstring,ncount,cnum
Local Array num9[1,2],num10[1,2]
ncount=0
cstring=" "
*ReadProcessMemory(hProcess,0x22e8300 ,lpcmem,8132608,@lpnumread)
For a=0x9300000 To 0x9400000
ReadProcessMemory(hProcess,a,lpcmem,1,@lpnumread)&&读取0x22e8300到0x2aa9b00处共8132608字节(7M)到cmem
cstring=Sys(2600,lpcmem,1)
If Isdigit(cstring)
cnum=cnum+cstring
ncount=ncount+1
Else
If ncount=9
num9[alen(num9,1),1]=cnum
Dimension num9[alen(num9,1)+1,2]
Endif
If ncount=10
num10[alen(num10,1),1]=cnum
Dimension num10[alen(num10,1)+1,2]
Endif
cnum=""
ncount=0
Endif
Endfor
If !Used("n9")
Use n9 In 0
Select n9
Else
Select n9
Endif
Append From Array num9
Delete All For n9="536870912" Or n9="553648127" Or "F"$n9
Pack
If !Used("n10")
Use n10 In 0
Select n10
Else
Select n10
Endif
Append From Array num10
Endproc
*处理字串
********************************************************************READ5BYTE**************************************************
********************************每次读5字节
Procedure read5byte
Lparameters cType&&type of machine
Public cmem,lpcmem,cyear,Cmonth,cday,ctitle
cmem=" "
lpcmem=varptr("cmem")
cyear=Alltrim(Str(Year(Date())))+"/"
Cmonth=Alltrim(Str(Month(Date())))
Cmonth=Iif(Len(Cmonth)=2,Cmonth,"0"+Cmonth)+"/"
cday=Alltrim(Str(Day(Date())))
cday=Iif(Len(cday)=2,cday,"0"+cday)+"]"
ctitle=cType+cyear+Cmonth+cday
Public hwindow,hpid,hprocess,PROCESS_ALL_ACCESS,lpnumread,mheap
hwindow=0
hpid=0
hprocess=0
PROCESS_ALL_ACCESS=0x1F0FFF&&right to open
lpnumread=0
hwindow=FindWindow(0,ctitle)
GetWindowThreadProcessId(hwindow,@hpid)
hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,hpid)
**处理字串
Local a,cstring,ncount,cnum,Back,preced
Local Array num9[1],num10[1]
ncount=0
cstring=""
cnum=""
*读取1M内存,每次五字节
For a=0x9300000 To 0x9400000 Step 6
ReadProcessMemory(hProcess,a,lpcmem,6,@lpnumread)
cstring=Sys(2600,lpcmem,6)
If Isdigit(cstring) And Isdigit(Substr(cstring,2,1)) And Isdigit(Substr(cstring,3,1)) And Isdigit(Substr(cstring,4,1)) And Isdigit(Substr(cstring,5,1))
cnum=cnum+cstring&&如果五字节都是数字,开始前读4字节,后读六字节
For Back=1 To 4&&前读
ReadProcessMemory(hProcess,a-Back,lpcmem,1,@lpnumread)
cstring=Sys(2600,lpcmem,1)
If Isdigit(cstring)
cnum=cstring+cnum
Else
Exit&&如果有一个非数字,退出
Endif
Endfor
For preced=1 To 6&&后读六字节
ReadProcessMemory(hProcess,a+preced,lpcmem,1,@lpnumread)
cstring=Sys(2600,lpcmem,1)
If Isdigit(cstring)
cnum=cnum+cstring
Else
Exit&&如果遇到非数字,退出
Endif
Endfor
If Len("cnum")=9&&评判数字是否为九位或十位,存入数组
Dimension num9[ALEN(num9)+1]
num9[ALEN(num9)]=cnum
Else
If Len("cnum")=10
Dimension num10[ALEN(num10)+1]
num10[ALEN(num10)]=cnum
Endif
Endif
cnum=""&&清空缓存区,更新读取位置
a=a+preced
Endif
Endfor
Endproc