- 프로세스 핸들 관련 설명

------------------------------------------------------------------------------
프로세스의 핸들을 얻어올 때 사용하는 함수

HANDLE WINAPI OpenProcess(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwProcessId
);

성공시 지정한 프로세스의 핸들이 리턴
실패시 NULL 리턴

- dwDesiredAccess : 핸들을 얻어 접근 하고자 하는 프로세스의 접근 권한을 설정 한다.
(함수를 호출한 프로세스가 아닌 다른 프로세스의 전체 접근 권한을 지닌 핸들을 구하고자 할 때는 
SeDebugPrivilege 특권을 활성화 시켜야 한다.)

- bInheritHandle : 핸들의 상속 여부를 지정 (TRUE : 상속, FLASE : 비상속)

- dwProcessId : 핸들을 얻고자 하는 프로세스의 ID를 지정
(함수를 호출한 프로세스 자신의 PID를 얻고자 할 때는 
GetCurrentProcessId 함수를 사용한다.)

------------------------------------------------------------------------------------------------------------------------------------------------------------
http://choiwoo.tistory.com/5
출처

다른 프로세스의 가상메모리를 확보할때 사용

LPVOID VirtualAllocEx(
HANDLE hProcess, 
LPVOID lpAddress, 
DWORD dwSize, 
DWORD FlAllocationType, 
DWORD FlProtect
);

- hProcess : 대상 핸들
- lpAddress : 할당받을 주소 (NULL 입력시 자동으로 비어있는 주소 할당)
- dwSize : 할당받을 메모리의 크기 (NULL 입력시 하나의 페이지 크기를 할당)
- FlAllocationType : 메모리를 Reserve 아니면 Commit -> MEM_RESERVE, MEM_COMMIT

----------------------------------------------------------------------------------------------------------------

할당받은 메모리에 쓰기를 할때 사용

BOOL WINAPI WriteProcessMemory(
HANDLE hProcess,
LPVOID ipBaseAddress,
LPVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
)
- hProcess : 프로세스 핸들정보
- ipBaseAddress : VirtualAllocEx ()를 통해 얻은 메모리 주소위치
- lpBuffer : DLL 경로 
- nSize : DLL 경로 문자열 길이 + NULL
- *lpNumberOfBytesWritten : 대상 프로세스 전달된 문자열 길이(? 무슨말인지)

----------------------------------------------------------------------------------------------------------------

모듈의 핸들 얻을때 사용하는 함수

HMODULE WINAPI GetModuleHandle( _In_opt_ LPCTSTR lpModuleName)

- lpModuleName : 얻고자 하는 핸들의 이름

----------------------------------------------------------------------------------------------------------------

함수의 주소를 얻어 올때 사용하는 함수
성공시 함수의 주소 리턴 실패시 ?

FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);

- hModule : 찾고자 하는 함수를 가진 모듈의 핸들값 
- lpProcName : 찾고자 하는 함수 이름

----------------------------------------------------------------------------------------------------------------

다른 프로세스에 스레드를 생성할때 사용하는 함수

HANDLE WINAPI CreateRemoteThread (
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress, 
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadID
);

- hProcess : 스레드가 생성될 프로세스의 핸들
- lpThreadAttributes : 스레드핸들을 자식 프로세스에게 상속할수있는지 여부(NULL 설정시 상속되지않음)
- dwStackSize : 스레드의 스택크기
- lpStartAddress : 스레드 함수 주소
- lpParameter : 스레드 파라미터 주소
- dwCreationFlags : 스레드가 시작되는 방식 지정 (0 : 바로 실행, 0x00000004 : 잠시 중지)
- lpThreadID : 생성될 스레드의 아이디 전달

----------------------------------------------------------------------------------------------------------------
http://artisticbit.tistory.com/…/WaitForSingleObject-%ED%95…
커널 오브젝트의 Signaled, Non-Signaled 상태 설명
https://www.joinc.co.kr/w/man/4100/WaitForsingleObject
함수에 관한 자세한 설명

