You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查找DLL的最小与最大内存地址,解决注入扫内存时读取自身DLL的问题

解决方案

共有3种可落地的实现方案,可根据你的扫描场景选择:

  • 方案1:直接排除自身DLL的固定模块地址范围
    注入完成后第一时间调用GetModuleInformationAPI获取当前DLL在目标进程中的加载基址和镜像大小,得到固定的地址排除区间。后续扫描内存时只要当前内存块落入该区间直接跳过即可,该方案实现最简单、扫描效率最高,适合不需要排除DLL动态申请内存的场景。
    核心实现代码示例:
    // 初始化阶段获取自身DLL信息
    HMODULE hSelfModule = GetModuleHandle(L"你的注入DLL文件名.dll");
    MODULEINFO selfModInfo = {0};
    GetModuleInformation(GetCurrentProcess(), hSelfModule, &selfModInfo, sizeof(MODULEINFO));
    ULONG_PTR excludeStart = (ULONG_PTR)selfModInfo.lpBaseOfDll;
    ULONG_PTR excludeEnd = excludeStart + selfModInfo.SizeOfImage;
    
    // 扫描时的过滤逻辑
    MEMORY_BASIC_INFORMATION mbi;
    ULONG_PTR curAddr = 0;
    while(VirtualQuery((LPCVOID)curAddr, &mbi, sizeof(mbi)) == sizeof(mbi)) {
        // 命中自身DLL范围直接跳过
        if(curAddr >= excludeStart && curAddr < excludeEnd) {
            curAddr += mbi.RegionSize;
            continue;
        }
        // 此处写你的正常扫描逻辑
        curAddr += mbi.RegionSize;
    }
    
  • 方案2:通过内存块所属模块名过滤
    遍历内存时调用K32GetMappedFileNameAPI查询当前内存块关联的模块文件名,和自身注入的DLL文件名做匹配,匹配成功则跳过该内存块。该方案适配性更强,就算DLL被重定位也不会影响过滤效果,但会增加扫描过程的性能开销,适合扫描频率不高的场景。
  • 方案3:维护动态排除列表
    如果需要同时排除DLL运行过程中通过VirtualAlloc、malloc等接口动态申请的内存,你可以额外维护一个动态排除列表,每次申请内存时将地址范围存入列表,扫描时同时和固定模块区间、动态排除列表做比对,命中则跳过。

注意事项

  • 若目标进程为64位程序,需使用ULONG_PTR类型存储地址,避免地址计算时出现整数溢出问题
  • 如果你的扫描逻辑需要读取其他系统DLL的内存,不要直接排除所有模块范围,仅过滤自身DLL即可

内容的提问来源于stack exchange,提问作者GUY Yankovitch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 18:06:01