반응형

모듈이란

 

모듈은 함수들의 집합으로, 무언가에 관련된 데이터나 함수를 하나로 묶은 단위이다.

 

Windows 내의 예시로는 .dll이나 .exe 파일이다.

 


GetModuleHandle()

// https://learn.microsoft.com/ko-kr/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea
HMODULE GetModuleHandleA(
  [in, optional] LPCSTR lpModuleName
);
#include <stdio.h>
#include <windows.h>

int main() 
{
    HMODULE hModule = GetModuleHandle(NULL);

    if (hModule != NULL)
        printf("Module Handle: 0x%p\n", hModule);
    else
        printf("Failed to get module handle. Error code: %d\n", GetLastError());

    return 0;
}

 

lpModuleName에 .dll이나 .exe 파일의 이름을 넘겨주면 모듈에 대한 핸들(HMODULE)을 리턴하는데, 실제 코드에서 리턴되는 값은 base 주소를 넘겨준다.

 

즉 GetModuleHandle() API는 .dll과 .exe 파일의 베이스 주소를 리턴해주는 API 함수이다.

 

참고로 GetModuleHandle() API의 lpModuleName에 NULL을 주면, 현재 프로세스의 베이스 주소를 리턴한다.

 


LoadLibrary()

 

// https://learn.microsoft.com/ko-kr/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya
HMODULE LoadLibraryA(
  [in] LPCSTR lpLibFileName
);

 

GetModuleHandle() API와 같이 모듈에 대한 핸들을 리턴하는 API 함수이다.

 

 


GetModuleHandle() API와 LoadLibrary() API의 공통점과 차이점

 

공통점

위의 두 API 함수 모두 모듈에 대한 핸들을 리턴한다.

 

차이점

LoadLibrary는 LoadLibrary()를 호출하는 프로그램(주체)이 직접 dll, exe 파일을 메모리에 올려 핸들을 얻어오는 함수이다.
GetModuleHandle은 메모리에 이미 올라와서 현재 실행 중인 dll, exe 파일의 핸들을 얻어오는 함수이다.

예를 들어 LoadLibrary()는 내가 필요로 하는 dll 파일을 직접 호출해 핸들을 얻어오고자 할 때 사용하고
GetModuleHandle()는 현재 시스템 메모리에 이미 올라가져 있는 dll, exe 프로세스의 핸들을 얻어오고자 할 때 사용한다.

단순히 값만 참조할 때는 GetModuleHandle을 사용하고, 실제 지속적으로 사용하기 위해서는 LoadLibrary를 사용한다.
GetModuleHandle로 얻어온 핸들에 대해서는 다른 프로그램에서도 사용 중일 수 있으므로 FreeLibrary() 대신 CloseHandle()로 마무리해주는 것이 좋다.

LoadLibrary로 얻어온 핸들에 대해서는 FreeLibrary()로 마무리해도 된다.
LoadLibrary()는 reference count가 증가하고, GetModuleHandle()은 reference count가 증가하지 않는다.

여기서 reference count는 메모리를 효율적으로 관리하기 위해서 사용되는 참고한 횟수이다.

reference count가 증가될 경우 핸들 리스크 혹은 메모리 리스크가 발생할 가능성이 있다.

 


GetProcAddress()

 

// https://learn.microsoft.com/ko-kr/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress
FARPROC GetProcAddress(
  [in] HMODULE hModule,
  [in] LPCSTR  lpProcName
);

 

GetModuleHandle() API와 LoadLibrary() API가 모듈의 Base 주소를 리턴한다면, GetProcAddress()는 모듈 안에 있는 함수 또는 변수의 주소를 리턴한다.

 

예를 들어 특정 DLL에서 export하는 printf() 함수의 주소를 알고 싶으면, GetModuleHandle() API 혹은 LoadLibrary()와 APIGetProcAddress()를 조합해 현재 메모리상에서 특정 함수의 주소를 알 수 있다.

반응형

+ Recent posts