지정된 객체가 시그널상태가 될때까지 혹은 비시그널 상태로 제한시간 까지 기다릴때사용하는 함수

성공시 
WAIT_ABANDONED ( 지정된 객체가 파기된 뮤텍스 객체다. 
뮤텍스를 소유한 쓰레드가 뮤텍스 객체의 소유권을 되돌려주지 않고 종료했다. 
그래서 뮤텍스 객체의 소유권이 호출한 쓰레드로 옮겨졌으며, 뮤텍스는 비시그널 상태가 되었다.)

WAIT_OBJECT_0 ( 지정한 객체에 시그널 상태다.) 
WAIT_TIMEOUT 리턴 ( 제한시간이 지날 때 까지 시그널 상태가 되지 않았다.)

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);

- hHandle : 기다릴 객체의 핸들
- dwMilliseconds : 제한시간을 밀리초 단위로 지정(0 : 객체의 상태를 확인하고 바로 반환, INFINITE : 시그널이 도착할때 까지 기다린다.)


Dll Injection p311


출처 : https://www.joinc.co.kr/w/man/4200/CreateThread


DLL Injection p311 


pragma comment(lib, "urlmon.lib")

- 명시적인 라이브러리의 링크

 해당 라이브러리를 링크 시켜준다. (라이브러리 링크?)

 파일헤더와 라이브러리의 차이


-----------------------------------------------------------------------------------------------

현재 어플리케이션의 디버거창에 스트링을 출력하는 함수

OutputDebugString(LPCTSTR lpOutputString)


--------------------------------------------------------------------------------------------------

쓰레드 생성함수(호출한 프로세스의 가상 주소에 쓰레드를 생성해서 실행)


함수가 성공적으로 실행되면 생성된 쓰레드의 handle이 리턴

실패면 NULL 리턴

GetLastError()함수 호출시 자세한 에러 내역 확인 가능


실제로 신경써 줄 부분은 lpStartAddress 와 lpParameter 두 가지 뿐이며

나머지는 디폴트 값 (0 혹은 NULL 포인터)으로 전달하면 된다.


HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes, 

SIZE_T dwStackSize,  

LPTHREAD_START_ROUTINE lpStartAddress, 

LPVOID lpParameter, 

DWORD dwCreateionFlags,

LPDWORD lpThreadId 

);


- LPSECURITY_ATTRIBUTES lpThreadAttributes : SECURITY_ATTRIBUTES 구조체 포인터 (NULL 사용하면 기본 보안특성 사용)


typedef struct _SECURITY_ATTRIBUTES 

{

    

DWORD nLength;   // 이 구조체의 크기

    

LPVOID lpSecurityDescriptor;    // 공유 제어에 대한 보안 descriptor 포인터.

    

BOOL bInheritHandle;    // Child Process 로 Kernel Object Handle를 넘겨줄 것인지.


}


- SIZE_T dwStackSize : 스택의 크기를 초기화 한다. 단위는 byte (0이면 기본 크기 사용)


- LPTHREAD_START_ROUTINE lpStartAddress : 실행할 쓰레드 함수의 포인터


- LPVOID lpParameter : 쓰레드에 넘겨줄 변수의 포인터


- DWORD dwCreateionFlags : 쓰레드가 생성될 때 사용할 추가적인 플래그 값(0이면 쓰레드 생성 즉시 cpu에 스케쥴링)


- LPDWORD lpThreadId : 쓰레드 식별 번호 (NULL 이면 쓰레드 식별번호를 반환하지 않는다.)


--------------------------------------------------------------------------------------------------

이 함수 사용 이유 -> http://rockdrumy.tistory.com/381


BOOL WINAPI CloseHandle(_In_ HANDLE hObject)

- _In_ HANDLE hObject : CreateThread()함수 리턴값


쓰레드를 종료하는 함수가 아니라 참조 하지 않을때 사용하는 함수


-----------------------------------------------------------------------------------------------------------------------


