You can get the currently-logged-in user without sharibg memory; this can
be obtained from the process handle.
You will have serious problems mapping the heap into your address space,
because you will never know when it is stable. There is no way to
synchronize your monitoring program’s access to the heap with the target
process’s access to te heap, and, since the heap is expanding in multiple
discontiguous sets of pages, one mapping won’t do it, and there’s no good
way to notice that the heap has been extended. The heap is NOT implmented
as a single, contiguous block of pages.
You could also implement interprocess messaging to query know values;
trying to decrypt critical information from a heap, even if it were a
single block of contiguous pages, requires far more magic than could be
sensible. I’ve had the misfortune to have to debug heap problems using a
debugger to explore the heap, and I cannot imagine having to write code
that did what I did.
There are major problems in dealing with pointers, which often do not
point into the heap (for example, string literals are pooled in the code
segment). And if you have a structure you want to read, you have no idea
if you are getting consistent data. Consider something as simple as an
array or vector. Your app calls “qsort” on it. Your monitoring app has
no way to know this, so what it sees at any given instant may be a
partially-correct structure which is in te middle of being sorted, and may
have an element missing entirely, or have two pointers to the same
element. And those are just the simplest of the failure modes. Without
an inter-process synchronization mechanis to protect the heap (nearly
impossible to implement correctly), your monitoring process cannot be
expected to work correctly.
Note also that the block of memory will map into your process with a start
address quite different than the address in the target. There is no way
to force it to map at a specific address (and you would still have to map
the multiple discontiguos heap segments, and if you had a pointee, you
would, in effect, have to map it to a block-relative address, then, in
your monitoring app, convert it to a true 32/64-bit address in your
monitoring process’s address space. You would have to know which of the
many discontiguous heap blocks it referred to, convert it relative to that
block’s offset, and then, knowing the block, convert it back to an address
in your process’s address space.
While all this is doable, you end up in te Turing Tarpit, in which all
things are possible if you know every single problem, but ultimately
nothing is easy.
n
So explain how being able to examine the heap can be done in a thread-safe
fashion, and how you anticipate that reading (but not modifying) it can
convey useful information in a way that, as I said above, can improve its
uptime.
I’ve engineered several “non-stop” systems in my career, and I find it
hard to understand how looking at the heap can help. In fact, in all my
recovery code, I had to treat the heap as “damaged goods” and simply reset
it to have all elements free and re-create the strucures “from scratch”,
and retrieve necessary state from the transactions on the disk (in a set
of fies) or state in its co-process, or, in one case, in metadata I stored
in te kernel (since I “owned” both the kernel component and the
application (neither f which I had created) it was easy for me to add the
necessary IOCTLs to the kernel to set and get the metadata). In the
co-process model, a graceful shutdown of either component sent a “I’m
going away” message to its partner. Each partner could restart te other.
Each also waited on the process handle of its partner. When this broke
loose, the rocess would signal all of the components, “Daddy gone bye-bye”
for te secondary process and “Child ran away” was broadcast to various
components of the primary process. A photo of the process was put on a
milk carton (“Have you sseen this process?”) and the parent process
restarted its child. If the parent process failed abruptly, the child
process went to the nice men in blue coats, who took it to their station,
bought it ice cream, and waited for the parent to restart. Again, each
coud do this without knwing anything about the other’s heap. So I am very
suspicious about why this mapping is necessary, and why you think it is
even doable, and what you hope to get from it. I think a much simpler
mechanism might solve the same problem, which we still don’t know.
joe
How does examining the heap improve the reliability of the target program
and thus increase its uptime? I have managed to create service code
thatsimply couldn’t fail without once needing to consult the heap, even
from within the process. The code had a “hard failure” (unrecoverable
error, typically a memory access error) at least once a day–we could only
explain it when examining the dumps by postulating transient memory
failure–but when I finished the rewrite, no one ever knew that such
failures happened; it was “self-healing”.
The techniques I describe will not give you access to the heap, but I
believe that such access is probably unnecessary, and probably impossible
to do “right”. In one case, I had two mutually-dependent processes, and
if either oe failed, the other knew how to restart it and re-create all
necessary state in its companion. Again, if it failed (turns out there
was a bug in a third-party library that they said was too hard to fix),
the users never really saw the failure; the GUI component might disappear
for 30 seconds, but when it cameback it had all the same windows up, and
they contained all the data they had previously contained; if the crash
happened in the middle of a transaction, it treated it as a true
“transaction”, that had either been committed or rolled back. All done by
interprocess message protocols.
First, let me thank everyone for the the kind help.
The purpose of the mapping is for implementing a monitoring process for
security measures over another process. In my scenario I have a very
important process running in the system that should have no downtime
whatsoever. My product scan the target’s memory in order to get out some
internal information from it, such as the user currently logged in, in the
application. This is a security product, not a virus.
From what I was told in personal response to my post, is that when memory
is mapped using MDL, Windows don’t manage the memory in the same way.
I’ll try to refine my question:
Lets say I want to map part of the heap of another process (target
process) to my process (reader process).
Lets also say that this part of the heap is found at virtual address
0x10000 at the target process address space.
I want the same memory to be mapped to the reader process at any virtual
address. I want this memory to keep behaving the same way any other piece
of userland memory is behaving under Windows, which means that if it is
not used for some time neither from the target process nor the reader
process, Windows might or might not choose to page it out as it usually
does. And if it is paged out Windows would page it in at any attempt to
access it from either the reader or the target.
I think that memory mapped file is has about this kind of behavior, I just
want to make memory that is not mapped file to act the same.
Is there a way to do such a thing?
Am I missing something?
NTDEV is sponsored by OSR
OSR is HIRING!! See http://www.osr.com/careers
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer