C++实现第三方资源释放与载入过程(以DLL为例)

简介

我们经常看见有一些程序开始执行时会释放一些文件,以便于后续操作。例如一些病毒为了便于传播和隐藏,经常把一些需要用的动态库或是驱动文件打包进一个可执行文件中,再由需要使用的时候,再临时释放和加载。接下来笔者就将演示如何将DLL打包进文件,并实现动态释放和加载。

实现流程

  • 开发工具:Visual Studio 2017

1.在项目工程上点击右键,选择“添加资源”;

添加资源

2.选择"导入"项,选择“所有文件”,选择我们要导入的文件“test.dll”;

导入文件

3.会弹出命名自定义资源类型的对话框,自定义我们的资源类型;

重新添加资源

4.点击确定后,完成导入,"Ctrl+S"保存二进制资源文件;

完成导入

5.我们可以在自动添加的“resource.h”头文件中看到我们的资源ID宏;

资源ID宏

6.编程实现载入资源。

编程实现载入资源

代码样例

  • DLL样例文件代码

//
// FileName : HelloWorldDll.cpp
// Creator : PeterZheng
// Date : 2018/11/02 11:10
// Comment : HelloWorld Test DLL ^_^
//


#include <iostream>
#include <Windows.h>

using namespace std;

BOOL WINAPI DllMain(
    _In_ HINSTANCE hinstDLL,
    _In_ DWORD     fdwReason,
    _In_ LPVOID    lpvReserved
)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern"C" __declspec(dllexport) VOID Func()
{
    MessageBox(NULL, "HelloWorld", "Tips", MB_OK);
    return;
}
  • EXE资源载入文件代码:

//
// FileName : LoadResource.cpp
// Creator : PeterZheng
// Date : 2018/11/02 11:10
// Comment : Load Resource Demo
//


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
#include "resource.h"

using namespace std;

typedef VOID(*Func)(VOID);

BOOL ReleaseLibrary(UINT uResourceId, CHAR* szResourceType, CHAR* szFileName)
{
    // 找到资源
    HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(uResourceId), szResourceType);
    if (hRsrc == NULL)
    {
        MessageBox(NULL, "Find Resource Error!", "Tips", MB_OK);
        return FALSE;
    }
    // 获取资源大小
    DWORD dwSize = SizeofResource(NULL, hRsrc);
    if (dwSize <= 0)
    {
        MessageBox(NULL, "Get Resource Error!", "Tips", MB_OK);
        return FALSE;
    }

    // 载入资源
    HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
    if (hGlobal == NULL)
    {
        MessageBox(NULL, "Load Resource Error!", "Tips", MB_OK);
        return FALSE;
    }

    // 锁定资源,并返回指向资源第一字节的指针
    LPVOID lpRes = LockResource(hGlobal);
    if (lpRes == NULL)
    {
        MessageBox(NULL, "Lock Resource Error!", "Tips", MB_OK);
        return FALSE;
    }
    HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == NULL)
    {
        MessageBox(NULL, "Create File Error!", "Tips", MB_OK);
        return FALSE;
    }
    DWORD dwWriten = 0;
    BOOL bRes = WriteFile(hFile, lpRes, dwSize, &dwWriten, NULL);
    if (bRes == FALSE || dwWriten <= 0)
    {
        MessageBox(NULL, "Write To File Error!", "Tips", MB_OK);
        return FALSE;
    }
    CloseHandle(hFile);
    CloseHandle(hGlobal);
    CloseHandle(hRsrc);
    return TRUE;
}

int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    BOOL bRes = ReleaseLibrary(IDR_TESTRES1, (CHAR*)"TESTRES", (CHAR*)"test.dll");
    if (bRes == FALSE)
    {
        MessageBox(NULL, "Release DLL Error!", "Tips", MB_OK);
        return 0;
    }
    HMODULE hModule = LoadLibrary("test.dll");
    if (hModule == NULL)
    {
        MessageBox(NULL, "Load Library Error!", "Tips", MB_OK);
        return 0;
    }
    Func fc = (Func)GetProcAddress(hModule, "Func");
    if (fc == NULL)
    {
        MessageBox(NULL, "GetProcAddress Error!", "Tips", MB_OK);
        return 0;
    }
    fc();
    FreeLibrary(hModule);
    return 0;
}

转载于:https://www.cnblogs.com/PeterZ1997/p/10556143.html

### React 中解决 `ResizeObserver loop completed with undelivered notifications` 报错 在 React 项目中遇到 `ResizeObserver loop completed with undelivered notifications` 错误时,可以通过多种方式进行修复。以下是几种常见的解决方案: #### 方法一:通过重写 `ResizeObserver` 可以在项目的入口文件(如 `index.js` 或 `main.js`)中覆盖默认的 `ResizeObserver` 实现,使用防抖技术来减少频繁的通知调用。 ```javascript const debounce = (fn, delay) => { let timer; return (...args) => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn(...args); }, delay); }; }; const _ResizeObserver = window.ResizeObserver; window.ResizeObserver = class ResizeObserver extends _ResizeObserver { constructor(callback) { super(debounce(callback, 200)); // 设置延迟时间为 200ms } }; ``` 此方法适用于大多数场景,并能有效缓解因高频通知引发的问题[^1]。 --- #### 方法二:隐藏 Webpack Dev Server 覆盖层 如果该问题是由于开发环境中的 Webpack Dev Server 导致,则可以直接禁用其错误提示覆盖层。在全局样式文件(如 `index.css` 或 `global.css`)中添加以下代码即可实现: ```css #webpack-dev-server-client-overlay { display: none !important; } ``` 这种方法不会真正解决问题,而是屏蔽了错误提示,适合临时测试阶段使用[^3]。 --- #### 方法三:调整 Ant Design 组件行为 当使用 Ant Design 的 Table 等组件时,可能会因为内部逻辑触发上述问题。此时可尝试优化表格渲染性能或更新至最新版本以获取官方修复支持。如,在数据加载完成后手动控制 DOM 更新频率,从而降低对 `ResizeObserver` 的依赖程度[^4]。 --- #### 方法四:限制回调执行次数 如果不希望修改原生 API 定义,也可以采用限流策略限制每次事件触发后的实际响应数量。具体做法如下所示: ```javascript function throttle(fn, limit) { let lastCall = 0; return function(...args) { const now = new Date().getTime(); if (now - lastCall >= limit) { lastCall = now; return fn.apply(this, args); } }; } // 使用节流函数包裹原有回调逻辑 new ResizeObserver(throttle((entries) => { entries.forEach(entry => console.log('Resized:', entry)); }, 500)).observe(document.querySelector('#target')); ``` 这种方式无需改动全局配置,仅针对特定需求定制化适配[^5]。 --- ### 总结 以上四种方式分别从不同角度出发解决了 `ResizeObserver loop completed with undelivered notifications` 这类异常现象的发生机制及其应对措施。开发者应根据实际情况灵活选用最合适的手段加以实施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值