미친해커

[C] Rlibloaderapi.h - GetRemoteModuleFileName 본문

C/Remote libloaderapi.h

[C] Rlibloaderapi.h - GetRemoteModuleFileName

미친해커 2022. 2. 17. 16:16
반응형

GetModuleFileName

GetModuleFileName 함수는 인자로 들어온 HMODULE의 전체 경로를 반환해주는 함수이다. 즉 HMODULE(ImageBase)는 가지고 있지만 해당 HMODULE이 어떤 DLL인지 모를때 사용하면 유용한 함수이다.

GetRemoteModuleFileName

DWORD GetRemoteModuleFileNameA(HANDLE ProcessHandle, HMODULE hModule, LPSTR lpFilename, DWORD nSize)
{
    ZeroMemory(lpFilename, nSize);
    wchar_t Filename[MAX_PATH];
    DWORD Size = GetRemoteModuleFileNameW(ProcessHandle, hModule, Filename, MAX_PATH);
    int FilenameLength = WideCharToMultiByte(CP_ACP, 0, Filename, -1, NULL, 0, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, Filename, -1, lpFilename, FilenameLength <= nSize ? FilenameLength : nSize, NULL, NULL);
    return FilenameLength <= nSize ? FilenameLength : nSize;
}

DWORD GetRemoteModuleFileNameW(HANDLE ProcessHandle, HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
{
#ifdef _WIN64
    BOOL bWow64Process;
    IsWow64Process(ProcessHandle, &bWow64Process);
    size_t SizeOfPointer = bWow64Process ? 4 : 8;
#else
    size_t SizeOfPointer = 4;
#endif
    nSize -= 2;
    DWORD Size = 0;
    PVOID PebBaseAddress = GetRemotePeb(ProcessHandle);

    if (PebBaseAddress == NULL)
        return Size;

    PVOID PebLdrData = NULL;

    if (ReadProcessMemory(ProcessHandle, 
#ifdef _WIN64
            (ULONG_PTR)PebBaseAddress + (bWow64Process ? Peb_LdrOffset32 : Peb_LdrOffset64), 
#else
            (ULONG_PTR)PebBaseAddress + Peb_LdrOffset32,
#endif
            &PebLdrData, 
            SizeOfPointer, 
            NULL) == FALSE)
        return hModule;

#ifdef _WIN64
    PVOID LdrDataTableEntry = (ULONG_PTR)PebLdrData + (bWow64Process ? PebLdrData_LOMLOffset32 : PebLdrData_LOMLOffset64);
#else
    PVOID LdrDataTableEntry = (ULONG_PTR)PebLdrData + PebLdrData_LOMLOffset32;
#endif

    for (; ReadProcessMemory(ProcessHandle, LdrDataTableEntry, &LdrDataTableEntry, SizeOfPointer, NULL) 
            && 
#ifdef _WIN64
            (ULONG_PTR)PebLdrData + (bWow64Process ? PebLdrData_LOMLOffset32 : PebLdrData_LOMLOffset64) != LdrDataTableEntry
#else
            (ULONG_PTR)PebLdrData + PebLdrData_LOMLOffset32 != LdrDataTableEntry
#endif
        ;)
    {
        PVOID DllBase;

        if (ReadProcessMemory(ProcessHandle, 
#ifdef _WIN64
                (ULONG_PTR)LdrDataTableEntry + (bWow64Process ? LdrDataTableEntry_DllBase32 : LdrDataTableEntry_DllBase64),
#else
                (ULONG_PTR)LdrDataTableEntry + LdrDataTableEntry_DllBase32, 
#endif
                &DllBase, 
                SizeOfPointer, 
                NULL) == FALSE)
            return Size;
        
        if (DllBase != hModule)
            continue;

#ifdef _WIN64
        size_t SizeOfUnicodeString = bWow64Process ? sizeof(UNICODE_STRING32) : sizeof(UNICODE_STRING64);
#else
        size_t SizeOfUnicodeString = sizeof(UNICODE_STRING);
#endif
        BYTE *UnicodeString = calloc(1, SizeOfUnicodeString);

        if (ReadProcessMemory(ProcessHandle, 
#ifdef _WIN64
                (ULONG_PTR)LdrDataTableEntry + (bWow64Process ? LdrDatatableEntry_FullDllName32 : LdrDatatableEntry_FullDllName64), 
#else
                (ULONG_PTR)LdrDataTableEntry + LdrDatatableEntry_FullDllName32, 
#endif
                UnicodeString, 
                SizeOfUnicodeString, 
                NULL) == FALSE)
            return Size;

        ZeroMemory(lpFilename, nSize + 2);

        if (ReadProcessMemory(ProcessHandle, 
#ifdef _WIN64
                bWow64Process ? ((UNICODE_STRING32 *)UnicodeString)->Buffer : ((UNICODE_STRING64 *)UnicodeString)->Buffer, 
                lpFilename, 
                bWow64Process ? ((UNICODE_STRING32 *)UnicodeString)->Length <= nSize ? ((UNICODE_STRING32 *)UnicodeString)->Length : nSize : ((UNICODE_STRING64 *)UnicodeString)->Length <= nSize ? ((UNICODE_STRING64 *)UnicodeString)->Length : nSize, // UnicodeString.Length <= nSize ? UnicodeString.Length : nSize, 
#else
                ((UNICODE_STRING *)UnicodeString)->Buffer,
                lpFilename,
                ((UNICDOE_STRING *)UnicodeString)->Length <= nSize ? ((UNICDOE_STRING *)UnicodeString)->Length : nSize,
#endif
                &Size) == FALSE && (RtlFreeHeap(_get_heap_handle(), 0, UnicodeString) || 1))
            return Size;

        free(UnicodeString);
        break;
    }

    return Size;
}

사용예시

#include <stdio.h>
#include "Rlibloaderapi.h"

int main()
{
    DWORD PID;
    printf("PID : ");
    scanf("%d", &PID);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    
    if (hProcess == NULL)
    {
    	printf("OpenProcess Failed\n");
        printf("GetLastError : %d\n", GetLastError());
        return -1;
    }
    
    char buffer[MAX_PATH];
    
    HMODULE hModule = GetRemoteModuleHandleA(hProcess, "kernel32.dll");
    GetRemoteModuleFileNameA(hProcess, hModule, buffer, MAX_PATH);
    
    printf("%s\n", buffer);
    
    return 0;
}
반응형
Comments