실행 파일의 경로 얻을때 사용하는 함수


DWORD GetModuleFileName(HMODULE hModule, LPTSTR lpFilename, DWORD nSize)


- HMODULE hModule : DLL을 임포팅한 실행프로그램 경로를 확보하려면 이 값을 NULL로 전달

- LPTSTR lpFilename : 실행 경로를 받을 포인터

- DWORD nSize : 실행 경로가 들어갈 버퍼의 길이


----------------------------------------------------------------------------------------------------------------------------------------

_tcsrchr 함수 = strrchr의 TCHAR 용


----------------------------------------------------------------------------------------------------------------------------------------

_tcscpy_s(char *_Dst, rsize _t _SizeInBytes, const char* _Src)

(버퍼 오버플로우를막거나 잘못된 메모리 연산 방지를 위해 사용)


- char *_Dst : 저장변수

- rsize _t _SizeInBytes : 쓰려고 하는 데이터 크기 + 1

- const char* _Src : 쓰려고 하는 데이터 


------------------------------------------------------------------------------------------------------

인터넷에서 파일을 다운로드 할때 사용하는 함수


HRESULT URLDownloadToFile(

LPUNKNOWN pCaller, 

LPCTSTR szURL,

LPCTSTR szFileName,

DWORD dwReserved,

LPBINDSTATUSCALLBACK lpfnCB

);

- LPUNKNOWN pCaller : ActiveX container에 대한 포인터

- LPCTSTR szURL : 다운받을 파일의 URL

- LPCTSTR szFileName : 다운받은 파일을 저장할 위치와 파일명

- dwReserved : reserved

- LPBINDSTATUSCALLBACK lpfnCB : IBindStatusCallback 포인터



메시지 훅 p287 


출처 : http://soen.kr/lecture/win32api/lecnew/11-3-2.htm

         http://soen.kr/



모르는 개념


프로시저란 ? -> 함수라고 생각하면된다.


모듈이란 ? (HMODULE)

인스턴스 핸들이란 ? (HINSTANCE ) 


모든 실행 파일과 DLL 파일은 프로세스의 메모리 공간 상에 로드될 때 고유의 인스턴스 핸들을 할당 받는다.

이 인스턴스 핸들은 WinMain의 첫번째 매개변수인 hInstance를 통해 전달된다.


많은 애플리케이션에서 WinMain의 hInstance 매개변수를 전역변수로 저장해 두고 사용한다.

아래와 같이 HMODULE형 인자를 요구하는 함수들이 있으며, HMODULE과 HINSTANCE는 완전 동일하다.

(16비트 윈도우에서 구분되었지만 지금은 혼용)

즉 함수마다 요구하는 값은 같지만 자료형을 다르게 해서 사용한다? 는 의미인듯


DWORD GetModuleFileName (HMODULE hInstModule, PTSTR pszPath, DWORD cchPath);


----------------------------------------------------------------------------------------------------------------

* BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpRes)

Dll이 로딩될때 가장 먼저 실행되는 함수


- HINSTANCE hInst : DLL의 인스턴스 핸들


- DWORD fdwReason : DLL 호출된 타이밍

(DLL_PROCESS_ATTACH 

 DLL_PROCESS_DETACH 

 DLL_THREAD_ATTACH

 DLL_THREAD_DETACH ) 


- LPVOID lpRes : 암시적 호출시 TRUE, 명시적 호출시 FALSE


(함수가 어느 DLL에 있는지 밝히지 않고 사용 -> 암시적 

 어느 DLL에 있는 함수인지를 밝히고 사용 -> 명시적)


---------------------------------------------------------------------------------------------------------------

훅 체인에 등록되어 메시지를 감시하는 함수를 훅 프로시저(Hook Procedure)라고 한다. 

훅 타입에 따라 훅 프로시저의 인수나 리턴값의 의미는 달라지지만 원형은 고정되어 있다. 


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

