win32 programming lesson 20: advanced dll techniques

24
Win32 Programming Lesson 20: Advanced DLL Techniques

Upload: heather-pope

Post on 31-Dec-2015

247 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Win32 Programming Lesson 20: Advanced DLL Techniques

Win32 ProgrammingLesson 20: Advanced DLL Techniques

Page 2: Win32 Programming Lesson 20: Advanced DLL Techniques

Where are we? We’ve looked at DLLs from a

build/link/execute perspective But there are many different tricks you can

use to get more “bang for your buck”

Page 3: Win32 Programming Lesson 20: Advanced DLL Techniques

Explicit DLL Loading To use a DLL, a process must load it We’ve looked at doing this implicitly via load

and runtime and building in the calls Can be done when the application is running

too The beauty of this technique is that you don’t

need to know too much about the DLL at compile time

Page 4: Win32 Programming Lesson 20: Advanced DLL Techniques

Explicit Loading Simple to accomplish via LoadLibrary:

HINSTANCE LoadLibrary(PCTSTR pszDLLPathName);

HINSTANCE LoadLibraryEx(    PCTSTR pszDLLPathName,    HANDLE hFile,    DWORD dwFlags);

HINSTANCE is a pointer to the virtual memory where the DLL is mapped

Page 5: Win32 Programming Lesson 20: Advanced DLL Techniques

Parameters hFile: Reserved for future use – must be

NULL dwFlags: combination of

DONT_RESOLVE_DLL_REFERENCES, LOAD_LIBRARY_AS_DATAFILE, and LOAD_WITH_ALTERED_SEARCH_ PATH

Page 6: Win32 Programming Lesson 20: Advanced DLL Techniques

Implications DONT_RESOLVE_DLL_REFERENCES

Don’t execute DllMain or automatically load other DLLs needed by this one

LOAD_LIBRARY_AS_DATAFILE Useful if you want to load an .exe file without executing

it LOAD_WITH_ALTERED_SEARCH_ PATH

Changes the order in which directories are searched in order to load the DLL

Page 7: Win32 Programming Lesson 20: Advanced DLL Techniques

Explicitly unloading the DLL BOOL FreeLibrary(HINSTANCE

hInstanceDLL); And also:

VOID FreeLibraryAndExitThread(    HINSTANCE hinstDll,    DWORD dwExitCode);

Why? And of course, this is all predicated on usage

counts…

Page 8: Win32 Programming Lesson 20: Advanced DLL Techniques

Other Explicit calls Can check to see if a DLL is already loaded via:

HINSTANCE GetModuleHandle(PCTSTR pszModuleName);

Would use like this: HINSTANCE hinstDll = GetModuleHandle("MyLib"); 

// DLL extension assumed if (hinstDll == NULL) {    hinstDll = LoadLibrary("MyLib");  // DLL extension assumed }

Page 9: Win32 Programming Lesson 20: Advanced DLL Techniques

You can also… Get the full path of a loaded DLL DWORD GetModuleFileName(

   HINSTANCE hinstModule,    PTSTR pszPathName,    DWORD cchPath);

Page 10: Win32 Programming Lesson 20: Advanced DLL Techniques

Second Once a DLL has been explicitly loaded you

need to get the address of the functions you want

FARPROC GetProcAddress(    HINSTANCE hinstDll,    PCSTR pszSymbolName);

Where pszSymbolName is either: The name e.g. “MyFunc” The resource number MAKEINTRESOURCE(2)

Page 11: Win32 Programming Lesson 20: Advanced DLL Techniques

Warning! If you use the name, it can be slow, as you

must search through the names of all exported things

If you use the second function, GetProcAddress can return a non NULL value even though it has failed…

Page 12: Win32 Programming Lesson 20: Advanced DLL Techniques

DLLs (startup) A DLL can have a DllMain function which is

called upon startup This routine isn’t required – you implement it

if you need it Note the name is case sensitive. If you use

DLLMain you’re not going to get called

Page 13: Win32 Programming Lesson 20: Advanced DLL Techniques

Code ExampleBOOL WINAPI DllMain(HINSTANCE hinstDll, 

DWORD fdwReason,  PVOID fImpLoad) {    switch (fdwReason) {       case DLL_PROCESS_ATTACH:          // The DLL is being mapped into the process's address space.          break;       case DLL_THREAD_ATTACH:          // A thread is being created.          break;       case DLL_THREAD_DETACH:          // A thread is exiting cleanly.          break;       case DLL_PROCESS_DETACH:          // The DLL is being unmapped from the process's address space.          break;    }    return(TRUE);  // Used only for DLL_PROCESS_ATTACH }

Page 14: Win32 Programming Lesson 20: Advanced DLL Techniques

hInst hInstance passed in is where the DLL got

loaded – usually stored for later use in a Global

Remember though that when your DllMain is running, other DLLs may not have initialized. Thus, don’t call other DLLs within your DllMain

Page 15: Win32 Programming Lesson 20: Advanced DLL Techniques

Delay-loading a DLL You can opt to delay load an implicitly-linked

DLL Beneficial because:

Faster startup – you can save time initializing DLLs later when you need them

Backward compatibility – you can avoid calling missing functions and handle the error yourself

Page 16: Win32 Programming Lesson 20: Advanced DLL Techniques

Function Forwarding You can forward an exported function from

one DLL to another // Function forwarders to functions in DllWor

k #pragma comment(linker, "/export:SomeFunc=DllWork.SomeOtherFunc") 

Pretty simple eh?

Page 17: Win32 Programming Lesson 20: Advanced DLL Techniques

Known DLLs Life isn’t fair… some DLLs get special

treatment Look at:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

These DLLs always load from the same place

Page 18: Win32 Programming Lesson 20: Advanced DLL Techniques

Version Independence We are all familiar with DLL Versioning

problems Can fix using .local files. If a file called

calc.exe.local exists, for example, in the directory in which calc.exe resides, DLLs are loaded from that directory first

For new systems think about Side-by-Side assemblies (see here)

Page 19: Win32 Programming Lesson 20: Advanced DLL Techniques

Rebasing DLLs When a module loads, it has a preferred base

address it would like to load at However, that address is not always going to

be available If a module is relocated, internal structures

have to be “fixed up” to deal with this new location (why?)

This is slow

Page 20: Win32 Programming Lesson 20: Advanced DLL Techniques

Instead You can use the rebasing tool to modify the

DLLs so that this relocation is done on disk, and not on the fly

Don’t ever ever *ever* rebase system DLLs

Page 21: Win32 Programming Lesson 20: Advanced DLL Techniques

Binding a DLL Similar in some senses to Rebasing Improves performance Saves the system having to fix up the module

import section

Page 23: Win32 Programming Lesson 20: Advanced DLL Techniques

Assignment Not due until April 26th – that’s over two

weeks NO MERCY on people who say on the 19th

“I’m stuck!” This is somewhat tricky I suggest you start work on it immediately… We will look at your code in a week in SVN

and assign some points for what you’ve done

Page 24: Win32 Programming Lesson 20: Advanced DLL Techniques

Calls… I want you to be able to intercept the following Winsock

system calls: connect send recv closesocket

You should be able to launch an arbitrary monitored process (specified on the Command line)

You should be able to display the calls to connect, send, recv and closesocket along with their parameters

Have fun I strongly suggest you read Ch 22.