Duda sobre valores de la memoria!!!

Iniciado por WILMER5, 7 Septiembre 2008, 19:04 PM

0 Miembros y 1 Visitante están viendo este tema.

WILMER5

Holas amigo estoy haciendo un pequeño programa en visual bsic 6.0 donde quiero modificar valores de la memoria en tiempo de ejecución, por ejemplo el programa selecciona un proceso y en una direccion de memoria leer y guardar valores, soy un poco novato en esto pero ya he avanzado un poco... para valores de 1,2 y 4 byte ya lo se hacer de esta manera:

Esta es la funcion que uso para leer valores y me funciona perfecto

Public Function ReadLong(Offset As Long, ProcessID As Long) As Long
Dim ProcessHandle As Long
Dim Value As Long
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID)
If ProcessHandle = 0 Then
MsgBox "No se encuentra el proceso", vbCritical, "Error de Lectura"
Exit Function
End If
ReadProcessMem ProcessHandle, Offset, Value, 4, 0&
ReadLong = Value
CloseHandle ProcessHandle
End Function


Esta es la funcion que uso para escribir valores.

Public Function WriteLong(Offset As Long, ProcessID As Long, Value As Long) As Boolean

Dim ProcessHandle As Long
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID)
If ProcessHandle = 0 Then
MsgBox "No se encuentra el proceso", vbCritical, "Error de Lectura"
Exit Function
End If
WriteProcessMemory ProcessHandle, Offset, Value, 4, 0&
CloseHandle ProcessHandle
End Function


ahora lo que me gustaria saber es como leer y guardar valores de Array de Byte

Por ejemplo:

en la dirección de memoria &H353BD7C0 guardar los siguientes valores, esto es un array de 96 bytes...

28 79 3D 35 00 00 00 00 2C 79 3D 35 00 00 00 00 48 BB 3B 35 01 00 00 00 4C 79 3D 35 01 00 00 00 DC 75 2F 35 58 93 2D 35 A4 04 00 00 F8 BE 3B 35 70 A3 0F 35 C0 A0 0F 35 D0 A0 0F 35 E0 A0 0F 35 00 A1 0F 35 10 A1 0F 35 20 A1 0F 35 F0 A0 0F 35 01 00 00 00 FF FF FF FF 30 A6 0F 35 58 93 2D 35

Acotación: Cada bloque de memoria tiene 16 posiciones, para 4 posiciones ya lo se modificar con la funcion que puse. de todos modos adjunto una imagen de referencia para explicarme mejor.



Muchas Gracias por leer mi pregunta espero que puedan ayudarme!!!


...........

http://msdn.microsoft.com/en-us/library/ms681674.aspx
Entre los parámetros de esa función tienes:

lpBuffer

    Puntero al buffer que contiene los datos que se van a escribir.

nSize

    Número de bytes que se van a escribir.

Pues simplemente especifica el número de bytes que quieras. En tu ejemplo tienes 4, pues cambia ese 4 por un 96, y en "Value" debes tener esos 96 bytes como un array.

Igual no entiendo muy bien tu pregunta, porque me extraña que no lo hayas visto por ti mismo.

WILMER5

ya lo habia intentando el igual no funciona, la funcion es solo para leer y escribir solo 4 bytes, y no hallo la manera de que me lea los 16 que quiero, como explique en el tema, con la funcion solo leo y modifico 4 bytes, pero cada bloque de memoria tiene 16 bytes, para poder escribir el array de bytes se necesita ocupar 6 bloques de memoria de 16 bytes cada uno, al poder modificar uno me imagino yo que lo demas seria mas facil, pero ay es donde esta mi duda, como hacer para que lea y escriba los 16 bytes de cada bloque de memoria!!!

De todos modos Gracias por responder,

...........

No sé de donde has sacado la conclusión de que la memoria se divide en bloque de 16 bytes, pero no es así. Los dump de memoria como el de la imagen de Olly suelen tener 16 bytes en cada línea por ser una forma conveniente de mostarlo, pero nada más. Esas APIs leen/escriben cualquier número de bytes en la memoria del proceso, siempre y cuando dicho segmento tenga los permisos adecuados.

byebye

aparte que en "value" no  almacenaras 16 bytes.

WILMER5

Cita de: susanalic en  8 Septiembre 2008, 18:10 PM
No sé de donde has sacado la conclusión de que la memoria se divide en bloque de 16 bytes, pero no es así. Los dump de memoria como el de la imagen de Olly suelen tener 16 bytes en cada línea por ser una forma conveniente de mostarlo, pero nada más. Esas APIs leen/escriben cualquier número de bytes en la memoria del proceso, siempre y cuando dicho segmento tenga los permisos adecuados.

