(Read|Write)ProcessMemory的函数封装成的命令行小工具 VB.NET源码
本帖最后由 老刘 于 2017-11-19 13:18 编辑http://s1.wailian.download/2017/11/19/46c4b5d790625966.png
Option ExplicitModule ReadProcessMemory
Public Class ReadProcessMemory_Main
Public Shared Sub Main(ByVal cmdArgs() As String)
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
If CmdArgs.Length = 3 Then
If IsNumeric(cmdArgs(0)) And IsNumeric(cmdArgs(1)) And IsNumeric(cmdArgs(2)) Then
Dim ProcessHandle,BytesLong,ReturnValue,Conter As Long
Dim Bytes(Clng(cmdArgs(2))) As Byte
ProcessHandle = WinAPI.OpenProcess(PROCESS_ALL_ACCESS,False,Clng(CmdArgs(0)))
ReturnValue = WinAPI.ReadProcessMemory(ProcessHandle,Clng(CmdArgs(1)),Bytes,Clng(CmdArgs(2)),BytesLong)
If ReturnValue = 1 Then
For Conter = 1 To BytesLong
Console.Write(Right("0" & Hex(Bytes(Conter)),2)&Chr(&H20))
Next
Console.WriteLine()
Else
Console.WriteLine("读取失败!")
End If
Else
Console.WriteLine("输入的值不合法!")
End If
Else
Console.WriteLine("老刘制作——进程内存读取工具")
Console.WriteLine("用法:")
Console.WriteLine(" ReadProcessMemory <ProcessID> <BaseAddress> <Long>")
Console.WriteLine(" ProcessID 指定需读取进程的PID")
Console.WriteLine(" BaseAddress 指定需读取进程内读取数据的起始地址")
Console.WriteLine(" Long 指定需读取进程内读取数据的长度(Byte)")
End If
End Sub
End Class
Public Class WinAPI
Declare Function OpenProcess Lib "KERNEL32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long ) _
As Long
Declare Function ReadProcessMemory Lib "KERNEL32" ( _
ByVal hProcess As Long, _
ByVal lpBaseAddress As Long, _
lpBuffer As Byte(), _
ByVal nSize As Long, _
ByRef lpNumberOfBytesRead As Long) _
As Long
End Class End ModuleOption Explicit
Module WriteProcessMemory
Public Class WriteProcessMemory_Main
Public Shared Sub Main(ByVal cmdArgs() As String)
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Const PAGE_EXECUTE_READWRITE As Long = &H40
If CmdArgs.Length > 2 Then
If IsNumeric(cmdArgs(0)) And IsNumeric(cmdArgs(1)) Then
Dim ProcessHandle,OldProtect,ReturnValue(2),Conter(1) As Long
Dim Bytes() As Byte
Conter(1) = 0
Rem 获取HEXs并生成数组
For Conter(0) = 2 to CmdArgs.Length - 1
If IsNumeric(CmdArgs(Conter(0))) Then
If CLng(CmdArgs(Conter(0))) >= 0 And _
CLng(CmdArgs(Conter(0))) <= &HFF Then
ReDim Preserve Bytes(Conter(1))
Bytes(Conter(1)) = CByte(CmdArgs(Conter(0)))
Conter(1) = Conter(1) + 1
End If
End If
Next
Rem 以最高权限附加到目标进程
ProcessHandle = Win32.OpenProcess( _
PROCESS_ALL_ACCESS, _
False, _
Clng(CmdArgs(0)))
Rem 更改内存属性为读+写+执行
ReturnValue(0) = Win32.VirtualProtectEx( _
ProcessHandle, _
Clng(CmdArgs(1)), _
Conter(1), _
PAGE_EXECUTE_READWRITE, _
OldProtect)
Rem 写入数据
ReturnValue(1) = Win32.WriteProcessMemory( _
ProcessHandle, _
Clng(CmdArgs(1)), _
Bytes,Conter(1),0)
If ReturnValue(1) <> 1 Then
If ReturnValue(0) <> 1 Then
Console.WriteLine("更改内存属性失败!")
End If
Console.WriteLine("写入失败!")
End If
If ReturnValue(0) <> 0 Then
Rem 还原内存属性
ReturnValue(2) = Win32.VirtualProtectEx( _
ProcessHandle, _
Clng(CmdArgs(1)), _
Conter(1), _
OldProtect,0)
End If
Else
Console.WriteLine("输入的值不合法!")
End If
Else
Console.WriteLine("老刘制作——进程内存写入工具")
Console.WriteLine()
Console.WriteLine("用法:")
Console.WriteLine(" WriteProcessMemory <ProcessID> <BaseAddress> <HEX> ...")
Console.WriteLine(" ProcessID 指定需写入进程的PID")
Console.WriteLine(" BaseAddress 指定需写入进程内数据的起始地址")
Console.WriteLine(" HEXs 需写入的数据(至少一个,数值范围:0~255)")
Console.WriteLine()
Console.WriteLine("提示:")
Console.WriteLine("传入数据时,十六进制请用""&H""前缀表示")
End If
End Sub
End Class
Public Class Win32
Declare Function OpenProcess Lib "KERNEL32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long ) _
As Long
Declare Function WriteProcessMemory Lib "KERNEL32" ( _
ByVal hProcess As Long, _
ByVal lpBaseAddress As Long, _
ByVal lpBuffer As Byte(), _
ByVal nSize As Long, _
ByRef lpNumberOfBytesWritten As Long) _
As Long
Declare Function VirtualProtectEx Lib "KERNEL32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flNewProtect As Long, _
ByRef lpflOldProtect As Long) _
As Long
End Class End Module
编译用这个批处理:
@Echo off
Rem Code BY 老刘
Set 使用最新版本Net编译=False
Set 使用当前系统位数对应的FrameWork版本编译=True
Set 系统位数=&Set COMMAND=
if /i "%使用最新版本Net编译%" NEQ "True" ^
Set "COMMAND=&& GOTO :JumpOut"
if /i "%使用当前系统位数对应的FrameWork版本编译%" EQU "True" ^
Set 系统位数=%PROCESSOR_ARCHITECTURE:~-2%
For /D %%a in (%systemroot%\Microsoft.NET\FrameWork%系统位数:86=%\v?.*) Do (
rem 循环迭代,如果“使用最新版本编译”不为真,读取到第一个版本时就跳出。
If Exist "%%~a\csc.exe" if Exist "%%~a\vbc.exe" Set "FrameWorkPath=%%~a" %Command%
)
:JumpOut
Set "Path=%FrameWorkPath%;%Path%"
if Exist "%~1" Call :处理 "%~1" & GOTO :Eof
Echo 拖入文件,按回车编译。
:LOOP
Set /p FilePath=^>
if Exist "%FilePath:"=%" Call :处理 "%FilePath:"=%"
Goto :Loop
:处理
Set C#_Or_VB.NET=
IF /i "%~x1" EQU ".CS" Set C#_Or_VB.NET=CSC
IF /i "%~x1" EQU ".VB" Set C#_Or_VB.NET=VBC
IF Not DEFINED C#_Or_VB.NET GOTO :Eof
PUSHD "%~dp1"
%C#_Or_VB.NET% -nologo "%~nx1"
IF ERRORLEVEL 1 GOTO :Eof
Echo RUNNING...
"%~n1.EXE"
Echo.&Echo Successed!
POPD
GOTO :Eof
实例:XP扫雷雷区查看器(http://www.bathome.net/thread-45155-1-1.html)
页:
[1]