블로그 이미지
ludwings

카테고리

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

win api] lol 실행 차단

WIN API / 2014. 1. 2. 22:28

그냥 공부하는 겸해서 만들어보려고 한다.

 

버전은 두가지 인데

 

첫번째는 유저단에서 돌아가고, 단순하게 전역으로 zwsysteminformation을 후킹함으로써 이 프로세스가 숨겨지도록 하며, 대기하였다가 lol 프로세스가 실행되면 강제로 종료시킨다..

 

두번째는 큐밤아카데미 선생님이 숙제로 내주신 커널 단에서 lol 프로세스를 종료하는건데 처리는 유저단과 비슷하지만 커널단에서 처리... 처음이지만 한번 해봐야겠다.

 

 

 

reversecore님의 블로그에서 많은 도움을 얻었따~

 

2014-1-2 작성시작

이름은 LOL_HAJIMARUYOT으로 해야지 엘오엘하지마루욧

 

기본적으로 프로세스를 숨겨주기위해 전역으로 stealth.dll을 인젝션 해 줄 생각이다... 전에 작성했던 dll injector&ejector의 소스를 이용해서 쉽게 만들수 있었고.. stealth.dll 을 작성해야한다..

 

.exe 의 기능

실행하면 현재 실행중인 모든 프로세스에 stealth.dll 을 인젝션 시킨다.

 

stealth.dll

이 분은 zwsysteminformation을 코드패치를 통해서 후킹한다... 내가원하는 프로세스라면 프로세스간 연결을 끊어서 숨겨버린다.

 

 

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

1/3

변경

stealth.dll -> LOL_HAJIMARUYOT.dll

LOL_HAJIMARUYOT.exe -> AllProcessInjector.exe

 

잘못생각했던 점

1. injector 프로세스가 계속돌면서 새로운 프로세스가 생성되면 인젝션 시켜줘야 된다고 생각했다.

   그런데 이건 createprocessa, createprocessw 를 후킹해두면 어떤 부모프로세스(explorer.exe) 등이 프로세스를 생성할때 자동으로 stealth.dll을 인젝션 해줌과 동시에 생성되는 프로세스 이름을 확인하고 종료해버릴수도 있다.

   그럼 프로세스를 은폐하는 기술은 필요가 없으며 모든 프로세스의 dll을 ejection 해줘야 lol 차단을 종료 할 수 있다.

 

2. stealth 기능

   위에서 말한것과 같이 stealth기능은 필요가 업ㅈㅅ이 dll 에서 모두 처리하고 injection하는 프로세스느는 종료되기 떄문에 createprocess 함수들만 후킹하면 된다.

 

우선 모든프로세스에 dll을 인젝션하는 소스당

 

-- allprocessinjector 소스 --

 

소스출처 : reversecore.com

#include 
#include 
#include 

#define DllPath L"c:\\stealth.dll"

enum { INJECTION_MODE = 0 , EJECTION_MODE };

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath);
BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath);
BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath);
DWORD CheckProcess(LPCTSTR szProcessName);

int APIENTRY WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{
	int nMode = INJECTION_MODE;
	
	InjectAllProcess(nMode, DllPath);

	if(nMode == EJECTION_MODE)
		return 0;

	while(1)
	{
		DWORD dwPID = CheckProcess(L"notepad.exe"); // process to kill
		if(dwPID != 0)
		{
			HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
			TerminateProcess(hProc, 0);

			CloseHandle(hProc);
		}

		Sleep(5000); // 5초에 한번검사
	}

	return 0;
}

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	HANDLE hProcess, hThread;
	LPVOID pRemoteBuf;
	DWORD dwBufSize = (DWORD)(lstrlen(szDllPath)+1)*sizeof(TCHAR);
	LPTHREAD_START_ROUTINE pThreadProc;


	if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
	{
		return FALSE;
	}

	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, 
		MEM_COMMIT, PAGE_READWRITE);

	WriteProcessMemory(hProcess, pRemoteBuf, 
		(LPVOID)szDllPath, dwBufSize, NULL);

	pThreadProc = (LPTHREAD_START_ROUTINE)
		GetProcAddress(GetModuleHandle(L"kernel32.dll"), 
		"LoadLibraryW");

	hThread = CreateRemoteThread(hProcess, NULL, 0, 
		pThreadProc, pRemoteBuf, 0, NULL);

	WaitForSingleObject(hThread, INFINITE);	

	VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;
}

BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	BOOL                    bMore = FALSE, bFound = FALSE;
	HANDLE                  hSnapshot, hProcess, hThread;
	MODULEENTRY32           me = { sizeof(me) };
	LPTHREAD_START_ROUTINE  pThreadProc;

	if( INVALID_HANDLE_VALUE == 
		(hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)) )
		return FALSE;

	bMore = Module32First(hSnapshot, &me);
	for( ; bMore ; bMore = Module32Next(hSnapshot, &me) )
	{
		if( !_tcsicmp(me.szModule, szDllPath) || 
			!_tcsicmp(me.szExePath, szDllPath) )
		{
			bFound = TRUE;
			break;
		}
	}

	if( !bFound )
	{
		CloseHandle(hSnapshot);
		return FALSE;
	}

	if( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
	{
		CloseHandle(hSnapshot);
		return FALSE;
	}

	pThreadProc = (LPTHREAD_START_ROUTINE)
		GetProcAddress(GetModuleHandle(L"kernel32.dll"), 
		"FreeLibrary");
	hThread = CreateRemoteThread(hProcess, NULL, 0, 
		pThreadProc, me.modBaseAddr, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);	

	CloseHandle(hThread);
	CloseHandle(hProcess);
	CloseHandle(hSnapshot);

	return TRUE;
}

BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath)
{
	DWORD                   dwPID = 0;
	HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;
	PROCESSENTRY32          pe;

	// Get the snapshot of the system
	pe.dwSize = sizeof( PROCESSENTRY32 );
	hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );

	// find process
	Process32First(hSnapShot, &pe);
	do
	{
		dwPID = pe.th32ProcessID;

		// 시스템의 안정성을 위해서
		// PID 가 100 보다 작은 시스템 프로세스에 대해서는
		// DLL Injection 을 수행하지 않는다.
		if( dwPID < 100 )
			continue;

		if( nMode == INJECTION_MODE )
			InjectDll(dwPID, szDllPath);
		else
			EjectDll(dwPID, szDllPath);
	} while( Process32Next(hSnapShot, &pe) );

	CloseHandle(hSnapShot);

	return TRUE;
}

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;
}



 

// -- stealth.dll // #include #include #define STATUS_SUCCESS (0x00000000L) #define DEF_NTDLL ("ntdll.dll") #define DEF_ZWQUERYSYSTEMINFORMATION ("ZwQuerySystemInformation") #define DEF_HIDEPROCNAMEA ("AllProcessInjector.exe") #define DEF_HIDEPROCNAMEW (L"AllProcessInjector.exe") //나중에 쓰일지도 모른다. //TCHAR g_szKillProcName[MAX_PATH] = {0, }; // save origin op code s BYTE g_pOrgBytes[5] = {0, }; typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemProcessInformation = 5, SystemProcessorPerformanceInformation = 8, SystemInterruptInformation = 23, SystemExceptionInformation = 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45 } SYSTEM_INFORMATION_CLASS; typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; BYTE Reserved1[52]; PVOID Reserved2[3]; HANDLE UniqueProcessId; PVOID Reserved3; ULONG HandleCount; BYTE Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes) { FARPROC pfnOrg; DWORD dwOldProtect, dwAddress; BYTE pBuf[5] = { 0xE9, 0, }; PBYTE pByte; pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName); pByte = (PBYTE)pfnOrg; if(pByte[0]== 0xe9) return FALSE; VirtualProtect((LPVOID)pfnOrg, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect); memcpy(pOrgBytes, pfnOrg, 5); // pOrgBytes에 백업 해둔다. dwAddress = (DWORD)pfnNew - (DWORD)pfnOrg - 5; memcpy(&pBuf[1], &dwAddress, 4); 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 NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION) ( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); NTSTATUS WINAPI MyZwQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength) { NTSTATUS status; FARPROC pFunc; PSYSTEM_PROCESS_INFORMATION pCur, pPrev; unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes); pFunc = GetProcAddress(GetModuleHandleA(DEF_NTDLL), DEF_ZWQUERYSYSTEMINFORMATION); // 우선 실행해. status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); // 그리고 그결과를 확인해 if(status != STATUS_SUCCESS) goto __NTQUERYSYSINFORMATION_END; if(SystemInformationClass == SystemProcessInformation) { // 이거 프로세스 정보 가지고 있을때 pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation; while(1) { if(pCur->Reserved2[1] != NULL) { if(!wcscmp((WCHAR *)pCur->Reserved2[1], DEF_HIDEPROCNAMEW)) { if(pCur->NextEntryOffset == 0) pPrev->NextEntryOffset = 0; else pPrev->NextEntryOffset += pCur->NextEntryOffset; } else pPrev = pCur; } if(pCur->NextEntryOffset == 0) break; pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset); } } __NTQUERYSYSINFORMATION_END: hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, (PROC)MyZwQuerySystemInformation, g_pOrgBytes); return status; } BOOL WINAPI DllMain(_In_ HANDLE _HDllHandle, _In_ DWORD _Reason, _In_opt_ LPVOID _Reserved) { char szCurProc[MAX_PATH] = {0,}; char *p = NULL; GetModuleFileNameA(NULL, szCurProc, MAX_PATH); p = strchr(szCurProc, '\\'); if((p!=NULL)&&!stricmp(p+1, DEF_HIDEPROCNAMEA)) return TRUE; switch(_Reason) { case DLL_PROCESS_ATTACH: hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, (PROC)MyZwQuerySystemInformation, g_pOrgBytes); break; case DLL_PROCESS_DETACH: unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes); break; } return TRUE; }

 

 

