미친해커

[C] Rlibloaderapi.h - GetRemoteProcAddress 본문

C/Remote libloaderapi.h

[C] Rlibloaderapi.h - GetRemoteProcAddress

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

GetProcAddress

GetProcAddress 함수는 kernel32.dll에 정의되어 있는 함수이다. 인자로 HMODULE과 함수의 이름을 주고 호출하게되면 해당 DLL에서 Export 하는 함수들 중 인자로 넣은 함수의 이름과 같은 이름의 함수의 주소를 반환해준다.

 

이 함수도 마찬가지로 현재 프로세스를 기준으로 하게된다. 하지만 굳이 이 함수까지 구현한 이유는 DLL Injection과 같은 기술을 사용할 때 혹시라도 kernel32.dll의 ImageBase가 다르거나 특정 함수의 주소를 알아야할 때가 있을 것같아 해당 함수도 Remote 버전을 구현하게 되었다.

GetRemoteProcAddress

FARPROC GetRemoteProcAddress(HANDLE ProcessHandle, HMODULE hModule, LPCSTR lpProcName)
{
#ifdef _WIN64
    BOOL bWow64Process;
    IsWow64Process(ProcessHandle, &bWow64Process);
    size_t SizeOfPointer = bWow64Process ? 4 : 8;
#else
    size_t SizeOfPointer = 4;
#endif
    FARPROC Proc = NULL;
    ULONG_PTR ImageBase = hModule;
    IMAGE_DOS_HEADER DOS;

    if (ReadProcessMemory(ProcessHandle, hModule, &DOS, sizeof(IMAGE_DOS_HEADER), NULL) == FALSE)
        return Proc;
#ifdef _WIN64
    BYTE *NT = malloc(bWow64Process ? sizeof(IMAGE_NT_HEADERS32) : sizeof(IMAGE_NT_HEADERS64));
#else
    IMAGE_NT_HEADERS32 *NT = malloc(sizeof(IMAGE_NT_HEADERS32));
#endif

    if (ReadProcessMemory(ProcessHandle, ImageBase + DOS.e_lfanew, NT, _msize(NT), NULL) == FALSE && IFREE(NT))
        return Proc;

    if (
#ifdef _WIN64
        (bWow64Process ? 
        ((IMAGE_NT_HEADERS32 *)NT)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 
        :
        ((IMAGE_NT_HEADERS64 *)NT)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 
#else
        NT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
#endif
         == NULL && IFREE(NT))
        return Proc;

    IMAGE_EXPORT_DIRECTORY EXPORT;

    if (ReadProcessMemory(ProcessHandle, 
            ImageBase 
            + 
#ifdef _WIN64
            (bWow64Process ? 
            ((IMAGE_NT_HEADERS32 *)NT)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 
            :
            ((IMAGE_NT_HEADERS64 *)NT)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress), 
#else
            NT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, 
#endif
            &EXPORT, 
            sizeof(IMAGE_EXPORT_DIRECTORY), 
            NULL) == FALSE && IFREE(NT))
        return Proc;

    free(NT);

    for (DWORD i = 0; i < EXPORT.NumberOfNames; i++)
    {
        ULONG64 FunctionName = 0;
        char ch;

        if (ReadProcessMemory(ProcessHandle, ImageBase + EXPORT.AddressOfNames + i * 4, &FunctionName, 4, NULL) == FALSE)
            return Proc;
        
        FunctionName += ImageBase;

        for (DWORD j = 0; ReadProcessMemory(ProcessHandle, FunctionName + j, &ch, 1, NULL); j++)
        {
            if (ch != *(lpProcName + j))
                break;

            if (ch == NULL && *(lpProcName + j) == NULL)
            {
                WORD Ordinal;
                if (ReadProcessMemory(ProcessHandle, ImageBase + EXPORT.AddressOfNameOrdinals + i * 2, &Ordinal, sizeof(WORD), NULL) == FALSE)
                    return Proc;

                if (ReadProcessMemory(ProcessHandle, ImageBase + EXPORT.AddressOfFunctions + Ordinal * 4, &Proc, SizeOfPointer, NULL) == FALSE)
                    return Proc;

                Proc += ImageBase;
                break;
            }
            else if (ch == NULL || *(lpProcName + j) == NULL)
                break;
        }

        if (Proc)
            break;
    }

    return Proc;
}

사용예시

#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;
    }
    
    HMODULE hModule = GetRemoteModuleHandleA(hProcess, "kernel32.dll");
    FARPROC pLoadLibraryA = GetRemoteProcAddress(hProcess, hModule, "LoadLibraryA");
    
    printf("LoadLibraryA : %p\n", pLoadLibraryA);
    
    return 0;
}
#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 Modulename[MAX_PATH];
    char Functionname[64];
    
    printf("Module name : ");
    scanf("%s", Modulename);
    
    HMODULE hModule = GetRemoteModuleHandleA(hProcess, Modulename);
    
    if (hModule == NULL)
    {
    	printf("%s not found!\n");
        return -1;
    }
    
    printf("Function name : ");
    scanf("%s", Function);
    
    FARPROC Functions = GetRemoteProcAddress(hProcess, hModule, Function);
    
    printf("%s : %p\n", Function, Functions);
    
    return 0;
}
반응형
Comments