i am developing desktop app (memory scanner). the core of the app is kernel driver and dll who communicate with each other. in my kernel driver i use all the low level function of Nt and Zw undocumented Functions
i success to get from random process:
stack problem: when i compere the stack data to the program VmMap i see that i get only the 64bit stack threads, why?
when i try to search value in all the address i get its take maybe 10-15 min and then i get maybe 5 results that equle to the value i search.
i dont understand why i can find (health value) is need to be in the virtual memory an i have all the virtual memory of a process in the computer not only virtual memory of modules
i think that i need to get maybe 10,000 results
here i share parts of the code maybe it will help you to understand more.
get stack addresses code:
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, 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, 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));
}
}
get virtual memory addresses
HANDLE handle;
res = ZwOpenProcess(&handle, MAXIMUM_ALLOWED, &ObjectAttributes, &st->ClientId);
if (!NT_SUCCESS(res)) {
DbgPrintEx(0, 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, 0, "fail to load mbi res: %#010x.\n", res);
break;
return STATUS_UNSUCCESSFUL;
}
//DbgPrintEx(0, 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;
}
this is the code from the application of how to find value in address range
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;
User contributions licensed under CC BY-SA 3.0