현재 내환경은 win 8 64bit 환경이여서 all injection 되는지 확인해보지 못해서... 가상머신 xp 에서 돌려봣는데.. 안됀다.. 왜이러지..? 애초에 32비트 환경이아니면 만들기 힘들잖아?

 

-- 14/01/07 --

일단 하긴했는데 문제가 있ㅇ당

테스트용으로 메모장이 켜지면 종료되게 했다.

그런데 myresumethread에서 예외처리안했더니 시도때도 없이 막 디버깅하라고듬

 

소스들임

 

 

 

 

stealth.cpp

 

AllProcessInjector.cpp

 

 

어차피 목표는 유저단이 아니라 커널단에서 막는거니..  이 정도에서 넘어가자 커널로

 

'WIN API' 카테고리의 다른 글

cpp 객체리턴 액세스 위반 에러  (6) 2015.04.28
winapi] 64bit dll injector  (2) 2014.01.08
win api] lol 실행 차단  (0) 2014.01.02
Dll Injector, Dll Ejector  (0) 2013.10.11
#pragma once  (0) 2013.09.04
WINAPI ] 간단한 채팅2  (0) 2013.05.07
Posted by ludwings

댓글을 달아 주세요

메모

메모 / 2014. 1. 2. 09:36
그 입문서를 모두 읽어 본 후에 비로소 WINDOWS DRIVER MODEL 을 읽는다면 아마도 이 책이 좋다~ 라고 생각할 것이다. (물론 본인의 생각은 아니다. 고수(?)의 의견을 빌리자면 그렇단 얘기다.)

아래 링크는 쉽게 드라이버의 세계에 입문하기 위해서 많은 도움을 주는 아주 좋은 조언자이니 꼭 읽어보길 바란다.


[초보자를 위한 Kernel based windows rootkit -1부]
http://beist.org/research/public/beginnerwinrootkit/beginnerwinrootkit.pdf
- beist 랩에서 발견한 기초룻킷 강좌. 여기에 간단하게 드라이버 제작에 대한 설명이 포함되어 있다. 지금 읽으면서 처음 드라이버를 빌드할 수 있도록 가이드라인을 제시해주고 있다.


[드라이버 쪼물딱 거리기 1~3탄]
http://somma.egloos.com/2710282 <== 1탄
http://somma.egloos.com/2710303 <== 2탄
http://somma.egloos.com/2731001 <== 3탄
- 유명한 쏘마님의 드라이버 입문 강좌이다.

[비주얼스튜디오에서 DDK Build를...]
http://hongyver.pe.kr/ttblog/705
- 커맨드라인을 벗어난 빌드환경을 구성하는데 많은 도움이 된다고 한다. 물론 해볼 예정.

[MS 사이트에서 찾은 기초자료]
http://download.microsoft.com/download/5/D/6/5D6EAF2B-7DDF-476B-93DC-7CF0072878E6/DrvDev_Intro.doc
- 드라이버 빌드에 대한 기본적인 설명 문서

 

출처

http://ggil.tistory.com/category/%EB%B0%A5%EC%A4%84%ED%8C%81?page=2

'메모' 카테고리의 다른 글

자전거 국토종주  (0) 2015.10.09
코드인젝션시 주의사항  (7) 2014.01.10
메모  (0) 2014.01.02
Windbg 사용, 설정  (0) 2013.12.24
JAVA Error occurred during initialization of VM 문제해결  (0) 2013.12.19
메모  (2) 2013.11.28
Posted by ludwings

댓글을 달아 주세요

한.. 한달정도 틈틈히 했는데 재밌었다... 처음으로 올클해봣슴 걔꿀!

님들도해보세여 재밋음 저같은 허접도 올클가능! 추천해요 11등!

 

suninatas.com

'워게임 > 기타' 카테고리의 다른 글

suninatas 올클리어~~  (4) 2013.12.27
suninatas 26번  (0) 2013.12.27
suninatas 24 25  (0) 2013.12.19
suninatas 23번 blind sql injection  (0) 2013.12.17
suninatas 22번 blind sql injection  (0) 2013.12.16
b1inder.dothome.co.kr ] Crypto 4  (1) 2013.12.04
Posted by ludwings

댓글을 달아 주세요

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

    이야 빡고수시네 ㄷㄷ

  2. 2014.05.20 11:19 러드윙스  댓글주소  수정/삭제  댓글쓰기

    우와! 멋저요! 나이스 러드윙스님!!!

최근에 달린 댓글

최근에 받은 트랙백

글 보관함