Solved

API for reading memory

Posted on 1997-06-16
11
476 Views
Last Modified: 2006-11-17
I am writing a program that that uses API calls to store a large file in a Allocated Chunk of memory.  How can I retrieve data from this chunk and store it back in to an array.
0
Comment
Question by:stephaner
  • 5
  • 3
  • 3
11 Comments
 
LVL 7

Expert Comment

by:tward
ID: 1427313
What is the function you are using to put it in memory?
0
 

Author Comment

by:stephaner
ID: 1427314
Here is a copy of the subroutine.  This subroutine is part of a class.


Public Sub Load()
  Dim FileSize As Long      'Used to store the file size
  Dim hFile As Long         'Used as a handle to the File
  Dim retval As Long        'Used as generic return value
  Dim lpBytesread As Long   'Used by Api(ReadFile)
 

   
  'Get the size of the file
    FileSize = FileLen(FileName)

  'Verify that the file is not zero length.
    If FileSize > 0 Then

      'Allocate a block of memory equal to the size of the input file.
        mlng_HandleMemory = GlobalAlloc(GMEM_ZEROINIT, FileSize)
       

        'Verify that the allocation succeded
          If mlng_HandleMemory <> 0 Then

            'Lock newly allocated memory
              mlng_MemoryAddress = GlobalLock(mlng_HandleMemory)
         
             
            'Open the File
              hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, ByVal 0&)
             
                       
            'Read File into Memory
              retval = lread(hFile, ByVal mlng_MemoryAddress, FileSize)
         
                           
            'Close the File
              retval = CloseHandle(hFile)
....
         
                           
0
 
LVL 7

Expert Comment

by:tward
ID: 1427315
Try the following API call:

Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

Here is an explanation of the function:

The ReadProcessMemory function reads memory in a specified process. The entire area to be read must be accessible, or the operation fails.
BOOL ReadProcessMemory(
    HANDLE hProcess,      // handle of the process whose memory is read  
    LPCVOID lpBaseAddress,      // address to start reading
    LPVOID lpBuffer,      // address of buffer to place read data
    DWORD nSize,      // number of bytes to read
    LPDWORD lpNumberOfBytesRead       // address of number of bytes read
   );      
 
Parameters
hProcess
Identifies an open handle of a process whose memory is read. The handle must have PROCESS_VM_READ access to the process.
lpBaseAddress
Points to the base address in the specified process to be read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access. If this is the case, the function proceeds; otherwise, the function fails.
lpBuffer
Points to a buffer that receives the contents from the address space of the specified process.
nSize
Specifies the requested number of bytes to read from the specified process.
lpNumberOfBytesRead
Points to the actual number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.
 
Return Values
If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
The function fails if the requested read operation crosses into an area of the process that is inaccessible.
Remarks
ReadProcessMemory copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call the function. The process whose address space is read is typically, but not necessarily, being debugged.
The entire area to be read must be accessible. If it is not, the function fails as noted previously.

0
 
LVL 7

Expert Comment

by:tward
ID: 1427316
Also note that after you are done with the memory you need to do a GlobalUnlock which I don't see in your above code.
0
 

Author Comment

by:stephaner
ID: 1427317
I am not sure how to put my class together using this function.  Maybe a little background on what I am trying to achieve would help.
My class is used for bitmap manipulation and display.  The idea is that I would have a load function which copies the whole file into memory.  Then I could implement functions to read and dissect the data such as getting the BitmapHeadears, Bitmapdata, ShowBitmap, SaveBitmap.  It seems that since I will be accessing this data often, it would be faster to do it this way than simply reading the data from the file every time I need it.

It is for this reason that there is no call to unlock the memory as this would be done in the Save routine.

Also I have implemented this save routine, although it does copy data back into a file (using lwrite),  the data does not correspond with the original copy of it.

Is it that my approach to the problem is inadequate, or unrealizable?

0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:stephaner
ID: 1427318



0
 
LVL 5

Accepted Solution

by:
y96andha earned 100 total points
ID: 1427319
Use the RtlMoveMemory function.

Example to copy 400 bytes of data starting with position 20 in the memory chunk, and to put these bytes back at position 1024 in the memory chunk:

Declare Sub MoveMemory1 Lib "kernel32"  Alias "RtlMoveMemory" (Byval dest as String, Byval src as Long, Byval bytes as Long)

Declare Sub MoveMemory2 Lib "kernel32"  Alias "RtlMoveMemory" (Byval dest as Long, Byval src as String, Byval bytes as Long)

Dim data as String
data=String(400,0)
CopyMemory1 data, mlng_MemoryAddress+20, 400

CopyMemory2 mlng_MemoryAddress+1024, data, 400



Please comment if you have any questions.

0
 

Author Comment

by:stephaner
ID: 1427320
I could not find the above declrations in the API file.  Do you no why?  Also right now I am using "agCopyData" to perform this task. However, this does not allow me to read in anything other than a string.  I would like to be able to read in directly other data types such as Intgers and Longs.  Would your functions allow for this?
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427321
Yes, they would. All you have to do is to make sure that the declaration passes pointers as the first two arguments and a length as the last. To read a Long, you would make a declaration like this:

Declare Sub MoveMemory3 Lib "kernel32" Alias "RtlMoveMemory" (dest as Long, Byval src as Long, Byval bytes as Long)

Dim data as Long
MoveMemory3 data, mlng_MemoryAddress+47, Len(data)


Notice that there is no ByVal on the first argument, which makes  VB take its address and pass it to the DLL function.

I do not know why the declaration is not in the API file. Maybe because VB isn't made for using pointers. Do you know if there is any instruction in VB to get the address of a certain variable? Anyway, I got the declaration from my C++ compiler, so it should work.

I cannot find a declaration for agCopyData either.

0
 

Author Comment

by:stephaner
ID: 1427322
Ok, I was able to make it work for the following types: Byte, String, Integer, Long.  However I still need to know what the declare would be for an array of bytes? a UDT?  Also I had to modify each declare depending on the type.  Is there a way to have only one declare that fits all?

"agCopydata" is part of a lib called "ApiGid32.dll"
This lib contans the functions you mentioned such as:
agGetAddressForObject, gGetAddressForInteger, agGetAddressForLPSTR
and other usefull functions.  For more inforrmation on this lib:
"www.desare.com"
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427323
I do not know for an array of bytes. I have a student version of VB, which means I do not have a manual, just a CD. I think that you should pass the first byte. UDT= User Defined Type? In that case, it will work just like Byte, Integer, Long and so on.

To make a declare fit all, you should use

Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (dest as Any, src as Any, Byval bytes as Long)

This should enable you to specify whatever type you'd like. It could be that you still need need to specify the pointer address, that is, the mlng_MemoryAddress part as "ByVal xxx as Long".

On the other hand, if you can get the address for any data type, then you can use

Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest as Long, ByVal src as Long, Byval bytes as Long)

and just pass in the addresses.


0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now