# FreeLibrary bug becomes a PE packers bug

there is a way to find out if a program was packed or not. XP/S2K3 has a bug that has to be taken into account unless a packer wants to crash a packed program.

FreeLibrary() does not unload statically linked libraries, but frees dynamically linked ones. consider the following code. it should work. at least it works on XP/S2K3 (W2K is a bug free):

// get USER32 module handle
HANDLE h; h = GetModuleHandle(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h); FreeLibrary(h);

// time to unload

// call any function from statically linked USER32

ok, now remove USER32 from the import table and load it on the fly.

// load USER32 and get the module handle
HANDLE h; h = LoadLibrary(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h);FreeLibrary(h);

// time to unload

// call any function from dynamically linked USER32
(int (WINAPI *)(int, char*, char*, int)) GetProcAddress(h,”MessageBoxA”)(0, “:-)”, “[x]“, 0);

wow! the program crashes!!! interesting… but… it has nothing to do with packers! um, actually it has. some packers (and especially protectors) leaves only KERNEL32.DLL there and loads the rest on the fly.

guess, we have a file with statically linked libraries. guess, the program frees one or more libraries doing it deliberately or maybe there is a bug. this bug does not appear, coz FreeLibrary not unloads statically linked DLLs. imagine what happens if we pack the file by packer removes all DLL from the import table? the answer: the program will crash!!!

download the POC (original exe and file packed by RLPack) and test your packer/protector collection.



  1. zarulshahrin

    Ermmm… Try this one:


    int main()
    HANDLE h;

    h = LoadLibrary(“USER32.DLL”);

    (int (WINAPI *)(int, char*, char*, int)) GetProcAddress(h,”MessageBoxA”)(0, “Test 1″, “Test 1″, 0);

    FreeLibrary(h); FreeLibrary(h); FreeLibrary(h);


    (int (WINAPI *)(int, char*, char*, int)) GetProcAddress(h,”MessageBoxA”)(0, “Test 2″, “Test 2″, 0);
    return 0;

  2. hey Kris,

    when you say, “there is a way to find out if a program was packed or not.”

    you mean from within the running program? what’s the use and why bother?
    and even if needed, there are various self checking techniques to do that.

    btw, soul12 already wrote this, check this link in openrce.rg

  3. I hope I can help in figuring out why it crashs..

    its more then likely somewhat associated with the call’s to GetProcAddress..
    if you remove a dll in the peb but not im memory and a try to dynamically call it using the Ldr functions or things that mimic them aka*GetProcAddress* the whole call has to be reformulated like darawks approach with manual mapping..I also had some code up on the net that was stolen by Spider..unfortunatly I am un able to get a login into that site..I find it most annoying..code is called “Executing Shellcode in Explorer with RtlRemoteCall..”
    it was a previous failed attempt by me..

    As I have done enumerable tests on alot of things coding, including with removing dlls from the PEB and switching modules around in the PEB..I have found these things out the fun and exploritive way..though for you to use that idea in a new and different way I find that is everything that we are and strive to do.. congratulations ;)

    its seems petfairy is onto you to..
    ‘you mean from within the running program? what’s the use and why bother?’ seems to be a Carbon copy response..

    ignore him please!!!and keep up the tireless thoughts ;)

    Regards BanMe

  4. actually I cant say it was stolen Cause I can’t verify if he left my name there or not.. :p

    I so retract that small lapse im my thought process..for now at least.. :)

  5. @banme: dude, please read the post again to understand the context. :-)

    I’m asking question to understand perspective of Kris and not to discourage him, when he wanted to check if his program is packed or not (the one which is has already gotten control and executing currently). what benefit would it provide knowing that it is packed?

    P.S: I’m not Pferrie, Kris knows who i am. :-)

Leave a comment

Comments are closed.