[Win32/C] custom resource vrijgeven uit geheugen

Pagina: 1
Acties:

  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 00:16
In een Win32 programma in C gebruiken drZymo (ook een GoTter) en ik LoadResource om een custom resource uit een DLL te laden. Het betreft hier een certificaat dat bepaalt welke rechten de code in de DLL heeft in het programma. Nu zijn er voor de verschillende GDI resources (bitmaps, icons enz) mooie functies om ze vrij te geven na gebruik, maar voor custom resources is geen functie. MSDN zegt het volgende bij LoadResource:
The system automatically deletes these resources when the process that created them terminates, however, calling the appropriate function saves memory and decreases the size of the process's working set.
Zo'n 'appropriate function' is er dus alleen voor de GDI resources. Google levert ook niks op. Het programma moet echter voor onbepaalde tijd kunnen draaien, en kan ook een willekeurig aantal DLL's voor z'n kiezen krijgen, at runtime. Dit levert dus een ordinair geheugenlek op, want het proces beëindigen om die resources vrij te geven is geen optie. Hiervoor moet dus een andere oplossing komen. Wie weet er een? :P

[ Voor 3% gewijzigd door johnwoo op 31-01-2005 15:56 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • cenix
  • Registratie: September 2001
  • Laatst online: 15-05 15:54
Zoek en gij zult vinden (op MSDN): FreeResource

http://msdn.microsoft.com...eeresource.asp?frame=true

  • drZymo
  • Registratie: Augustus 2000
  • Laatst online: 12-04 13:01
Oplossing heb ik dus net zelf gevonden :D. Ik heb de hele LoadResource functie goed uitgepluisd (met dan aan PE Explorer).

LoadResource werkt als volgt. Zodra een dll met LoadLibrary geladen wordt dan wordt de dll in het geheugen gekopieerd op een standaard locatie (voor mijn test dll was die 0x1000000). Deze locatie krijg je al handle terug van LoadLibrary. Op deze locatie staat dus de complete binary van de dll. LoadResource gebruikt een functie RtlImageDirectoryEntryToData om in die image de specifieke resource op te zoeken en geeft een pointer naar die geheugen plaats terug. Bij mijn test was dit bijvoorbeeld 0x1000A328, en op locatie 0x9238 in het bestand op mijn harddisk stond de resource.

Als de dll nu met FreeLibrary vrij gegeven wordt, dan wordt ook het stuk geheugen waar de image in staat vrij gegeven. De pointer die door LoadResource teruggegeven was, wijst naar naar een plaats in dat stuk geheugen en is dus ongeldig.

Kortom het is niet nodig om geheugen van een custom resource vrij te geven omdat het nooit gealloceert is. Het is gewoon een simpele pointer naar een stuk geheugen wat altijd bestaat zolang de dll geladen is. Het is dus geen extra geheugen wat vrij gegeven moet worden.

Ik hoop dat het zo een beetje helder is. Nu kan ik in ieder geval weer met een gerust hard verder klooien :D.

"There are three stages in scientific discovery: first, people deny that it is true; then they deny that it is important; finally they credit the wrong person."


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 00:16
FreeResource is deprecated en doet helemaal niks.
Een disassembly levert dit op:
code:
1
2
3
FreeResource:
               xor     eax,eax
               retn    0004h


[edit]
En drZymo heeft dus een fout in MSDN gevonden. Volgens MSDN wordt het geheugen pas vrijgegeven als het proces beëindigd wordt, maar het wordt dus in feite al "vrijgegeven" zodra de DLL ontladen wordt.

Waar kunnen we dat terugkoppelen naar MS >:)

[ Voor 22% gewijzigd door johnwoo op 31-01-2005 16:06 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • drZymo
  • Registratie: Augustus 2000
  • Laatst online: 12-04 13:01
Ja helaas dus:
The FreeResource function is obsolete and is only supported for backward compatibility with 16-bit Microsoft Windows.

...

The system automatically deletes these resources when the process that created them terminates. However, calling the appropriate function saves memory and decreases the size of the process's working set. For more information, see LoadResource.

"There are three stages in scientific discovery: first, people deny that it is true; then they deny that it is important; finally they credit the wrong person."


  • drZymo
  • Registratie: Augustus 2000
  • Laatst online: 12-04 13:01
Het is dus een kleine fout in de documentatie. Ipv 'The system automatically deletes these resources when the process that created them terminates. ' moet er dus staan 'The system automatically deletes these resources when the module that contains them is freed.'.

"There are three stages in scientific discovery: first, people deny that it is true; then they deny that it is important; finally they credit the wrong person."


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
De locatie is toevallig 0x1000000; voornamelijk omdat je geen ander adres hebt opgegeven en geen andere DLL op dat adres hebt geladen. Dat is geen algemene garantie - en relevant als je zoals de TS meerdere DLLs wil laden.

De reden voor deze complexiteit is Win16, waar dit soort dingen dikke ellende was - voornamelijk omdat je permanent met segmenten aan het vechten was. Ik kan me goed voorstellen dat ze het met Win32 gewoon hebben laten vallen. Een simpele read is triviaal, in een flat memory model. Er is dus weinig noodzaak meer voor resources, hooguit om je file count wat beperkt te houden.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1