ZwQuery VirtualMemory 로 프로 세 스 모듈 매 거 진
ZwQueryVirtualMemory
:CreateToolhelp32Snapshot,Module32First,Module32Next "Tool Help Functions" , ( Win95 ), ntdll.dll ZwQueryVirtualMemory,。 , ( IceSword)。
:
//-------------------------------------------------------------------------------------------------
NTSTATUS
NTAPI
ZwQueryVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL );
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName,
MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;
:
ProcessHandle -
BaseAddress -
MemoryInformationClass -
MemoryInformation - ,
MemoryInformationLength - ( )
ReturnLength - ( )
:
NTSTATUS - STATUS_SUCCESS
//-------------------------------------------------------------------------------------------------
, MemoryBasicInformation MemorySectionName,
, : , , ,
. MEM_IMAGE , .
, \Device\HarddiskVolume1 , DOS , C:\,D:\ 。 \Device\HarddiskVolume1 C \Device\HarddiskVolume2 D 。 QueryDosDevice 。
:
// CheckDll.cpp : 。
//
#include "stdafx.h"
#include <windows.h>
#include <winternl.h>
#include <string>
#include <map>
using namespace std;
#pragma warning(disable:4312)
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName
}MEMORY_INFORMATION_CLASS;
typedef
NTSTATUS
(WINAPI *ZWQUERYVIRTUALMEMORY) (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
map<wstring, wstring> g_mapDevice2Path;
void ConvertVolumePaths(
IN PWCHAR DeviceName,
IN PWCHAR VolumeName
)
{
DWORD CharCount = MAX_PATH + 1;
PWCHAR Names = NULL;
PWCHAR NameIdx = NULL;
BOOL Success = FALSE;
for (;;)
{
//
// Allocate a buffer to hold the paths.
Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];
if ( !Names )
{
//
// If memory can't be allocated, return.
return;
}
//
// Obtain all of the paths
// for this volume.
Success = GetVolumePathNamesForVolumeNameW(
VolumeName, Names, CharCount, &CharCount
);
if ( Success )
{
break;
}
if ( GetLastError() != ERROR_MORE_DATA )
{
break;
}
//
// Try again with the
// new suggested size.
delete [] Names;
Names = NULL;
}
if ( Success )
{
//
// Display the various paths.
for ( NameIdx = Names;
NameIdx[0] != L'\0';
NameIdx += wcslen(NameIdx) + 1 )
{
g_mapDevice2Path[DeviceName] = NameIdx;
}
}
if ( Names != NULL )
{
delete [] Names;
Names = NULL;
}
return;
}
BOOL InitDevice2Path()
{
BOOL bRet = FALSE;
DWORD CharCount = 0;
WCHAR DeviceName[MAX_PATH] = L"";
DWORD Error = ERROR_SUCCESS;
HANDLE FindHandle = INVALID_HANDLE_VALUE;
BOOL Found = FALSE;
size_t Index = 0;
BOOL Success = FALSE;
WCHAR VolumeName[MAX_PATH] = L"";
//
// Enumerate all volumes in the system.
FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
if (FindHandle == INVALID_HANDLE_VALUE)
{
Error = GetLastError();
wprintf(L"FindFirstVolumeW failed with error code %d
", Error);
return bRet;
}
for (;;)
{
//
// Skip the \\?\ prefix and remove the trailing backslash.
Index = wcslen(VolumeName) - 1;
if (VolumeName[0] != L'\\' ||
VolumeName[1] != L'\\' ||
VolumeName[2] != L'?' ||
VolumeName[3] != L'\\' ||
VolumeName[Index] != L'\\')
{
Error = ERROR_BAD_PATHNAME;
wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s
", VolumeName);
break;
}
//
// QueryDosDeviceW doesn't allow a trailing backslash,
// so temporarily remove it.
VolumeName[Index] = L'\0';
CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));
VolumeName[Index] = L'\\';
if ( CharCount == 0 )
{
Error = GetLastError();
wprintf(L"QueryDosDeviceW failed with error code %d
", Error);
break;
}
ConvertVolumePaths(DeviceName, VolumeName);
//
// Move on to the next volume.
Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));
if ( !Success )
{
Error = GetLastError();
if (Error != ERROR_NO_MORE_FILES)
{
wprintf(L"FindNextVolumeW failed with error code %d
", Error);
break;
}
//
// Finished iterating
// through all the volumes.
Error = ERROR_SUCCESS;
break;
}
}
FindVolumeClose(FindHandle);
FindHandle = INVALID_HANDLE_VALUE;
return bRet;
}
void DeviceName2PathName(OUT WCHAR* szPathName, IN const WCHAR* szDeviceName)
{
memset(szPathName, 0, MAX_PATH * 2);
wstring strDeviceName = szDeviceName;
size_t pos = strDeviceName.find(L'\\', 9);
wstring strTemp1 = strDeviceName.substr(0, pos);
wstring strTemp2 = strDeviceName.substr(pos + 1);
wstring strDriverLetter = g_mapDevice2Path[strTemp1];
wstring strPathName = strDriverLetter + strTemp2;
wcscpy_s(szPathName, MAX_PATH, strPathName.c_str());
}
/**
*
* @param dwProcessId Id
* @return void
*/
void EnumProcessModules(IN DWORD dwProcessId)
{
DWORD dwStartAddr = 0x00000000;
BYTE szBuffer[MAX_PATH * 2 + 4] = {0};
WCHAR szModuleName[MAX_PATH] = {0};
WCHAR szPathName[MAX_PATH] = {0};
MEMORY_BASIC_INFORMATION mbi;
PUNICODE_STRING usSectionName;
ZWQUERYVIRTUALMEMORY fnZwQueryVirtualMemory;
HANDLE hProcess =NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
if (hProcess == NULL)
{
wprintf(L"Open Process %d Error
", dwProcessId);
return;
}
dwStartAddr = 0x00000000;
fnZwQueryVirtualMemory = (ZWQUERYVIRTUALMEMORY)
::GetProcAddress(GetModuleHandleA("ntdll.dll"),
"ZwQueryVirtualMemory" );
if(fnZwQueryVirtualMemory)
{
do
{
if (fnZwQueryVirtualMemory(
hProcess,
(PVOID)dwStartAddr,
MemoryBasicInformation,
&mbi,
sizeof(mbi),
0) >= 0 )
{
if(mbi.Type == MEM_IMAGE)
{
if (fnZwQueryVirtualMemory(
hProcess,
(PVOID)dwStartAddr,
MemorySectionName,
szBuffer,
sizeof(szBuffer),
0) >= 0 )
{
usSectionName = (PUNICODE_STRING)szBuffer;
if( _wcsnicmp(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR)) )
{
wcsncpy_s(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR) );
szModuleName[usSectionName->Length / sizeof(WCHAR)] = UNICODE_NULL;
DeviceName2PathName(szPathName, szModuleName);
wprintf(L"[0x%.8x]\t%s
", dwStartAddr, szPathName);
}
}
}
}
// , !
dwStartAddr += 0x1000;
}while( dwStartAddr < 0x80000000 );
}
CloseHandle(hProcess);
}
/**
* ("SeDebugPrivilege" 、 )
* @param void
* @return TRUE- ;FALSE-
*/
BOOL EnableDebugPriv()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
LUID Luid;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid ))
{
CloseHandle(hToken);
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = Luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return FALSE;
}
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwProcessId = 4;
if (argc != 2)
{
wprintf(L"usage:CheckDll ProcessId");
return 1;
}
dwProcessId = _ttoi(argv[1]);
InitDevice2Path();
//
if (EnableDebugPriv())
{
EnumProcessModules(dwProcessId);
}
g_mapDevice2Path.clear();
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.