Author Topic: LoadLibrary, GetProcAddress, FreeLibrary  (Read 14408 times)

dedndave

  • Member
  • *****
  • Posts: 8827
  • Still using Abacus 2.0
    • DednDave
LoadLibrary, GetProcAddress, FreeLibrary
« on: November 06, 2015, 05:20:09 AM »
i have a question - can't find the answer in any MSDN document....

1) LoadLibrary
2) GetProcAddress
3) FreeLibrary

is the proc address still valid after FreeLibrary ?
same question - assuming the reference count is not 0
how would i test the answer, either way ?

jj2007

  • Member
  • *****
  • Posts: 10664
  • Assembler is fun ;-)
    • MasmBasic
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #1 on: November 06, 2015, 05:40:10 AM »
Good question. A quick test shows that msvcrt works even after FreeLibrary.

ragdog

  • Member
  • ****
  • Posts: 610
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #2 on: November 06, 2015, 07:26:42 AM »
Quote
Good question. A quick test shows that msvcrt works even after FreeLibrary.

I understand it the handle is not longer valid.

Quote
When the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid

I have make a quick test and Jochen has right .




zedd151

  • Member
  • ****
  • Posts: 871
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #3 on: November 06, 2015, 07:34:47 AM »
It would'nt be very hard to write a small proggy to test whether or not
the handle would still be valid.

BUT you must make certain that no OTHER process (in
the same context as your proggy) is using that handle.

If you try to free the handle while another process is using it, it might not get freed?

That is if I understood my lessons.

Or I could be completely wrong. (Would'nt be the 1st time - lol)
I'm not always the sharpest knife in the drawer, but I have my moments.  :P

ragdog

  • Member
  • ****
  • Posts: 610
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #4 on: November 06, 2015, 08:05:34 AM »
My test was wrong my second works with FreeLibrary the module after FreeLibrary is unload
and this secound call does not works.

Code: [Select]
push chr$ ("printf")
call ebx

Code: [Select]
invoke LoadLibrary,chr$ ("msvcrt.dll")
mov edi,eax
invoke GetProcAddress,eax,chr$ ("printf")
mov ebx,eax
push chr$ ("printf")
call eax
invoke FreeLibrary,edi
push chr$ ("printf")
call ebx

@ Jochen have you forgot to delete the include msvcrt?

TWell

  • Member
  • ****
  • Posts: 748
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #5 on: November 06, 2015, 08:09:21 AM »
I test msvcrt.dll and wprintf.

After FreeLibrary() function pointer was not valid anymore (crash).
Debugger shows that module unloading.

But maybe useful for undocumented API functions.

dedndave

  • Member
  • *****
  • Posts: 8827
  • Still using Abacus 2.0
    • DednDave
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #6 on: November 06, 2015, 08:36:36 AM »
BUT you must make certain that no OTHER process (in
the same context as your proggy) is using that handle.

the handle is unique to the current process
(the module is loaded into the address space of the current process)

the real question is.....

how do you clear out the address space used by the module to make the test   :biggrin:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7633
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #7 on: November 06, 2015, 08:41:27 AM »
Dave, it depends on if the library is normally loaded into memory. If its one of the main system libraries, KERNEL, USER, GDI then you can usually get away with it but with individual DLLs it would be unreliable as they would be dumped from memory in lazy write time scales.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

dedndave

  • Member
  • *****
  • Posts: 8827
  • Still using Abacus 2.0
    • DednDave
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #8 on: November 06, 2015, 08:42:49 AM »
this takes us to the next step....

back in the old forum, we had a discussion about using LoadLibrary vs GetModuleHandle for kernel32.dll
Hutch insisted that we should use LoadLibrary and FreeLibrary
my argument was that kernel32 is always loaded (functions like ExitProcess, etc)

now, we need to know if ExitProcess clears the reference counter - lol

in other words, if i use LoadLibrary to get functions from kernel32
and - don't use FreeLibrary, in order to insure the proc addresses remain valid
will ExitProcess perform a proper clean-up, or do i have a memory leak ?

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7633
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #9 on: November 06, 2015, 08:49:20 AM »
With the system libraries you can LoadLibrary(), GetProcAddress() then immediately call FreeLibrary() which is safe as the system library is still in memory, GetModuleHandle will do it as well without changing the reference counter but an old warning still applies, when Microsoft upgrade OS versions they only have their own documentation as reference so you may get a nasty surprise if you call a function address this way in a later OS version or after an upgrade. (Having been bitten a number of times with this problem, I err on the side of caution).  :biggrin:
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #10 on: November 06, 2015, 08:50:49 AM »
Code: [Select]
H = LoadLibrary( “kernel32.lib” )
P = GetProcAddress( H, “ExitProcess” )
H2 = LoadLibrary( “kernel32.lib” )
P2 = GetProcAddress( H2, “ExitProcess” )
FreeLibrary( H )
FreeLibrary( H2 )
P3 = ExitProcess

if (P == P2 == P3) ...

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7633
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #11 on: November 06, 2015, 09:06:36 AM »
Like this.

Code: [Select]
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    .data?
      pMessageBox dd ?

    .data
      titl db "Msgbox Call",0
      tmsg db "Howdy from the MessageBox address",0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main

    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc


    LOCAL pUser :DWORD

    fn LoadLibrary,"user32.dll"
    mov pUser, eax

    fn GetProcAddress,pUser,"MessageBoxA"
    mov pMessageBox, eax

    fn FreeLibrary, pUser

    push 0
    push OFFSET titl
    push OFFSET tmsg
    push 0
    call pMessageBox

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

Zen

  • Member
  • ****
  • Posts: 962
  • slightly red-shifted
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #12 on: November 06, 2015, 09:32:41 AM »
Raymond Chen has a number of blog entries that are ALMOST relevant to this question,...:bgrin:
...Here's one of them that seems to answer your question: What is the point of FreeLibraryAndExitThread?
This one is even MORE OBTUSE: Why can't I use the linker to delay-load a function from kernel32?
...And, if you want to know everything about LoadLibrary, FreeLibrary that nobody realistically cares about: Why are DLLs unloaded in the "wrong" order?
Zen

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #13 on: November 06, 2015, 09:39:17 AM »
If MyProg loads MyDll, and MyProg loads MyProg as a child you will have two separate instances in memory: [MyProg(1)/MyDll(1)] and [MyProg(2)/MyDll(2)].

I will assume the pointer is only valid (after delete) if you load the dll twice.

Code: [Select]
LoadLibraryA( "kernel32.dll" )
push eax
GetProcAddress( eax, "ExitProcess" )
mov esi,eax
LoadLibraryA( "kernel32.dll" )
push eax
GetProcAddress( eax, "ExitProcess" )
mov edi,eax
FreeLibrary()
FreeLibrary()
printf( "ExitProcess:       %08X\n", ExitProcess )
printf( "GetProcAddress(1): %08X\n", esi )
printf( "GetProcAddress(2): %08X\n", edi )

Code: [Select]
ExitProcess:       00401E98
GetProcAddress(1): 7C81BFA2
GetProcAddress(2): 7C81BFA2

sinsi

  • Guest
Re: LoadLibrary, GetProcAddress, FreeLibrary
« Reply #14 on: November 06, 2015, 10:11:51 AM »
Use FreeLibrary more than once to make sure the reference count is 0 and run hutch's code. The degugger gives me
Code: [Select]
<Unloaded_user32.dll>+0x6fd1e:
7669fd1e ??              ???