DLL劫持之IAT类型(Loadlibrary)

Loadlibrary

Loadlibrary的底层是LoadLibraryEx

DLL劫持之IAT类型(Loadlibrary)_第1张图片

第三个参数:

  1. DONT_RESOLVE_DLL_REFERENCES : 这个标志用于告诉系统将DLL映射到调用进程的地址空间中,但是不调用DllMain并且不加载依赖Dll(只映射自己本身)。

  2. LOAD_LIBRARY_AS_DATAFILE : 这个标志与DONT_RESOLVE_DLL_REFERENCES标志相类似,因为系统只是将DLL映射到进程的地址空间中,就像它是数据文件一样。系统并不花费额外的时间来准备执行文件中的任何代码。

  3. LOAD_LIBRARY_SEARCH_USER_DIRS : 搜索路径的使用使用AddDllDirectorySetDllDirectory设置的路径(保护Dll自己和依赖Dll)。

  4. LOAD_LIBRARY_SEARCH_SYSTEM32 : 从%windows%\system32加载Dll和其依赖项。

  5. LOAD_LIBRARY_SEARCH_APPLICATION_DIR : 应用程序安装路径搜索Dll和其依赖项。

  6. LOAD_WITH_ALTERED_SEARCH_PATH: 按照如下目录搜索:

DLL劫持之IAT类型(Loadlibrary)_第2张图片

默认环境下LoadLibrary按照以下目录搜索

DLL劫持之IAT类型(Loadlibrary)_第3张图片

SetDllDirectory函数如下DLL劫持之IAT类型(Loadlibrary)_第4张图片

跟到KernelBaseGetGlobalData

DLL劫持之IAT类型(Loadlibrary)_第5张图片

跟到0环可以发现,在转换之后可以得到路径

DLL劫持之IAT类型(Loadlibrary)_第6张图片

LoadLibraryExW函数原型

DLL劫持之IAT类型(Loadlibrary)_第7张图片

首先通过BaseGetProcessDllPath获取路径,然后调用LdrLoadDll加载dll

NTSTATUS __stdcall LdrLoadDll(PWSTR SearchPath, PULONG LoadFlags, PUNICODE_STRING DllName, PVOID *BaseAddress)
{
  //...
  if ( SearchPath )
  {
    result = RtlInitUnicodeStringEx(&DestinationString, SearchPath);
    if ( result < 0 )
      return result;
    NewSearchPath = &DestinationString;
  }
  else
  {
    NewSearchPath = &LdrpDefaultPath;
  }
  //...
  v7 = LdrpLoadDll(DllName, (int)NewSearchPath, v6, 1, 0, (int)&DllName);
  //...
  return v7;
}

再调用LdrpLoadDll

int __stdcall LdrpLoadDll(PCUNICODE_STRING Source, int a2, int a3, char a4, int a5, int a6)
{
    //...
    if ( !LdrpInLdrInit )
      RtlEnterCriticalSection(&LdrpLoaderLock);
    
    //...
    LdrpFindOrMapDll(*(PCUNICODE_STRING *)((char *)&v31 + 1), v29, a3, v27[0], (int)&v33, (int)&v31);

    //...
    if ( v21 & 0x1000000 )
        v22 = LdrpCorProcessImports((void *)v21, v33);
    else
        v22 = LdrpProcessStaticImports(v33, v29);
    //...

    LdrpRunInitializeRoutines(0);

    //...

    if ( !LdrpInLdrInit )
      RtlLeaveCriticalSection(&LdrpLoaderLock);
}

通过分析函数,其流程如下

  1. 加载锁RtlEnterCriticalSection(&LdrpLoaderLock)

  2. 通过LdrpFindOrMapDll加载dll

  3. 处理导入表信息

  4. 运行回调函数LdrpRunInitializeRoutines

  5. 释放锁RtlLeaveCriticalSection(&LdrpLoaderLock)

在第4步运行LdrpRunInitializeRoutines其实就是调用DllMain,也就是说加载dll首先会加载锁,再调用DllMain

你可能感兴趣的:(microsoft,网络,安全,学习)