digo que se divide en 16 byte porque asi me lo muestra el programa, en el post creo que aclare que soy novato en esto, y que el avance que tuve fue de modificar solo 4 byte los primero cuatro, como cada linea tiene 16, me imagine que al poder leer y escribir los 16 bytes de esa direccion de memoria, pordria hacer lo mismo con las otras!!!

en la funcion que coloque dice que lleen 4 byte pero al colocar 16 me muestra error!!! ademas cuando colo un valor mayor a 4, por ejemplo 5,6,7,8 me muestra el mismo valor como si colocara 4... y ay es donde esta mi mayor duda, si alguien ya lo ha hecho o tiene alguna funcion de ejemplo espero que por favor la publique o me guie a realizarla, ojo: no estoy pidiendo a nadie que me haga nada solo un poco de ayuda a gente con experiencia en esto para poder hacer la cosas!!!!

byebye

esq como te digo la variable value es de tipo long, ahi no almacenaras 16 bytes.

mirate bien los tipos de datos.

WILMER5

Cita de: ®® en  8 Septiembre 2008, 23:04 PM
esq como te digo la variable value es de tipo long, ahi no almacenaras 16 bytes.

mirate bien los tipos de datos.

tambien probe cambiando las declaraciones de las funciones y de las variables y
tampoco me funciono, me sigue leyendo como maximo 4 bytes.!!!

...........

#8
Estuve jugando un poquito y vi que VB almacena los elementos de un array de forma peculiar:
http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495

Entonces, para obtener un puntero al primer elemento de un array de bytes, tienes que usar: VarPtr(MiArray(0)).

"Value" sí es un Long, ya que es un puntero al inicio del array.

He hecho un miniprograma que escribe 5 bytes en la dirección 403000 del propio proceso (inicio del segmento de datos):

EL VISUAL BASIC SE CIERRA AL EJECUTARLO, NI IDEA PORQUÉ,  PERO EL PROGRAMA FUNCIONA PERFECTAMENTE

Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
----------------------------------------------------------------------------------------------

Private Function WriteMemory(ByVal Offset As Long, ByVal ProcessID As Long, ByVal Value As Long, ByVal NumBytes As Long) As Boolean

Const PROCESS_VM_OPERATION As Long = &H8
Const PROCESS_VM_WRITE As Long = &H20

Dim ProcessHandle As Long
ProcessHandle = OpenProcess(PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, False, ProcessID)

If ProcessHandle = 0 Then
    MsgBox "No se encuentra el proceso", vbCritical, "Error de Lectura"
    Exit Function
End If

Dim exito As Boolean
exito = WriteProcessMemory(ProcessHandle, Offset, Value, NumBytes, 0)

CloseHandle (ProcessHandle)

WriteMemory = exito

End Function

---------------------------------------------------------------------------------------------

Private Sub Form_Load()

Dim MiArray(4) As Byte
MiArray(0) = &H11
MiArray(1) = &H22
MiArray(2) = &H33
MiArray(3) = &H44
MiArray(4) = &H55

Dim exito As Boolean
exito = WriteMemory(&H403000, GetCurrentProcessId(), VarPtr(MiArray(0)), 5)

End Sub





.
.
.
.
.
.

Si ahora queremos leer esos mismos 5 bytes:


Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
--------------------------------------------------------------------
Private Function ReadMemory(ByVal Offset As Long, ByVal ProcessID As Long, ByVal NumBytes As Long) As Byte()

Dim ProcessHandle As Long
Dim Value As Long
Dim ArrayLeer() As Byte
ReDim ArrayLeer(NumBytes)
Value = VarPtr(ArrayLeer(0))
Const PROCESS_VM_READ As Long = &H10

ProcessHandle = OpenProcess(PROCESS_VM_READ, False, ProcessID)

Dim exito As Boolean
exito = ReadProcessMemory(ProcessHandle, Offset, Value, NumBytes, 0)

CloseHandle ProcessHandle

ReadMemory = ArrayLeer

End Function
---------------------------------------------------------------------------
Dim leer() As Byte
leer = ReadMemory(&H403000, GetCurrentProcessId(), 5)

Dim i As Long
Dim texto As String
For i = 0 To 4
   texto = texto & Hex(leer(i))
Next
MsgBox (texto)





WILMER5

Susalic estoy eternamente agradecido contigo, muchas gracias por ayudarme, lo probe y me funciona a la perfección, no solo para 5 bytes sino para los que quiera... me quito el sombrero ante ti, y una vez más Gracias!!!