用ZwQueryVirtualMemory枚举进程模块

//
#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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值