I have been reading about memory managment in win32,
When we have one dll that is used by two different
programs, and if that dll is not loaded at same linear
(virtual) memory base in both processes then dll is
physicly loaded two different physical memory bases (RAM)
thus we have 2 copies of dll instead of having one.

I dont understand why is this the problem for windows,
why win32 cant just load that dll in RAM and by paging
put reference to that physical memory in 2 different linear
memory addreses in different processes????

for example: we have processes A and B and they use same dll
but in process B prefered address for dll is already commited
so dll must be loaded at some other address
now
process A loads dll at X linear address
process B loads dll at Y linear address

so in RAM dll is loaded at say 10000 and 20000
now why cant windows assign RAM address 10000 to X in process A
and in the same time to Y in process B
i mean what the problem? win only needs to change memory context of two processes..
Posted on 2002-10-05 16:06:47 by Mikky
Wouldn't that mean that both processes uses the same variables (and functions) in the dll, eg process A alters an variable in the dll, then Process B reads the variable. Or process A calls an function, and mean while process B calls the same function at the (same address); that could open a whole new world of possible errors/exceptions/etc. :rolleyes:
Example 1 could be an problem or that could be something that's wanted ( ((in)directly) sharing data between processes).
Posted on 2002-10-05 18:13:23 by scientica
The problem is that the dll in process B should be relocated.
That means that every peace of code that directly references memory should be changed to point at new memory address.
Let's see:
.text:10001027 FF 75 08              push    [ebp+uType]            ; uType

.text:1000102A 68 [b]00 30 00 10[/b] push offset aTestFunction ; lpCaption
.text:1000102F 68 [b]0E 30 00 10[/b] push offset aThisIsDll ; lpText
.text:10001034 6A 00 push 0 ; hWnd
.text:10001036 E8 05 00 00 00 call MessageBoxA


.reloc:10004000 00 10 00 00         dd 1000h            ; Page RVA

. . . . .
.reloc:1000400C 2B 30 dw 302Bh ; Type of reloc = 3, Offset = 2Bh
.reloc:1000400E 30 30 dw 3030h ; Type of reloc = 3, Offset = 30h


Instructions at 1000102A and 1000102F reference memory directly:
push offset 10003000h

push offset 1000300Eh

But it's valid only for ImageBase = 10000000h
If dll is loaded at different address, say 20000000h, the loader needs to look into .reloc section,
and find which addresses should be patched. You can see that we need to patch (bold highlited above):

Page RVA + Offset + ImageBase (see PE-format description for details)

1000h + 2Bh + ImageBase = 1000102Bh
1000h + 30h + ImageBase = 10001030h

We should add offset = NewImageBase - PrefferedImageBase = 20000000h - 10000000h = 10000000h
And after relocating the code looks like this:
.text:20001027 FF 75 08              push    [ebp+uType]            ; uType

.text:2000102A 68 [b]00 30 00 20[/b] push offset aTestFunction ; lpCaption
.text:2000102F 68 [b]0E 30 00 20[/b] push offset aThisIsDll ; lpText
.text:20001034 6A 00 push 0 ; hWnd
.text:20001036 E8 05 00 00 00 call MessageBoxA

And our two instructions at 2000102A and 2000102F reference now right memory addresses:
push offset 20003000h

push offset 2000300Eh

Since the code was patched in second dll but remains the same in first one,
it's not possible to load it at the same physical memory.

Hope it's clear now.
Posted on 2002-10-06 07:06:17 by Four-F
woah.. great response 4-F
it really clears some things up although its still little foggy, i guess i will have to read it tomorow few more times again to get it completly

on the other hand, logicaly i still think that this could be doned without duplicating dll in physical memory... loader relocates memory locations in virtual memory so its not soupose to affect physical memory right?... in the other words windows low level drivers will physicly load dll then windows will say to pe loader
to relocate variables in in process B and after that is doned loader should put references of that relocated variables to points in the same variables as process A...... thus we dont need duplicating

like this


virtual mem | physical mem
-----------------+-------------------
A |
+----------------+-> DLL variable
B (after reloc) |


or blah... sorry if i am talking nonsences maybe i have not readed all needed stuff to completly understand all this, but i wroted this by logic thinking
Posted on 2002-10-06 16:49:31 by Mikky
loader relocates memory locations in virtual memory so its not soupose to affect physical memory right?...
Wrong.
in the other words windows low level drivers will physicly load dll then windows will say to pe loader to relocate variables in in process B and after that is doned loader should put references of that relocated variables to points in the same variables as process A...... thus we dont need duplicating
It's nonsense. Every dll has to have it's own data section. If data section is relocated (placed at different virtual address), all references to it should be changed and it causes patching code section. If dll's code cection is patched in second process but not patched in first one you have two different sections and you can't share it.
Mikky, please read my post above carefully once more. Then make simple prototype and look inside it under debugger.
Posted on 2002-10-07 04:05:12 by Four-F