블로그 이미지
ludwings

카테고리

분류 전체보기 (132)
WIN API (22)
워게임 (61)
만든것 (2)
메모 (39)
Total17,407
Today17
Yesterday3

작업관리자에서 메모장 종료하는 것을 막아보도록 terminateprocess를 후킹해봤다..

 

처음에 안됬던게 TerminateProcess(HANDLE hProcess, UINT uExitCode) 에서

 

hProcess를 이용하여 getprocessid 를 사용해 종료하려고 하는 프로세스의 id를 구해보려고 했으나 자꾸 0이 리턴 되었다..

 

알고보니 이 hProcess의 값은 작업관리자에서 OpenProcess 해줄때 옵션을 PROCESS_TERMINATE를 주어서 이 핸들로는  아무런 정보도 건지지 못한 것이고.. duplicatehandle을 사용하여 복사해준뒤 getprocessid를 사용하니까 정상적으로 동작했다.

 

정보 : http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=50&MaeulNo=20&no=487716&ref=487336

 

 

/*hook_terminateprocess code*/
#include 
#include 

#include 

#define DEF_PROCNAMEW L"notepad.exe"
#define DEF_KERNEL32 "Kernel32.dll"
#define DEF_TERMINATEPROCESS "TerminateProcess"

// global variable
BYTE g_pOrgBytes[5] = {0,};


DWORD CheckProcess(LPCTSTR szProcessName)
{
	HANDLE hSnapShot = INVALID_HANDLE_VALUE;
	PROCESSENTRY32 pe;
	DWORD dwPID;
	pe.dwSize = sizeof(PROCESSENTRY32);

	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);

	Process32First(hSnapShot, &pe);

	do 
	{
		dwPID = pe.th32ProcessID;
		if(dwPID < 100)
			continue;

		if(!lstrcmp(pe.szExeFile, szProcessName)) // 찾고자하는 프로세스가 있으면 
			return dwPID;

	} while (Process32Next(hSnapShot, &pe));

	CloseHandle(hSnapShot);

	return 0;
}

BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{
	FARPROC pfnOrg;
	DWORD dwOldProtect, dwAddress;
	BYTE pBuf[5] = {0xE9, 0, };
	PBYTE pByte;

	// 후킹 대상 API 주소를 구한다
	pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
	pByte = (PBYTE)pfnOrg;

	// 만약 이미 후킹 되어 있다면 return FALSE
	if( pByte[0] == 0xE9 )
		return FALSE;

	// 5 byte 패치를 위하여 메모리에 WRITE 속성 추가
	VirtualProtect((LPVOID)pfnOrg, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

	// 기존 코드 (5 byte) 백업
	memcpy(pOrgBytes, pfnOrg, 5);

	// JMP 주소 계산 (E9 XXXX)
	// => XXXX = pfnNew - pfnOrg - 5
	dwAddress = (DWORD)pfnNew - (DWORD)pfnOrg - 5;
	memcpy(&pBuf[1], &dwAddress, 4);

	// Hook - 5 byte 패치 (JMP XXXX)
	memcpy(pfnOrg, pBuf, 5);

	// 메모리 속성 복원
	VirtualProtect((LPVOID)pfnOrg, 5, dwOldProtect, &dwOldProtect);

	return TRUE;
}

BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
{
	FARPROC pFunc;
	DWORD dwOldProtect;
	PBYTE pByte;

	// API 주소 구한다
	pFunc = GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
	pByte = (PBYTE)pFunc;

	// 만약 이미 언후킹 되어 있다면 return FALSE
	if( pByte[0] != 0xE9 )
		return FALSE;

	// 원래 코드(5 byte)를 덮어쓰기 위해 메모리에 WRITE 속성 추가
	VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

	// Unhook
	memcpy(pFunc, pOrgBytes, 5);

	// 메모리 속성 복원
	VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);

	return TRUE;
}

typedef BOOL (WINAPI *PFTERMINATEPROCESS)(HANDLE hProcess, UINT uExitCode);

BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode)
{
	FARPROC pFunc;
	unhook_by_code(DEF_KERNEL32, DEF_TERMINATEPROCESS, g_pOrgBytes);
	BOOL bRet;
	
	DWORD dwnotepadid = CheckProcess(DEF_PROCNAMEW);
	DWORD dwcurrentid;
	
	HANDLE outprocess;
	BOOL bRet= DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &outprocess, PROCESS_ALL_ACCESS, FALSE, 0);

	if(bRet)
	{
		dwcurrentid = GetProcessId(outprocess);
		bRet = FALSE;
	}
	else
	{
		goto __MYTERMINATEPROCESS_END;
	}


	if(dwnotepadid == dwcurrentid) // notepad. exe에 주입할거니까 ㅋㅋ
	{
		bRet = FALSE;
		goto __MYTERMINATEPROCESS_END;
	}

	pFunc = GetProcAddress(GetModuleHandleA(DEF_KERNEL32), DEF_TERMINATEPROCESS);

	bRet = ((PFTERMINATEPROCESS)pFunc)(hProcess, uExitCode);
	
__MYTERMINATEPROCESS_END:
	hook_by_code(DEF_KERNEL32, DEF_TERMINATEPROCESS, (PROC)MyTerminateProcess, g_pOrgBytes);

	return bRet;
}

BOOL WINAPI DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved )
{
	switch(dwReason)
	{
	case DLL_PROCESS_ATTACH:
		hook_by_code(DEF_KERNEL32, DEF_TERMINATEPROCESS, 
			(PROC)MyTerminateProcess, g_pOrgBytes);
		break;
	case DLL_PROCESS_DETACH:		
		unhook_by_code(DEF_KERNEL32, DEF_TERMINATEPROCESS, 
			g_pOrgBytes);
		break;
	}
	return TRUE;
}
Posted by ludwings

댓글을 달아 주세요

  1. 2014.01.10 15:41 신고 QBeom  댓글주소  수정/삭제  댓글쓰기

    소스 변수명들이 극-혐이네요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함