当前位置: 首页 > news >正文

seo优化网站推广平面设计网课培训有用吗

seo优化网站推广,平面设计网课培训有用吗,263企业邮箱注册申请,网页设计字体颜色代码文章目录 MemoryModule - exp - test概述笔记测试环境GetModuleFileName不能正常执行GetModuleFileNameWntdll_LdrGetDllFullName猜测原因用LoadLibrary载入的DLL中功能是正常的 gLog可以正常使用内存载入DLL无法支持的功能的折中方法COM操作正常调用方代码接口代码 接口入参测… 文章目录 MemoryModule - exp - test概述笔记测试环境GetModuleFileName不能正常执行GetModuleFileNameWntdll_LdrGetDllFullName猜测原因用LoadLibrary载入的DLL中功能是正常的 gLog可以正常使用内存载入DLL无法支持的功能的折中方法COM操作正常调用方代码接口代码 接口入参测试接口出参测试接口实现用LoadLibrary先测试一下用 MemoryModule 试试 openssl调用的测试接口代码用LoadLibrary测试ok用 MemoryModule 试试 备注END MemoryModule - exp - test 概述 MemoryModule 是从内存载入DLL的一种实现。 测试一下和隐式载入DLL/显式载入在效果上有哪些不同? 是否可以在内存中载入执行正规DLL的接口 在内存载入正规DLL时是否可以在DLL中执行正常的API? 是否可以正常调用其他正规DLL的接口 笔记 测试环境 vs2019 x64 debug MemoryModule WIN32API COM openssl3.2 GetModuleFileName不能正常执行 原因: 载入的DLL地址不同应该和GetModuleFileName的实现有关系。而不是从内存载入DLL有问题。 dw_rc GetModuleFileName(hModule, szBuf, sizeof(szBuf));b_err ((dw_rc 0) || (dw_rc sizeof(szBuf)));// 隐式调用dll hModule 00007FFDEB9E0000, dw_rc 110, szBuf D:\my_dev\my_local_git_prj\soft\exp\exp012_MemoryModule\src\MyMemoryDllLoader\x64Debug\DllForTest_x64Debug.dll// MemoryModule hModule 0000000180000000, dw_rc 0, szBuf _stprintf(szBufTmp, TEXT(hModule %p, dw_rc %d, szBuf %s\r\n), hModule, dw_rc, szBuf);OutputDebugString(szBufTmp);从内存载入DLL的实现用VS2019无法正常断在DLL中调试。但是用IDA是可以的。 用IDA载入DLL后在干兴趣的地方下断点然后进行调试选择主程序(有动态载入DLL功能的那个EXE), 跑起来当应用动态载入DLL时是可以断住单步调试的。 看一下为啥GetModuleFileName不好使? kernel32_GetModuleFileNameW() kernelbase_GetModuleFileNameW 单步的时候没有几步就返回0了。 GetModuleFileNameW DWORD __stdcall GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) {DWORD v3; // ediint DllFullName; // eax__int64 v5; // rdxint v6; // esi__int64 v7; // rbx__int64 v9; // rcx__int128 v10; // [rsp20h] [rbp-18h] BYREFv3 nSize;v10 0i64;if ( ((unsigned __int8)hModule 3) ! 0 ){v9 3221225781i64; LABEL_8:BaseSetLastNTError(v9, lpFilename);return 0;}if ( nSize 0x7FFF ){v3 0x7FFF;goto LABEL_4;}if ( !nSize ){v9 3221225507i64;goto LABEL_8;} LABEL_4:*((_QWORD *)v10 1) lpFilename;WORD1(v10) 2 * v3 - 2;DllFullName LdrGetDllFullName(hModule, v10); // 这里没得到路径名称v6 DllFullName;v7 (unsigned __int16)v10 1;*(_WORD *)(*((_QWORD *)v10 1) 2 * v7) 0;if ( DllFullName 0 ){BaseSetLastNTError((unsigned int)DllFullName, v5);if ( v6 -1073741789 )LODWORD(v7) v3;}else{RtlSetLastWin32Error(0);}return v7; }ntdll_LdrGetDllFullName __int64 __fastcall LdrGetDllFullName(__int64 a1, __int64 a2) {unsigned int v2; // esiunsigned int LoadedDllByHandle; // eax__int64 v5; // rbx_WORD *v6; // rdi_QWORD *SubSystemTib; // rcx__int64 v9; // [rsp40h] [rbp8h] BYREF__int64 v10; // [rsp50h] [rbp18h] BYREFv2 0;v10 0i64;if ( a1 ){LoadedDllByHandle LdrpFindLoadedDllByHandle(a1, v10, v9);v5 v10;v2 LoadedDllByHandle;if ( !v10 )return v2;v6 (_WORD *)(v10 72);}else{v10 LdrpImageEntry;v6 (_WORD *)(LdrpImageEntry 72);v5 LdrpImageEntry;SubSystemTib NtCurrentTeb()-NtTib.SubSystemTib;if ( SubSystemTib SubSystemTib[1] )v6 (_WORD *)SubSystemTib[1];}if ( v5 ){RtlCopyUnicodeString(a2, v6);if ( *v6 *(_WORD *)(a2 2) )v2 -1073741789;if ( v5 ! LdrpImageEntry )LdrpDereferenceModule(v5);}return v2; }猜测原因 GetModuleFileName()是从LoadLibray()载入的DLL中找DLL路径名称如果是从内存中载入DLL, 那么系统载入的DLL列表中肯定没有这个hModule所以得到的DLL路径是空的。 那只能避免在内存载入的DLL(包括二次调用的其他DLL)中使用GetModuleFileName(), 这个限制还是挺大的。 用LoadLibrary载入的DLL中功能是正常的 void CLoaderDlg::OnBnClickedButton2() {HMODULE hDll NULL;PFN_FnAdd pfn NULL;int i_rc 0;do {hDll ::LoadLibraryA(DllForTest_x64Debug.dll);if (NULL ! hDll){pfn (PFN_FnAdd)::GetProcAddress(hDll, FnAdd);if (NULL ! pfn){i_rc (*pfn)(6, 7);TRACE(%d (*pfn)(6, 7);\r\n, i_rc);}}} while (false);} hModule 00007FFDF80B0000, dw_rc 110, szBuf D:\my_dev\my_local_git_prj\soft\exp\exp012_MemoryModule\src\MyMemoryDllLoader\x64Debug\DllForTest_x64Debug.dllDllForTest DLL_THREAD_ATTACH D:\my_dev\my_local_git_prj\soft\exp\exp012_MemoryModule\src\MyMemoryDllLoader\Loader\LoaderDlg.cpp(197) : atlTraceGeneral - 13 (*pfn)(6, 7); DllForTest DLL_THREAD_ATTACH DllForTest DLL_THREAD_ATTACH gLog可以正常使用 前提 - 不要使用GetModuleFileName相关的值去设置日志的路径 我这里直接就不设置日志路径了默认就是在临时目录中。 void my_dll_init(HMODULE hModule) {std::string strA;std::wstring strW;// 在内存载入的DLL中无法使用 GetModuleFileName(), 因为载入的DLL地址不在系统记录的DLL载入地址表中, 得不到DLL路径名称if (true) {strA DllForTest_x64Debug.dll;// 日志前缀名称, 只能是用常量字符串赋值, 不能是变量赋值, 否则日志名称开头是随机的字符google::InitGoogleLogging(LsGlog);strA _ strA;strA .log.txt;google::SetLogFilenameExtension(strA.data()); // 日志后缀名称// FLAGS_log_dir strA.data(); // 如果不设置日志路径, 应该是就在临时目录中FLAGS_logtostderr false;FLAGS_logtostdout false;FLAGS_stderrthreshold 999; // dont send log info to stderrLOG(INFO) glog was init now;}if (google::IsGoogleLoggingInitialized()) {LOG(INFO) log begin;} }void my_dll_uninit(void) {if (google::IsGoogleLoggingInitialized()) {LOG(INFO) log end;google::ShutdownGoogleLogging();} } 内存载入DLL无法支持的功能的折中方法 如果是第三方程序自己没源码工程这个就没招了。 如果自己有代码的工程可以将内存载入不支持的功能放在DLL外面执行然后将结果传进DLL中用。 以GetModuleFileName()为例 DLL代码中加入设置path的接口。 std::wstring g_strDllPathNameIn; extern C __declspec(dllexport) bool APIENTRY setDllPathName(TCHAR* pszPathNameIn) {bool b_rc false;do {if (NULL pszPathNameIn){break;}g_strDllPathNameIn pszPathNameIn;LOG(INFO) g_strDllPathNameIn wstring2string(g_strDllPathNameIn).data();b_rc true;} while (false);return b_rc; }在主程序(要内存载入DLL的工程)中内存载入DLL后先将不支持的功能在主程序中执行完再将结果设置进DLL, 再执行其他逻辑。 typedef bool (APIENTRY* PFN_setDllPathName)(TCHAR* pszPathNameIn); void CLoaderDlg::test2() {HMODULE hDll NULL;PFN_setDllPathName pfn NULL;int i_rc 0;TCHAR szBuf[MAX_PATH 1];DWORD dw_rc 0;bool b_rc false;do {hDll ::LoadLibraryA(DllForTest_x64Debug.dll);if (NULL ! hDll) {pfn (PFN_setDllPathName)::GetProcAddress(hDll, setDllPathName);if (NULL ! pfn) {dw_rc ::GetModuleFileName(NULL, szBuf, sizeof(szBuf));assert((dw_rc 0) (dw_rc ! sizeof(szBuf)));b_rc (*pfn)(szBuf);TRACE(%d PFN_setDllPathName()\r\n, b_rc);}::FreeLibrary(hDll);hDll NULL;}} while (false); } COM操作正常 调用接口的细节 执行COM初始化执行COM类的初始化执行COM类的操作执行COM类的反初始化执行COM反初始化 必须保证DLL退出前主动将COM和COM类的反初始化做了否则会报错。 调用方代码 void CLoaderDlg::OnBnClickedButton1() {uint8_t* pBuf NULL;int len 0;HMEMORYMODULE handle NULL;PFN_FnAdd p_FnAdd NULL;PFN_testWMI p_testWMI NULL;do {len sizeof(ucAry_ary_DllForTest_x64Debug);TRACE(TEXT(sizeof(ucAry_ary_DllForTest_x64Debug) %d\r\n), len);pBuf new uint8_t[len 1];assert(NULL ! pBuf);pBuf[len] \0;memcpy(pBuf, ucAry_ary_DllForTest_x64Debug, len);handle MemoryLoadLibrary(pBuf, len);if (NULL handle) {// _tprintf(_T(Cant load library from memory.\n));assert(false);break;}p_FnAdd (PFN_FnAdd)MemoryGetProcAddress(handle, FnAdd);if (NULL p_FnAdd) {break;}TRACE(TEXT(p_FnAdd(1, 2) %d\n), p_FnAdd(1, 2));// testWMIp_testWMI (PFN_testWMI)MemoryGetProcAddress(handle, testWMI);if (NULL p_testWMI) {break;}TRACE(TEXT(testWMI() %d\n), p_testWMI());} while (false);if (NULL ! handle) {MemoryFreeLibrary(handle);handle NULL;}if (NULL ! pBuf) {delete[] pBuf;pBuf NULL;} } 接口代码 extern C __declspec(dllexport) int APIENTRY testWMI(void) {int i_rc 0;CWmiBattery bat;std::wstring strInfo;do {i_rc;if (!ComInitOnce()) {break;}i_rc;bat.init();i_rc;if (!bat.get_info(strInfo)) {break;}i_rc;LOG(INFO) info wstring2string(strInfo).data();i_rc;bat.un_init();i_rc;ComUnInitOnce();i_rc;} while (false);return i_rc; }接口入参测试 // test 入参pfn_setDllPathName (PFN_setDllPathName)MemoryGetProcAddress(handle, setDllPathName);if (NULL pfn_setDllPathName) {break;}TRACE(TEXT(pfn_setDllPathName在这里插入代码片() %d\n), pfn_setDllPathName(TEXT(this is a path name)));从调用方打印的TRACE看到执行成功 D:\my_dev\my_local_git_prj\soft\exp\exp012_MemoryModule\src\MyMemoryDllLoader\Loader\LoaderDlg.cpp(189) : atlTraceGeneral - pfn_setDllPathName() 1从记录的日志看到值已经设置进入了 I20240510 16:49:54.355886 342176 dllmain.cpp:28] g_strDllPathNameIn this is a path name说明MemoryModule的入参传递没问题 接口出参测试 出参测试主要看能不能将参数传出来。 如果在DLL内部分配内存能不能传出来? 能不能在调用方释放指针(DLL内部创建的内存指针)? 接口实现 extern C __declspec(dllexport) bool APIENTRY testParamOut(char** ppOut, int* pLen) {bool b_rc false;int len 0;do {if ((NULL ppOut) || (NULL pLen)){break;}len MAX_PATH;*pLen len;*ppOut new char[len 1];memset(*ppOut, 0, sizeof(len));(*ppOut)[len] \0;strcpy(*ppOut, fill content from DLL\r\n);b_rc true;} while (false);return b_rc; }用LoadLibrary先测试一下 void CLoaderDlg::test4() {// test param outHMODULE hDll NULL;// // typedef bool (APIENTRY* PFN_testParamOut)(char** ppOut, int* pLen);PFN_testParamOut pfn NULL;bool b_rc false;char* pOut NULL;int lenOut 0;do {hDll ::LoadLibraryA(DllForTest_x64Debug.dll);if (NULL ! hDll) {pfn (PFN_testParamOut)::GetProcAddress(hDll, testParamOut);if (NULL ! pfn) {b_rc (*pfn)(pOut, lenOut);TRACE(%d (*pfn)(pOut, lenOut);\r\n, b_rc);}TRACE(lenOut %d\r\n, lenOut);if (NULL ! pOut){TRACE(pOut %s\r\n, pOut);delete[] pOut;pOut NULL;}::FreeLibrary(hDll);hDll NULL;}} while (false); }从打印的TRACE日志可以看出正常从文件载入DLL, 可以从DLL中newBuffer, 填充值传给调用方。 调用方可以正常使用DLL传出来的数据buffer, 可以在调用方delete DLL中创建的buffer. 用 MemoryModule 试试 // test 出参// typedef bool (APIENTRY* PFN_testParamOut)(char** ppOut, int* pLen);pfn_testParamOut (PFN_testParamOut)MemoryGetProcAddress(handle, testParamOut);if (NULL pfn_testParamOut) {break;}char* pOut NULL;int lenOut 0;bool b_rc false;b_rc pfn_testParamOut(pOut, lenOut);TRACE(TEXT(pfn_setDllPathName() %d\n), b_rc);if (b_rc){if (NULL ! pOut){OutputDebugStringA(pOut );OutputDebugStringA(pOut);OutputDebugStringA(\r\n);delete[] pOut;pOut NULL;}TRACE(lenOut %d\r\n, lenOut);} 根据TRACE, gLog可以看出执行的都对行为和LoadLibray相同。 openssl调用的测试 接口代码 用以前做的实验aes_128_cbc加解密的代码。 在DLL中操作stdout/stderr是不行的(BIO_dump_fp()这种函数都是不能调用的)。纯逻辑的OSSL接口可以。 估计主程序不是控制台程序的缘故。 extern C __declspec(dllexport) bool APIENTRY testOssl() {bool b_rc false;mem_hook();do {OutputDebugString(TEXT( testOssl\r\n));LOG(INFO) testOssl;UCHAR ucBuf[0x100 - 3];int lenBuf sizeof(ucBuf);int i 0;UCHAR* pEncBuf NULL;int lenEncBuf 0;UCHAR* pDecBuf NULL;int lenDecBuf 0;// 可以在EVP_CipherInit_ex()之后, 用EVP_CIPHER_CTX_get_key_length()/EVP_CIPHER_CTX_get_iv_length()看长度UCHAR key[0x10]; // aes-128-cbcs key len 0x10UCHAR iv[0x10]; // aes-128-cbcs iv len 0x10for (i 0; i 0x10; i){key[i] (UCHAR)i;iv[i] (UCHAR)i;}for (i 0; i lenBuf; i){ucBuf[i] (UCHAR)i;}do {// printf(before enc:\n);// BIO_dump_fp(stdout, ucBuf, lenBuf);// enc// // 如果输入不是0x10对齐, 加密后, 就会自动0x10对齐(多出几个字节)// 所以要自己记录加密前的长度, 且加密时, 要将输出(加密后)buffer 16对齐(或直接比输入的长度多16字节)// 且加密后, 要自己记录加密后的长度if (!aes_128_cbc_EncDec(true, ucBuf, lenBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pEncBuf, lenEncBuf)){assert(false);break;}// printf(enc before lenBuf %d, enc after lenEncBuf %d\n, lenBuf, lenEncBuf);// enc before lenBuf 253, enc after lenEncBuf 256// printf(after enc:\n);// BIO_dump_fp(stdout, pEncBuf, lenEncBuf);// decif (!aes_128_cbc_EncDec(false, pEncBuf, lenEncBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pDecBuf, lenDecBuf)){assert(false);break;}// 解密后的数据长度和解密前一样了// printf(after dec:\n);// BIO_dump_fp(stdout, pDecBuf, lenDecBuf);// 比较明文和解密后的明文是否相同if ((lenDecBuf ! lenBuf) || (0 ! memcmp(ucBuf, pDecBuf, lenBuf))){assert(false);break;}// printf(enc / dec all ok\n);} while (false);if (NULL ! pEncBuf){OPENSSL_free(pEncBuf);pEncBuf NULL;}if (NULL ! pDecBuf){OPENSSL_free(pDecBuf);pDecBuf NULL;}OutputDebugString(TEXT(testOssl ok\r\n));LOG(INFO) testOssl ok;b_rc true;} while (false);mem_unhook();LOG(INFO) end testOssl;return b_rc; } 用LoadLibrary测试ok void CLoaderDlg::test5() {// typedef bool (APIENTRY* PFN_testOssl)();HMODULE hDll NULL;PFN_testOssl pfn NULL;bool b_rc false;do {hDll ::LoadLibraryA(DllForTest_x64Debug.dll);if (NULL ! hDll) {pfn (PFN_testOssl)::GetProcAddress(hDll, testOssl);if (NULL ! pfn) {b_rc (*pfn)();TRACE(%d (*pfn)();\r\n, b_rc);}::FreeLibrary(hDll);hDll NULL;}} while (false); } 用 MemoryModule 试试 // test OSSLpfn_testOssl (PFN_testOssl)MemoryGetProcAddress(handle, testOssl);if (NULL pfn_testOssl) {break;}b_rc pfn_testOssl();TRACE(%d pfn_testOssl(), b_rc); 测试的可以正常的 备注 初步看来用MemoryModule从内存中载入DLL和正常LoadLibrary(或者隐式调用DLL)有点区别区别不大。 MemoryModule基本就和LoadLibray一样。 区别 DLL中不能依赖DLL载入地址的WIN32API(e.g. GetModuleFileName()) 如果还有其他区别以后遇到再记录。 初步看起来可以选择MemoryModule从内存载入正常开发的DLL. 这样安全很多。 如果DLL是被保护的(DLL文件对应的数据受密码学保护都是释放到内存来用)如果是这样的话逆向工程师将DLLdump出来落地改了DLL也没用。因为最终用起来是现释放现用。最多逆向工程师能通过分析dump出来的DLL, 知道DLL具体干的啥活。 如果最后能拉扯着逆向工程师去试图解密被密码学保护的数据/去试着组装被保护的数据, 那加固目的就基本达成了。 逆向工程师一般看到被密码学保护的数据(不是crackme那种强度)一般情况下就撤退了. 或者去研究授权数据解密后到应用使用数据这一段区间看有没有搞头。 对于我现在的应用如果逆向工程师改不了我发的授权数据加固的目就达到了。 END
http://www.zqtcl.cn/news/619081/

