代码在vs的安装目录下,*:\Microsoft Visual Studio\2019\Community\DIA SDK\Samples\DIA2Dump
// 例子使用的CoCreateInstance()函数,使用这个函数需要提前把dll通过regsvr32注册到系统,win10需要管理员权限
hr = CoCreateInstance(__uuidof(DiaSource),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiaDataSource),
(void **) ppSource);
// 例子也提供了另一个函数NoRegCoCreate(),不用提前注册,加上#include "diacreate.h"这个头文件,把上面的函数调用换成下面这样
hr = NoRegCoCreate(L"msdia140.dll", // 直接使用dll名
__uuidof(DiaSource),
__uuidof(IDiaDataSource),
(void**)ppSource);
mov r9, [rbp+450h+arg_8] ; void ** // 返回值 (void**)ppSource)
lea r8, _GUID_79f1bb5f_b66e_48e5_b6a9_1545c323ca3d ; struct _GUID * // __uuidof(IDiaDataSource)
lea rdx, _GUID_e6756135_1e65_4d17_8576_610761398c3c ; struct _GUID * // __uuidof(DiaSource)
lea rcx, aMsdia140Dll ; "msdia140.dll" // L"msdia140.dll"
call j_?NoRegCoCreate@@YAJPEB_WAEBU_GUID@@1PEAPEAX@Z ; // NoRegCoCreate()
//////////////////// 下面是NoRegCoCreate()这个函数
NoRegCoCreate(const wchar_t *, const struct _GUID *, const struct _GUID *, void **)
// rcx,rdx,r8,r9, 分别为这4个参数
mov [rsp+arg_0], rbx
mov [rsp+arg_8], rsi
push rdi
sub rsp, 30h
mov rbx, rdx // rdx第2个参数, rbx = __uuidof(DiaSource)
mov rsi, r8 // r8第3个参数, rsi = __uuidof(IDiaDataSource)
xor edx, edx ; hFile
mov rdi, r9 // r9第4个参数, rdi = (void**)ppSource)
lea r8d, [rdx+8] ; dwFlags
call cs:__imp_LoadLibraryExW // 1. LoadLibraryExW "msdia140.dll" ( 第1个参数 rcx = L"msdia140.dll" )
test rax, rax
jnz short loc_14001FD0B
...
loc_14001FD0B: ; CODE XREF: NoRegCoCreate(wchar_t const *,_GUID const &,_GUID const &,void * *)+27↑j
lea rdx, ProcName ; "DllGetClassObject"
mov rcx, rax ; hModule
call cs:__imp_GetProcAddress // 2. GetProcAddress "DllGetClassObject"
test rax, rax
jz short loc_14001FCE9
lea r8, [rsp+38h+var_18]
mov rcx, rbx
lea rdx, _GUID_00000001_0000_0000_c000_000000000046
call rax ; // 3. <msdia140.DllGetClassObject>( __uuidof(DiaSource), rdx, [rsp+38h+var_18] )
mov ebx, eax
test eax, eax
js short loc_14001FD57
mov rcx, [rsp+38h+var_18] ; CDiaClassFactory::`vftable`{for`IClassFactory`} // 获取一个CDiaClassFactory的虚表
; CDiaClassFactory::`vftable`{for `CDiaBase`}
mov r9, rdi
mov r8, rsi
xor edx, edx
mov rax, [rcx]
call qword ptr [rax+18h] ; // 4. CreateInstance@CDiaClassFactory(
// this,
// 0,
// __uuidof(IDiaDataSource),
// (void**)ppSource) )
// )
1. 加载dll,获取DllGetClassObject函数的地址
2. 调用DllGetClassObject, 获取一个虚表,这里是CDiaClassFactory
3. 调用虚表里的函数CreateInstance, CDiaClassFactory->CreateInstance()
原文:https://www.cnblogs.com/asmalleyu/p/14204053.html