如何在内存中搜索值

问题描述

我正在开发桌面应用程序(内存扫描仪)。 该应用程序的核心是相互通信的内核驱动程序和dll。 在我的内核驱动程序中,我使用了 Nt 和 Zw undocumented Functions 的所有低级函数

我成功地从随机过程中获得:

  • 所有模块(名称、地址、大小) - 静态内存
  • 所有栈线程(base,limit)-栈内存
  • 进程从地址 0x1000 到地址 0x7fffffff 的所有虚拟内存 - 虚拟内存
  • 研究如何获取进程堆地址。

堆栈问题: 当我将堆栈数据与程序 VmMap 比较时,我看到我只得到 64 位堆栈线程,为什么?

当我尝试在所有地址中搜索值时,我可能需要 10-15 分钟,然后我可能会得到 5 个与我搜索的值相等的结果。

我不明白为什么我可以找到(健康值)需要在虚拟内存中 我拥有计算机中进程的所有虚拟内存,而不仅仅是模块的虚拟内存

我认为我可能需要获得 10,000 个结果

在这里分享部分代码,也许可以帮助您了解更多。

获取堆栈地址代码

NTSTATUS res = ZwOpenThread(&hThread,MAXIMUM_ALLOWED,&ObjectAttributes,&st->ClientId);

    if (!NT_SUCCESS(res)) {
        ExFreePool(qmemptr); // free memory
        ExFreePool(StackAreaList); // free memory
        return STATUS_UNSUCCESSFUL;
    }

    THREAD_BASIC_informatION info;
    durum = ZwQueryinformationThread(hThread,ThreadBasicinformation,&info,sizeof(THREAD_BASIC_informatION),NULL);

    if (!NT_SUCCESS(durum)) {
        DbgPrintEx(0,"durum: %#010x",durum);
        ExFreePool(qmemptr); // free memory
        ExFreePool(StackAreaList); // free memory
        return STATUS_UNSUCCESSFUL;
    }

    if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)process_id,&process))) {
        if (NT_SUCCESS(Mmcpy(process,(PVOID)info.TebBaseAddress,PsGetCurrentProcess(),&tib,sizeof(NT_TIB)))) {
            //DbgPrintEx(0,"StackLimit: %#010x to StackBase: %#010x \n",tib.StackLimit,tib.StackBase);

            tempStackArea = { 0 };
            tempStackArea.Base = (uintptr_t)tib.StackBase;
            tempStackArea.Limit = (uintptr_t)tib.StackLimit;
            memcpy((PVOID)((ULONG_PTR)StackAreaList + (i * sizeof(StackArea))),&tempStackArea,sizeof(StackArea));
        }
    }

获取虚拟内存地址

HANDLE handle;
res = ZwOpenProcess(&handle,&st->ClientId);
if (!NT_SUCCESS(res)) {
    DbgPrintEx(0,"fail to open process res: %#010x.\n",res);
    return STATUS_UNSUCCESSFUL;
}
uintptr_t len = 0x7FFFFFFF;

ULONG index2 = 0;
for (uintptr_t i = 0x1000; i < len;)
{
    res = ZwQueryVirtualMemory(handle,(PVOID)i,MemoryBasicinformation,&mbi,sizeof(MEMORY_BASIC_informatION),&bytes);
    if (!NT_SUCCESS(res)) {
        DbgPrintEx(0,"fail to load mbi res: %#010x.\n",res);
        break;
        return STATUS_UNSUCCESSFUL;
    }
    //DbgPrintEx(0,"Address: %#014x.\n",mbi.BaseAddress);

    SM_VM tempVm = { 0 };
    tempVm.Address = i;
    tempVm.Type = mbi.Type;
    tempVm.State = mbi.State;
    tempVm.Protect = mbi.Protect;
    tempVm.Size = mbi.RegionSize;
    tempVm.AllocationBase = (uintptr_t)mbi.AllocationBase;

    if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_GUARD) == 0) && ((mbi.Protect == PAGE_NOACCESS) == 0)) {
        auto isWritable = ((mbi.Protect & PAGE_READWRITE) != 0 || (mbi.Protect & PAGE_WRITEcopY) != 0 || (mbi.Protect & PAGE_EXECUTE_READWRITE) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITEcopY) != 0);
        if (isWritable) {
            memcpy((PVOID)((ULONG_PTR)VMList + (index2 * sizeof(SM_VM))),&tempVm,sizeof(SM_VM));
        }
    }
    

    index2 = index2 + 1;
    i += mbi.RegionSize;
}

这是如何在地址范围内查找值的应用程序代码

            int len = bytess.Length;
            byte[] temp4Bytes = new byte[4];
            var base_address = baseAddress;
            Record temp_record;
            List<Record> record_list = new List<Record>();
            for (int i = 0; i < len; i++)
            {
                temp_record = new Record();
                temp_record.Name = name;
                temp_record.Address = base_address + i;
                temp_record.Offset = i;
                //  base+0    00 00 00 00
                //  base+4    00 01 02 03
                //  base+8    04 05 06 07
                //  base+c    ...
                //  00 00 00 00

                if (i + 3 == len - 1) break;
                temp4Bytes[0] = bytess[i];
                temp4Bytes[1] = bytess[i + 1];
                temp4Bytes[2] = bytess[i + 2];
                temp4Bytes[3] = bytess[i + 3];
                temp_record.Value = Smkd.ByteArrayToStruct<Int32>(temp4Bytes);

                if (temp_record.Value == _4bit_value)
                {
                    record_list.Add(temp_record);
                }
            }
            return record_list;

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)