- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to do some "dumb" multi-threading..
Is it possible for process 1 (say, console, fortran windows, etc), to directly access the memory space of independently running process 2?
in the simplest scenario, use p=loc(A) in process 2, and then use a Cray pointer in process 1 to access memory address p.
with the transfer of p between the processes done manually, or through some other interaction (thats the easy part).
At the moment I am (unsurprisingly) getting memory access violation. I realize this is to protect the user (myself), but is there some (safe) way around it?
Is it possible for process 1 (say, console, fortran windows, etc), to directly access the memory space of independently running process 2?
in the simplest scenario, use p=loc(A) in process 2, and then use a Cray pointer in process 1 to access memory address p.
with the transfer of p between the processes done manually, or through some other interaction (thats the easy part).
At the moment I am (unsurprisingly) getting memory access violation. I realize this is to protect the user (myself), but is there some (safe) way around it?
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the windows SDK have a look at the API's around memory-mapped files and how you use them to implement shared memory. Possibly dodgy fortran example attached.
Yin.F90
Yang.F90
Beyond that I suspect that you are into things like remote code injection and use of the debugging api's. That's all arcane witchcraft to me. Others may know better.
IanH
(Edit to fix embarrasing omission and subsequent error in files).
Yin.F90
Yang.F90
Beyond that I suspect that you are into things like remote code injection and use of the debugging api's. That's all arcane witchcraft to me. Others may know better.
IanH
(Edit to fix embarrasing omission and subsequent error in files).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What are you trying to pass around? Is it just variable values?
if this is the case, using the COM wizard may help - typically one process must control the other, or (which we did with a similar problem) you have a third program which has the responsibility for running both & marshalling information between the other two.
This approach is used within the water industry, albeit from a .NET framework for the marshalling program - see OpenMI.org for details.
if this is the case, using the COM wizard may help - typically one process must control the other, or (which we did with a similar problem) you have a third program which has the responsibility for running both & marshalling information between the other two.
This approach is used within the water industry, albeit from a .NET framework for the marshalling program - see OpenMI.org for details.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - bendel boy
What are you trying to pass around? Is it just variable values?
if this is the case, using the COM wizard may help - typically one process must control the other, or (which we did with a similar problem) you have a third program which has the responsibility for running both & marshalling information between the other two.
This approach is used within the water industry, albeit from a .NET framework for the marshalling program - see OpenMI.org for details.
if this is the case, using the COM wizard may help - typically one process must control the other, or (which we did with a similar problem) you have a third program which has the responsibility for running both & marshalling information between the other two.
This approach is used within the water industry, albeit from a .NET framework for the marshalling program - see OpenMI.org for details.
Yes, 'just' variable names. I am trying to have Process 1 accessing (but not modifying) variables (with exactly known addresses) in the image of process 2.
IanH's example above is relatively clear and quite helpful, though ideally I would like the code for Process 2 to remain as "untouched" by the sharing as possible (so that Process 1 does most of the work). I suspect I will eventually need to dubble into the "witchcraft"..
I am only superficially familiar with the COM approach - I will investigate the openMI work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - forall
Yes, 'just' variable names. I am trying to have Process 1 accessing (but not modifying) variables (with exactly known addresses) in the image of process 2.
IanH's example above is relatively clear and quite helpful, though ideally I would like the code for Process 2 to remain as "untouched" by the sharing as possible (so that Process 1 does most of the work). I suspect I will eventually need to dubble into the "witchcraft"..
I am only superficially familiar with the COM approach - I will investigate the openMI work.
Well, there is ReadProcessMemory which is not so witchcraftic (it must be preceded by OpenProcess, and there are numerous ways to get the dwProcessId). It does sound like a cludge though.
On the first sight, this looks like a useful example, but I really didn't enter the details.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Jugoslav Dujic
Well, there is ReadProcessMemory which is not so witchcraftic (it must be preceded by OpenProcess, and there are numerous ways to get the dwProcessId). It does sound like a cludge though.
On the first sight, this looks like a useful example, but I really didn't enter the details.
thanks Jugoslav,
I read the MSDN help and tried to put together the "cludge", but still am getting "memory access violation".
I attach the code below: the idea is to run the client as a console, and then, while it sits on the READ statement, transfer the processID and address of "val" to the other program (running as a separate console). I was hoping to see the value of "val" transfered via the buffer.
I seem to connect to the client process ok (positive handle), but still get a memory access violation on the ReadProcessMemory line..
Did I misunderstand the usage or misspecify some arguments?
Help much appreciated as usual
PS - on a separate note - is there no Fortran syntax highlighting available?
[cpp]!----------------------------------------------------
program client
use IFWIN,only:GetCurrentProcessId
implicit none
! locals
INTEGER(INT_PTR_KIND())::address,ProcessId
integer(4)::val
ProcessId=GetCurrentProcessId()
val=-15
write(*,*)"Value at location of interest:",val
address = LOC(val)
write(*,*)"ProcessId=",ProcessId
write(*,*)"address=",address
write(*,*)"Now, transfer processId and address to the other app"
read(*,*)
endprogram client
[/cpp]
[cpp]!******************************************************************
program main
use IFWIN,only:OpenProcess,CloseHandle,PROCESS_VM_READ,ReadProcessMemory
implicit none
! locals
integer(INT_PTR_KIND())::theirProcessId,theirHandle,theirVarLoc
INTEGER(INT_PTR_KIND())::newVarLoc
integer(4)::valueAtNewVarLoc,nBytesAsked,nBytesGotten
POINTER(newVarLoc,valueAtNewVarLoc)
integer(4)::ok
! Start procedure here
!
! this is to be transferred from the client process
write(*,*)"Enter their processID"
read(*,*)theirProcessId
write(*,*)"Enter their address"
read(*,*)theirVarLoc
! number of bytes to copy into buffer
nBytesAsked=4
! initialise to junk to see what gets changed
theirHandle=-99; ok=-99; nBytesGotten=-99; newVarLoc=-99
! get read access to the client process
theirHandle=OpenProcess(&
dwDesiredAccess=PROCESS_VM_READ,&
bInheritHandle=1,&
dwProcessId=theirProcessId)
write(*,*)"theirHandle=",theirHandle
! copy a piece of memory (at address 'theirVarLoc') of client process
ok=ReadProcessMemory(&
hProcess=theirHandle,&
lpBaseAddress=theirVarLoc,&
lpBuffer=newVarLoc,&
nSize=nBytesAsked,&
lpNumberOfBytesRead=nBytesGotten)
write(*,*)"ok=",ok
! display the value
write(*,*)"valueAtNewVarLoc=",valueAtNewVarLoc
ok=CloseHandle(theirHandle)
! End procedure here
endprogram main
!******************************************************************
[/cpp]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Place a break point on ReadProcessMemory, at break, open Dissassembly window, use Step Into to step through assembly statements to verify arguments are being passed correctly. In this case you want the values of the arguments not the references to the arguments. Check these values against what you expect. Apparently you are on x32 platform. Do not read the dissassembly window text, verify the contents of values being pushed onto stack against what you know (i.e. sign extention problems etc...). Unless you have the MS sources you will not see the source code when you enter ReadProcessMemory, but you can examine the stack for correct values.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - forall
[cpp]! copy a piece of memory (at address 'theirVarLoc') of client process
ok=ReadProcessMemory(&
hProcess=theirHandle,&
lpBaseAddress=theirVarLoc,&
lpBuffer=newVarLoc,&
nSize=nBytesAsked,&
lpNumberOfBytesRead=nBytesGotten)
write(*,*)"ok=",ok
[/cpp]
Hocus, pocus, I think there might be a missing LOC-us. Specifically on the lpNumberOfBytesRead argument - in C land it is declared as being a pointer.
I'm curious as to why you can't use threads to do your multi-threading. Care to share?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - IanH
Hocus, pocus, I think there might be a missing LOC-us. Specifically on the lpNumberOfBytesRead argument - in C land it is declared as being a pointer.
I'm curious as to why you can't use threads to do your multi-threading. Care to share?
Thanks as usual Ian!
Actually as well as broken logic with lpNumberOfBytesRead (but it just meant I was receving the address not the value), it turned out I needed to initialize newVarLoc to something legal (oops..). Not having that done I was getting some crazy chaotic behaviour for a few hrs, but thankfully its mostly sorted and works quite well.
I was also able to writeProcessMemory in direct analogy. A little scary but it works..
The reason I did not want to use more standard multithreading:
a) I am just starting on this kind of coding, so not very familiar with the kinds of options available,
b) I am designing some auxiliary debugging tools (to send variables, mainly large arrays, to procedures independently from the debugged process).
For this to be useful I need to require minimal modification of and direct access to the debugged process, otherwise I might as well just write out everything to a datafile and read it (which of course is simple in principle but requires modifying the debugged code for lots of diagnostic flags/output/etc - feasible but I wanted something more dynamic/automatic, if possible). And of course now I can adjust values during my debugging without restarting the debugged process (which is significant because sometimes I am faced with a bug or bug-like symptom after the code runs for a day, in which case I'd rather not have to re-run the whole thing after a possibly incomplete fix), etc.
With Yugoslav's and your's suggestions I am able to solve my task almost perfectly - the only thing remaining is to get theirVarLoc and array shape automatically from within the debugged code via some kind of macro and send it to a debugging DLL tool - this part would require emulating some of the CAV/IAV functionality and is also quite challenging, probably even impossible just given my knowledge :-( Thankfully even doing this transfer manually is already saving me lots of debugging time.
Perhaps this whole thing is also achievable using threads.. I also agree there might be other better ways of achieving this debugging functionality, but so far its the best I could come up with..
c) I am likely to be soon working with large existing codes and interacting with them. Using read/writeProcessMemory gives me a quick way of checking things "in principle" before rebuilding these large code as multithreaded. Again, maybe there are simpler/better ways, but I dont know any better (yet)..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - forall
Thanks as usual Ian!
Actually as well as broken logic with lpNumberOfBytesRead (but it just meant I was receving the address not the value), it turned out I needed to initialize newVarLoc to something legal (oops..). Not having that done I was getting some crazy chaotic behaviour for a few hrs, but thankfully its mostly sorted and works quite well.
I was also able to writeProcessMemory in direct analogy. A little scary but it works..
The reason I did not want to use more standard multithreading:
a) I am just starting on this kind of coding, so not very familiar with the kinds of options available,
b) I am designing some auxiliary debugging tools (to send variables, mainly large arrays, to procedures independently from the debugged process).
For this to be useful I need to require minimal modification of and direct access to the debugged process, otherwise I might as well just write out everything to a datafile and read it (which of course is simple in principle but requires modifying the debugged code for lots of diagnostic flags/output/etc - feasible but I wanted something more dynamic/automatic, if possible). And of course now I can adjust values during my debugging without restarting the debugged process (which is significant because sometimes I am faced with a bug or bug-like symptom after the code runs for a day, in which case I'd rather not have to re-run the whole thing after a possibly incomplete fix), etc.
With Yugoslav's and your's suggestions I am able to solve my task almost perfectly - the only thing remaining is to get theirVarLoc and array shape automatically from within the debugged code via some kind of macro and send it to a debugging DLL tool - this part would require emulating some of the CAV/IAV functionality and is also quite challenging, probably even impossible just given my knowledge :-( Thankfully even doing this transfer manually is already saving me lots of debugging time.
Perhaps this whole thing is also achievable using threads.. I also agree there might be other better ways of achieving this debugging functionality, but so far its the best I could come up with..
c) I am likely to be soon working with large existing codes and interacting with them. Using read/writeProcessMemory gives me a quick way of checking things "in principle" before rebuilding these large code as multithreaded. Again, maybe there are simpler/better ways, but I dont know any better (yet)..

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page