DLL

dll建立的時候必須在linker加上 /DLL 讓OS知道

address space分兩種
inplicit load-time &

DLL & process addr space
DLL function looks at a threads stack to retrieve its passed parameter and use thread stack for any local variable that it needs.

common error:
有些是c++ runtime而非dll ,在free的時候要注意

VOID EXEFunc() {
   PVOID pv = DLLFunc();
   // Access the storage pointed to by pv...
   // Makes no assumptions about C/C++ run-time heap
   DLLFreeFunc(pv);
}

PVOID DLLFunc() {
   // Allocate block from DLL's C/C++ run-time heap
   PVOID pv = malloc(100);
   return(pv);
}

BOOL DLLFreeFunc(PVOID pv) {
   // Free block from DLL's C/C++ run-time heap
   return(free(pv));
}

__declspec(dllexport)
會把dll內的function列出,產生.rba檔去對照位置

When the DLL is linked, the linker detects this embedded information about the exported variable, function, or class and automatically produces a .lib file. This .lib file contains the list of symbols exported by the DLL. This .lib file is, of course, required to link any executable module that references this DLL's exported symbols. In addition to creating the .lib file, the linker embeds a table of exported symbols in the resulting DLL file. This export section contains the list (in alphabetical order) of exported variables, functions, and class symbols. The linker also places the relative virtual address (RVA), indicating where each symbol can be found in the DLL module.

