//
#include <string>
#include <windows.h>
#include <winternl.h>
#include <map>
using namespace std;
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"";
FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
if (FindHandle == INVALID_HANDLE_VALUE)
{
Error = GetLastError();
wprintf(L"FindFirstVolumeW failed with error code %d\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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 = 1376;
InitDevice2Path();
// 首先提示权限
if (EnableDebugPriv())
{
EnumProcessModules(dwProcessId);
#include <string>
#include <windows.h>
#include <winternl.h>
#include <map>
using namespace std;
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"";
FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
if (FindHandle == INVALID_HANDLE_VALUE)
{
Error = GetLastError();
wprintf(L"FindFirstVolumeW failed with error code %d\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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 = 1376;
InitDevice2Path();
// 首先提示权限
if (EnableDebugPriv())
{
EnumProcessModules(dwProcessId);
}
return 0;
}