- int nCode : 훅프로시저에서 이 메시지를 어떻게 처리할 것인가? (음수이면 메시지를 처리하지않고 다음 훅 에게 전달)


- WPARAM wParam, LPARAM lParam : 전달된 메시지에 대한 추가정보(훅타입에따라 달라지므로 레퍼런스 참고)


----------------------------------------------------------------------------------------------------------------------

훅을 설치하는 함수

HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId )

- 훅 프로시저를 설치한 후 HHOOK 타입의 훅 핸들 리턴

- 에러 발생시 NULL 리턴


훅을 해제하는 함수

BOOL UnhookWindowsHookEx( HHOOK hhk );

- 해제하고자 하는 훅 핸들을 넘겨주면 됨. 훅을 설치한 프로그램은 종료되기 전에 반드시 훅 프로시저를 해제해 주어야 한다


----------------------------------------------------------------------------------------------------------------------------------------- 

훅 프로시저가 설치되면 해당 타입의 메시지는 목표 윈도우로 보내지기 전에

훅 프로시저에게 먼저 전달되는데 훅 프로시저는 메시지를 살펴본 후 특별한 이유가 없으면 

메시지를 훅 체인의 다음 훅 프로시저에게 전달해 주어야 한다.


메시지를 훅 체인의 다음 훅 프로시저에게 전달할때사용하는 함수


LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam)


- hhk는 현재 처리하고 있는 훅의 핸들인데 SetWindowsHookEx 함수가 리턴한 값이다. 

나머지 세 인수는 운영체제가 훅 프로시저에게 전달해준 인수들이다. 

훅 체인에 포함된 훅 프로시저의 목록은 운영체제가 직접 관리하기 때문에 

훅을 설치한 응용 프로그램은 다음 훅 프로시저의 번지를 따로 저장할 필요없이 

이 함수만 호출해 주면 훅 체인을 따라 모든 훅 프로시저가 순서대로 호출되며 최종적으로 목표 윈도우로 메시지가 전달될 것이다.



훅 프로시저는 전달 받은 메시지를 다음 훅 프로시저에게 꼭 전달해 주어야 할 의무는 없으며 

메시지를 아예 없애버리려면 전달하지 않아도 상관없으며 원하는 대로 변경할 수도 있다. 

물론 이 때는 메시지를 없애버리거나 변경한 후의 효과에 대해 확실히 책임질 수 있어야 한다. 

이 함수는 훅 체인에서 다음 훅 프로시저를 호출하고 훅 프로시저가 리턴하는 값을 다시 리턴해 주는데 

현재의 훅 프로시저는 이 리턴값을 또 그대로 리턴해 주어야 한다. 

그래서 훅 프로시저의 끝은 보통 return CallNextHookEx(...) 호출문이 온다.


-------------------------------------------------------------------------------------------------------------------------------

현재 실행되고 있는 프로세스의 이름을 얻어올때 사용하는 함수


DWORD WINAPI GetModuleFileName(HMODULE hModule, LPTSTR lpFilename, DWORD nSize)

- HMODULE hModule : 이름을 얻어올 프로세스의 핸들이지만, 보통 자신의 이름을 얻기위함으로 NULL로 사용


- lpFilename : 해당 모듈의 이름이 입력될 버퍼


- nSize : 입력한 크기 만큼 저장(오버플로우 방지)


------------------------------------------------------------------------------------------------------------------------------------

스트링에서 문자의 마지막 표시를 찾는 함수

가장 마지막 문자를 찾아준다.


char *strrchr(const char *str, int c)


ex) char str[10] = "dabcdefghi";

      char * p = NULL;

      p = strrchr(str, 'd');

-> p는 "defghi"



strchr인 r이 하나 빠진 함수는 처음 매칭 되는 문자열을 찾아준다.

--------------------------------------------------------------------------------------------------------------------------


__declspec(dllimport) : DLL로부터 제공받을 함수를 선언할때 사용

__declspec(dllexport) : 외부에 export할 함수를 선언할때 사용


+ Recent posts