Как прочитать информацию о восстановлении памяти процесса с помощью VirtualQueryEx в Go? - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь перенести определенные функции PSHunt (https://github.com/Infocyte/PSHunt/blob/master/Surveys/Survey.ps1) на Go. В частности, я пытаюсь использовать VirtualQueryEx для перебора страниц памяти процесса, как показано в следующем фрагменте Powershell:

# Get handle to the process
$hProcess = $Kernel32::OpenProcess(0x400, $False, $ProcessID) # PROCESS_QUERY_INFORMATION (0x00000400)

if (-not $hProcess) {
    throw "Unable to get a process handle for process ID: $ProcessID"
}

$MemoryInfo = New-Object $MEMORY_BASIC_INFORMATION
$BytesRead = $Kernel32::VirtualQueryEx($hProcess, $ModuleBaseAddress, [Ref] $MemoryInfo, $PageSize)

$null = $Kernel32::CloseHandle($hProcess)

Обратите внимание, что приведенный выше код вызывается из другой функции с помощью следующего: $MemoryInfo = Get-VirtualMemoryInfo -ProcessID $ProcessID -ModuleBaseAddress ([IntPtr]::Zero) -PageSize $SysInfo.PageSize

Моя реализация в Go выглядит следующим образом:

var systemInfo SYSTEM_INFO
getSystemInfo := 
kernel32dll.NewProc("GetSystemInfo")
_, _, err = getSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo)))

openProcess := kernel32dll.NewProc("OpenProcess")
hProcess, _, err := openProcess.Call(uintptr(0x410), uintptr(0), uintptr(processId))
fmt.Println("Message from OpenProcess:",err.Error())
defer windows.CloseHandle(windows.Handle(hProcess))

var memoryBasicInformation MEMORY_BASIC_INFORMATION
dll := syscall.MustLoadDLL("kernel32.dll")
defer dll.Release()

virtualQueryEx := dll.MustFindProc("VirtualQueryEx")

bytesRead, _, err := virtualQueryEx.Call((uintptr)(unsafe.Pointer(hProcess)), (uintptr)(unsafe.Pointer(????)), (uintptr)(unsafe.Pointer(&memoryBasicInformation)), (uintptr)(unsafe.Pointer(&systemInfo.PageSize)))
fmt.Println("Bytes read:",bytesRead)
fmt.Println("Message from VirtualQueryEx:", err.Error())

Независимо от того, чтоЯ делаю, VirtualQueryEx возвращает «Неверный доступ к ячейке памяти». Я не могу понять, какое значение передать в качестве базового адреса процесса (указано «????» выше). Документация Microsoft говорит, что этот параметр является необязательным,но если я оставлю это поле пустым, я получу ошибку о неправильной длине команды.

Как я уже говорил, моя цель - начать с основы процесса и просканировать весь процесс с помощью цикла, что может произойтипосле этого первоначального вызова VirtualQueryEx.

Для справки я использую библиотеку go syscall (в данном случае; хотя я также пробовалБиблиотека ys / windows безрезультатна.)

Пожалуйста, дайте мне знать, если я смогу что-то уточнить.

1 Ответ

0 голосов
/ 25 января 2019

Каждый процесс имеет свое собственное адресное пространство.Если вы обращаетесь к адресам памяти, которые ему не принадлежат, то это может привести к «Неверный доступ к ячейке памяти».

Моя цель - начать с основы процесса и просканировать весь объект с помощьюцикл

Сначала установите «lpAddress» (я имею в виду «????»), начиная с нуля (обычно вы получите смещение между базовым адресом процесса и нулевым адресом)

Затем проверьте значения memoryBasicInformation.AllocationProtect и memoryBasicInformation.Protect, чтобы определить, есть ли права доступа.

Итерируйте "lpAddress" в цикле с

lpAddress = memoryBasicInformation.BaseAddress + memoryBasicInformation.RegionSize

затем продолжайте использовать VirtualQueryEx().Когда lpAddress указывает адрес выше самого высокого адреса памяти, доступного для процесса, функция завершается с ошибкой ERROR_INVALID_PARAMETER и прерывает цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...