DLL源码的入口函数,接受参数为 (HINSTANCE p_hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 主要逻辑是对ul_reason_for_call进行判断,取值为“DLL_PROCESS_ATTACH”则执行Inject()函数,取值为“DLL_PROCESS_DETTACH”则执行unhook()函数,若为“DLL_THREAD_ATTACH”或“DLL_PROESS_ATTACH”则直接break返回。
一开始调用了 DebugLog::Init();FunctionFlow::Init();DynConfig::Init(); 其实就是进行一些初始化,主要获取一些配置参数,如:data_path,pliantext,datalimit,stringfinder. 随后调用Process类中的GetProcessModules方法来获取当前进程包含的所有模块,得到一个vector < MODULEENTRY32 > vDlls,再循环vDlls中的所有模块
若是”nss3.dll”或”nspr4.dll”,则通过GetProcAddress,获取Dll中导出函数”PR_Read”、”PR_Write”、”PR_GetDescType”、”PR_Recv”、”PR_Send”的地址,再利用AddHook()函数对这些函数进行hook;若是”ncrypt.dll”模块,则以相同的 方式获取“SslEncryptPacket”、”SslDecryptPacket”函数地址,用AddHook()函数进行hook;若是”ws2_32.dll”模块,则获取“recv”、”send”、”WSARecv”、”WSASend”函数地址,同样用AddHook()函数进行hook;若是”secur32.dll”模块,则获取”EncryptMessage”、”DecryptMessage”函数地址,并进行Hook;若是”ssh2core73u.dll”模块,这是SecureCRT内部使用的模块,则获取”?Get_raw_pointer@SSHPacket@SSH2@@QAE_NAAPAEH@Z”、”DecryptMessage”函数地址,并进行hook;若是“chrome.dll”、“putty.exe”、“Winscp.exe”模块(分别是chrome、putty以及WinSCP所使用的模块),则分别使用HookChrome()、HookPutty()、HookWinSCP()进行Hook; eg: PR_Read_Original = (PR_Read_Typedef)GetProcAddress(LoadLibrary(sModuleName.c_str()), "PR_Read"); PR_Write_Original =(PR_Write_Typedef)GetProcAddress(LoadLibrary(sModuleName.c_str()), "PR_Write"); PR_GetDescType_Original =(PR_GetDescType_Typedef)GetProcAddress(LoadLibrary(sModuleName.c_str()),"PR_GetDescType"); Hooker::AddHook((void *)PR_Read_Original, (void *)PR_Read_Callback); Hooker::AddHook((void *)PR_Write_Original, (void *)PR_Write_Callback);下面是函数GetProcAddress介绍
函数功能描述:GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。 函数原型: FARPROC GetProcAddress( HMODULE hModule, // DLL模块句柄 LPCSTR lpProcName // 函数名 ); 参数: hModule [*] 包含此函数的DLL模块的句柄。LoadLibrary或者GetModuleHandle函数可以返回此句柄。 lpProcName [*] 包含函数名的以NULL结尾的字符串,或者指定函数的序数值。如果此参数是一个序数值,它必须在一个字的底字节,高字节必须为0。 返回值: 如果函数调用成功,返回值是DLL中的输出函数地址。 如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError。最后调用InstallPlugin()函数