Using the Microsoft Visual Studio DumpBin.exe utility (with the -exports switch), you can see what a DLL's export section looks like. The following is a fragment of Kernel32.dll's export section. (I've removed some of DUMPBIN's output so that it won't occupy too many pages in this book.)

C:\Windows\System32>DUMPBIN -exports Kernel32.DLL

Microsoft (R) COFF/PE Dumper Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file Kernel32.DLL

File Type: DLL

  Section contains the following exports for KERNEL32.dll

    00000000 characteristics
    4549AD66 time date stamp Thu Nov 02 09:33:42 2006
        0.00 version
           1 ordinal base
        1207 number of functions
        1207 number of names

    ordinal hint RVA      name

          3    0          AcquireSRWLockExclusive (forwarded to
                          NTDLL.RtlAcquireSRWLockExclusive)
          4    1          AcquireSRWLockShared (forwarded to
                          NTDLL.RtlAcquireSRWLockShared)
          5    2 0002734D ActivateActCtx = _ActivateActCtx@8
          6    3 000088E9 AddAtomA = _AddAtomA@4
          7    4 0001FD7D AddAtomW = _AddAtomW@4
          8    5 000A30AF AddConsoleAliasA = _AddConsoleAliasA@12
          9    6 000A306E AddConsoleAliasW = _AddConsoleAliasW@12
         10    7 00087935 AddLocalAlternateComputerNameA =
                          _AddLocalAlternateComputerNameA@8
         11    8 0008784E AddLocalAlternateComputerNameW =
                          _AddLocalAlternateComputerNameW@8
         12    9 00026159 AddRefActCtx = _AddRefActCtx@4
         13    A 00094456 AddSIDToBoundaryDescriptor =
                          _AddSIDToBoundaryDescriptor@8
        ...
       1205  4B4 0004328A lstrlen = _lstrlenA@4
       1206  4B5 0004328A lstrlenA = _lstrlenA@4
       1207  4B6 00049D35 lstrlenW = _lstrlenW@4

  Summary

        3000  .data
        A000  .reloc
        1000  .rsrc
        C9000 .text

As you can see, the symbols are in alphabetical order and the numbers under the RVA column identify the offset in the DLL file image where the exported symbol can be found. The ordinal column is for backward compatibility with 16-bit Windows source code and should not be used in modern-day applications. The hint column is used by the system to improve performance and is not important for our discussion.

Delay load Dll

delayLoadInfo會在意外產生的時候產生, 會告訴你dll name跟function name

可藉由此結構知道錯誤在哪裡

或者用DelaoLoadDllExceptionFilter, 可用getExceptioninformation拉資料

他會取得資料丟到delayLoadinfo結構, 判斷例外種類做處理(dll不見或是function沒有)

可以在不用時候 unload, 在linker內做設定 support unload

呼叫unload delay load的時候,要確定你有設定他為delay load不然會找不到dll

請一組使用

使用上路徑必須有case sensitive, 且不得有path

free lib也會幫你處理, 請勿自行來

如何掌握delay load的進度?

在delayImp.lib內定義兩個全域變數, 可觀察進度跟失敗

Windows Via C/C++ - Books24x7

PfnDliHook __pfnDliNotifyHook2  = DliHook;
PfnDliHook __pfnDliFailureHook2 = DliHook;

DliHook是你的function, 會不停地幫你callback進去

裡面可以判斷每個狀況

case dliStartProcessing:
case dliNotePreLoadLibrary:
case dliFailLoadLib:
case dliNotePreGetProcAddress
case dliFailGetProc:
case dliNoteEndProcessing:

Forwarding

Windows Via C/C++ - Books24x7

C:\Windows\System32
>
DumpBin -Exports Kernel32.dll      
(some output omitted)

75   49    CloseThreadpoolIo (forwarded to NTDLL.TpReleaseIoCompletion)
76   4A    CloseThreadpoolTimer (forwarded to NTDLL.TpReleaseTimer)
77   4B    CloseThreadpoolWait (forwarded to NTDLL.TpReleaseWait)
78   4C    CloseThreadpoolWork (forwarded to NTDLL.TpReleaseWork)

(remainder of output omitted)

後面才是真正用的dll & function

用法:

You can take advantage of function forwarders in your DLL module as well. The easiest way to do this is by using a pragma directive, as shown here:

// Function forwarders to functions in DllWork
#pragma comment(linker, "/export:SomeFunc=DllWork.SomeOtherFunc")

已知的DLL:

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

Value name: SomeLib
Value data: SomeOtherLib.dll

如果今天用loadLibrary, 檔案名稱如果有副檔名, 會先用檔名去reg內搜尋

LoadLibrary(TEXT("SomeLib.dll"));

假如沒有, 就會依照原本的規則: 檔案目錄, 系統目錄

LoadLibrary(TEXT("SomeLib"));

Dll redirect:

建議大家再肚子裡放.exe.local , 但預設是關著的

SuperApp.exe.local.

Rebased modules

可執行黨: 0x00400000

dll module: 0x10000000

假如用到兩個dll, 位置會重疊,所以如何錯開?

在多個module下要指定不同的base adr, 可以在link底下的base address自行設定

也可以用tool幫忙, rebase.exe

他會先模擬module load進來後的情況. 需要給base adr跟大小, 就會幫你錯開並更改machine code, 就要更新每個header file

例如: 我要load兩個dll, 兩人prefer base adr相同, 用tool把兩者load近來,錯開

再把machine code改掉, 回存

建議在安裝的時候做處理

在vista以後已被修改

https://en.wikipedia.org/wiki/Security_and_safety_features_new_to_Windows_Vista#Preventing_exploits

"Starting with Windows Vista, Microsoft implemented Address Space Layout Randomization

which moves the system DLLs around every time you load them, and optionally the user DLLs as well."

https://blogs.msdn.microsoft.com/oldnewthing/20170118-00/?p=95205

Bind.exe

RVA: 每個的offset 在寫回file name, 讓loading的時候不用重新計算

效果會如下面這段, 可在初始化的時候避免消耗資源

  Bound to SHELL32.dll [4549BDB4] Thu Nov 02 10:43:16 2006
  Bound to ADVAPI32.dll [4549BCD2] Thu Nov 02 10:39:30 2006
  Bound to OLEAUT32.dll [4549BD95] Thu Nov 02 10:42:45 2006
  Bound to ole32.dll [4549BD92] Thu Nov 02 10:42:42 2006
  Bound to ntdll.dll [4549BDC9] Thu Nov 02 10:43:37 2006
  Bound to KERNEL32.dll [4549BD80] Thu Nov 02 10:42:24 2006
  Bound to GDI32.dll [4549BCD3] Thu Nov 02 10:39:31 2006
  Bound to USER32.dll [4549BDE0] Thu Nov 02 10:44:00 2006
  Bound to msvcrt.dll [4549BD61] Thu Nov 02 10:41:53 2006

results matching ""

    No results matching ""