相关文章:

  • 网站开发大概需要多久湛江招聘网最新招聘
  • 免费建网站 手机网站深圳网站设计(深圳信科)
  • 辽宁做网站的公司工作室网站建设的意义
  • 南京网站搜索排名免费企业网站空间
  • 手机要访问国外网站如何做附近学电脑在哪里报名
  • 免费建网站哪个网好中国建设银行信用卡黑名单网站
  • 网页设计好看的网站中小型网站建设 教案
  • 优秀网站设计案例行业内做网站的公司排名
  • 个人备案网站能做商城吗长沙app制作公司哪家好
  • 成都网站建设方案优化旺道seo怎么优化网站
  • 九江县建设规划局网站wordpress多个博客
  • 绵阳住房和城乡建设局网站做服装外贸的网站
  • 福建省华荣建设集团有限公司网站建设网站西安
  • 做视频网站程序多少钱网站内链有什么用
  • 建设企业网站模板联享品牌网站建设
  • 网站建设耂首先金手指提升网站访问速度
  • 为什么备案关闭网站网站seo推广招聘
  • 建设企业网站的重要性城乡建设厅官方网站
  • 网上有做口译的网站么怎样手机做网站教程
  • 孵化器网站平台建设网站一直建设中
  • 企业网站建设的方案书网站镜像 cdn
  • 淘宝做网站的都是模板泉州模板建站公司
  • 清理网站数据库网站服务器租一个月
  • wordpress免费简约主题搜索引擎优化的英文
  • 瑞安门户网站建设怎么建设自己网站首页
  • 网站建设岗位周计划thinkphp微网站开发
  • 如何修改asp网站栏目帝国cms网站搬家教程
  • 网站建设与网页制作小团队兼职做网站
  • 嘉兴做网站的公司网红营销价值
  • scala做网站广州化妆品网站制作