본문 바로가기
SSM

Apr 24, 2011 - Windows System Programming Expert Seminar(2)

by nickeys 2011. 4. 25.
1. HANDLE과 HWND
# 핸들? 32비트의 객체를 가리키는 id. 그 내부 구현은 다음과 같이 되어있다.

struct HWND__ {
};
typedef HWND__* HWND;

왜? typedef unsigned int HWND; <- 이렇게 하지 않고 위와 같이 했을까?
만약, 후자 처럼 선언을 한다면, HICON과 같이 다른 대상의 핸들과의 타입 체킹이 안된다는 문제가 있다.

C++에서 타입을 확인하기 위해서는 RTTI를 사용한다. typeid라는 키워드를 이용하는 것이다.
e.g> typeid(HWND).name(); // HWND타입의 이름을 문자열 형태로 반환.

2. Process Handle
process handle 을 구하려면 우선, process id를 알아야 한다.
=> DWORD pid;
DWORD tid = GetWindowThreadProcessId}(hWnd, &pid);
그리고 pid를 이용해서 process handle을 구한다.
=> HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pid); // 첫 번째 인자는 접근 권한
or HANDLE hProcess = OpenProcess(PROCESS_VM_READ, 0, pid);

3. DLL
# .dll 파일에는 실제 코드 가 담겨 있고(.c or .cpp 파일에 대한 정보) .lib 파일에는 그 실제 코드가 어디에 있는지를 알려주는 정보가 있다(.h 파일에 대한 정보). 즉, 정적 링크를 할 때에는 .lib 파일만 있어도 되고, 동적 링크를 할 때에는 .dll파일이 반드시 필요하다.

e.g>
#ifdef DLLSOURCE
    #define DLLAPI __declspec(dllexport)  //export 지시어
#else
    #define DLLAPI __declspec(dllimport)  //import 지시어
#endif
위의 코드 중 __declspec(dllexport) / __declspec(dllimport) 부분이 있다. 앞의 것은 그 프로젝트 내부에 있는 함수나 변수 등등을 외부에 노출 시키겠다는 의미다. 즉, 이렇게 외부에 노출 시켜서 .lib에 기록이 된다는 것이다.
뒤에 것은 해당 dll 파일이나 lib파일을 불러다 쓰는 쪽에서 사용 하는 것인데 굳이 쓰지 않아도 된다. extern 키워드로 대체도 가능하다.
lib 파일을 다음과 같이 링크 하게 되면, dllimport는 따로 하지 않아도 내부의 함수들을 다 쓸 수 있다(원형을 선언해 주지 않으면 경고는 뜬다).
#pragma comment(lib,"math.lib")

이렇게 하고 lib파일만 복사해 놓으면 링크시에는 문제가 없다. 단, 실행 했을 때에는 코드의 실제 내용이 필요 하므로, dll 파일이 필요하게 되어 프로그램이 죽게된다. 이러한 방식은 Static link라고 한다.

# 위와 같이 링크를 하게 되면, 실행파일을 만들면 딱히 장점이 보이지 않는다. 정적으로(컴파일시) 링크 정보를 실행 파일에 모두 포함 시켜야 한다는 점이 전체 라이브러리중에 한 함수만 쓴다 해도 그런 과정을 거치게 하고, 실행파일도 크기가 커진다. 이에 비해 속도가 약간 떨어지긴 하지만(필요한 코드를 로드할 때) 필요한 dll파일만 로드해서 사용하는 동적 링크가 모듈화에도 유리하다(오류 수정 시).

HMODULE LoadLibrary(LPCSTR) / FreeLibrary(HDODULE)

이 함수는 해당 dll파일을 로드/해제하는 역할을 한다.

FARPROC GetProcAddress(HMODULE, LPCSTR)

이 함수는 해당 모듈에서 함수를 찾아서 반환한다. 캐스팅을 통해 사용한다(함수 포인터).

e.g>F f; // typedef int (*F)(int, int);
HMODULE h = LoadLibrary("math.dll");
f= (F)GetProcAddress(h,"Add");
FreeLibrary(h);

4. DLL Injection
프로세스 상에서 타 프로세스에 직접적으로 접근할 방법이 없다. 그래서 dll을 통한 간접적인 접근 방법이 제공 되는데,
a. 타 프로세스를 연다.
b. 열린 프로세스에 가상 메모리를 잡는다.
c. 잡은 메모리에 dll 경로를 적는다.
d. CreateRemoteThread 함수를 통해 원격으로 함수를 호출한다.
e.g> HANDLE hThread =  CreateRemoteThread(hProcess,0,0, f,addr, 0,0); // f는 함수 포인터, addr은 할당한 가상 메모리의 시작 주소


'SSM' 카테고리의 다른 글

Apr 24, 2011 - Windows System Programming Expert Seminar(1)  (0) 2011.04.25
Sep 8, 2010 Naver DeView  (0) 2010.09.12
My name tags~  (0) 2010.08.19
2달 반 삽질의 결과 ㅋ  (0) 2010.07.29