這個(gè)東西呢,現(xiàn)在的動(dòng)能來看,需要的核心就這幾部分
十年的柘榮網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整柘榮建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“柘榮網(wǎng)站設(shè)計(jì)”,“柘榮網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
1、進(jìn)程列表獲取,VB6中都是用API,可是.NET里不用了。
2、進(jìn)程操作權(quán)限的提升,修改了VB6的一些API聲明來實(shí)現(xiàn)的。
3、進(jìn)程內(nèi)存的讀寫,也是修改了一些VB6的API實(shí)現(xiàn)的。
4、用BYTE結(jié)構(gòu)存取2進(jìn)制文件內(nèi)容以獲取配置。
5、一些進(jìn)制的轉(zhuǎn)換。
要陪媳婦去了,所以這篇寫最簡單的一個(gè):BYTE數(shù)組與INTEGER類型的轉(zhuǎn)換。
同志們可能要說了,這個(gè)是啥,還用你寫。。。呵呵。。反正我是不知道.NET里面轉(zhuǎn)換的方法,另外用分字節(jié)轉(zhuǎn)化的辦法代碼太多,也懶得寫。再就是公開一下這個(gè)API的使用方法,在網(wǎng)上找的頭大手疼也沒找到。
把它帖在這里,.NET2005下測試通過。
Private Declare Sub CopyMemoryToArr Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination() As Byte, ByRef Source As Integer, ByVal Length As Integer)
Private Declare Sub CopyMemoryToDec Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Int32, ByVal Source() As Byte, ByVal Length As Integer)
嘿嘿,看著眼熟吧,實(shí)際上就是VB6里咱們可愛的CopyMemory。。。不過因?yàn)橛猛静煌猿霈F(xiàn)了2個(gè)定義方式,我弄了半天,還是沒能寫成一種定義形式。
寫成函數(shù):
Public Function HexArr2Dec(ByVal ByteArr() As Byte) As Integer
Dim Dec As Integer
CopyMemoryToDec(Dec, ByteArr, 4)
Return Dec
End Function
Public Function Dec2HexArr(ByVal Dec As Integer) As Byte()
Dim mTmpArr(3) As Byte
CopyMemoryToArr(mTmpArr, Dec, 4)
Return mTmpArr
End Function
調(diào)用方法:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim byteArr(3) As Byte, intnum As Integer = 511
byteArr = Dec2HexArr(intnum)
Debug.Print(byteArr(0) " " byteArr(1) " " byteArr(2) " " byteArr(3))
MsgBox(HexArr2Dec(byteArr))
End Sub
ok了,就這些啊。?;仡^看看這個(gè)定義,有幾個(gè)有趣的地方
CopyMemoryToArr 中 ByVal Destination() As Byte 和 ByRef Source As Integer
CopyMemoryToDec 中 ByRef Destination As Int32 和 ByVal Source() As Byte
以往VB6里面,我們(至少是我)要像RtlMoveMemory函數(shù)傳遞值的時(shí)候,是這樣定義的
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
在.NET里這個(gè)ANY被INTPTR代替了,但是在某些操作數(shù)組的API中,例如ReadProcessMemory、WriteProcessMemory等,寫成INTPTR很難成功調(diào)用,我們就可以修改定義為XXXX() As Byte。還有一個(gè)有趣的地方,API里面?zhèn)鬟f數(shù)值時(shí),一般Byval來做,可是上面,卻定義為ByRef Source As Integer和ByRef Destination As Int32。。(懶啊我,沒有統(tǒng)一定義,INT32和INTEGER一樣吧)
總結(jié)一下:
若,VB6的API聲明中參數(shù)為ANY則:
1、當(dāng)需要向API內(nèi)傳遞數(shù)組的指針時(shí),將VB6聲明修改為ByVal xxxx() As Byte (必須為BYVAL)
2、當(dāng)需要向API內(nèi)傳遞一個(gè)被其操作的數(shù)據(jù)時(shí),將VB6聲明修改為ByRef Source As (Integer)
3、僅傳遞數(shù)據(jù)時(shí),可聲明為ByRef XXXX As IntPtr(Int32,Integer)
另舉2例:
Private Declare Function ReadProcessMemory Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByVal lpBuffer() As Byte, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer) As Integer
Private Declare Function WriteProcessMemory Lib "kernel32" ( _
ByVal hProcess As Int32, _
ByVal lpBaseAddress As Int32, _
ByVal lpBuffer() As Byte, _
ByVal nSize As Int32, _
ByRef lpNumberOfBytesWritten As Int32) As Integer
以上2聲明在VS.NET 2005環(huán)境測試通過。其中Int32和Integer可互相替換。
Imports System.Runtime.InteropServices
Public Class MemoryEditor
Inherits WINAPI.NativeMethods
Private phwnd As IntPtr
Private Buffer As Byte()
Private BytesRead As IntPtr
Private BytesWrite As IntPtr
''' summary創(chuàng)建內(nèi)存編輯器/summary
''' param name="processHwnd"進(jìn)程句柄/param
Sub New(processHwnd As IntPtr)
Me.phwnd = processHwnd
End Sub
''' summary根據(jù)指定偏移量讀取內(nèi)存基址/summary
''' param name="addr"內(nèi)存地址/param
''' param name="offsets"偏移量數(shù)組/param
Public Function ReadBaseAddress(addr As IntPtr, offsets() As Integer) As IntPtr
Dim address As IntPtr = ReadMemoryToInteger(addr)
For Each offset As Integer In offsets
address = address.ToInt32 + offset
address = ReadMemoryToInteger(address)
If address = IntPtr.Zero Then
Dim errInfo As String = "內(nèi)存偏移量[" Hex(offset) "]錯(cuò)誤!"
Throw New Exception(errInfo)
End If
Next
Return address
End Function
''' summary讀取4字節(jié)內(nèi)存數(shù)值/summary
''' param name="addr"內(nèi)存地址/param
Public Function ReadMemoryToInteger(addr As IntPtr) As Integer
Buffer = New Byte(3) {}
ReadProcessMemory(phwnd, addr, Buffer, 4, BytesRead)
Return BitConverter.ToInt32(Buffer, 0)
End Function
''' summary讀取4字節(jié)內(nèi)存數(shù)組/summary
''' param name="addr"內(nèi)存地址/param
Public Function ReadMemoryToBytes(addr As IntPtr) As Byte()
Buffer = New Byte(3) {}
ReadProcessMemory(phwnd, addr, Buffer, 4, BytesRead)
Return Buffer
End Function
''' summary將內(nèi)存值數(shù)組寫入指定地址/summary
''' param name="addr"內(nèi)存地址/param
''' param name="buffer"內(nèi)存值數(shù)組/param
Public Function WriteMemoryByBytes(addr As IntPtr, buffer As Byte()) As Boolean
Return WriteProcessMemory(phwnd, addr, buffer, buffer.Length, BytesWrite)
End Function
End Class
Namespace WINAPI
Public MustInherit Class NativeMethods
DllImport("kernel32.dll", SetLastError:=True) _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
Out() ByVal lpBuffer() As Byte, _
ByVal dwSize As Integer, _
ByRef lpBytesRead As Integer) As Boolean
End Function
DllImport("kernel32.dll", SetLastError:=True) _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
ByVal lpBuffer As Byte(), _
ByVal nSize As Integer, _
Out() ByRef lpBytesWritten As IntPtr) As Boolean
End Function
End Class
End Namespace
是不是內(nèi)存讀寫代碼有問題!用上面的代碼試試,我以前寫的;
調(diào)用方法:
Dim mem As New MemoryEditor(進(jìn)程句柄)
Dim offsets As Integer() = {H1, H2, H3} '{一級(jí)基址,二級(jí)基址,三級(jí)基址}
Dim baseaddr As IntPtr = mem.ReadBaseAddress(內(nèi)存地址, offsets)
Dim value As Integer = mem.ReadMemoryToInteger(baseaddr)
題主用的是 VB6 時(shí)代的 Windows API,那里面的 Long 類型相當(dāng)于 .NET 里的 Int32,聲明 API 時(shí)要把所有 Long 類型替換成 Int32 才可以正常使用,否則堆棧溢出。
另外操作內(nèi)存這種函數(shù)需要管理員權(quán)限來運(yùn)行,否則程序會(huì)報(bào)錯(cuò)甚至崩潰。
無法從地址讀取數(shù)值,建議你換一個(gè)更大內(nèi)存的內(nèi)存條就可以正常使用了。