블로그 이미지
ludwings

카테고리

분류 전체보기 (130)
WIN API (22)
워게임 (61)
만든것 (2)
메모 (37)
Total18,086
Today0
Yesterday3

'2014/01'에 해당되는 글 7건

  1. 2014.01.18 티스토리 초대장 dream (8)
  2. 2014.01.10 코드인젝션시 주의사항 (7)
  3. 2014.01.09 winapi] 메모장 종료 막기 (2)
  4. 2014.01.09 winapi] setprivilege
  5. 2014.01.08 winapi] 64bit dll injector (2)
  6. 2014.01.02 win api] lol 실행 차단
  7. 2014.01.02 메모

10개있는데 댓글달아주세여 dream

Posted by ludwings

댓글을 달아 주세요

  1. 2014.01.18 17:54  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  2. 2014.02.01 20:18  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  3. 2014.03.17 15:25  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  4. 2014.05.16 14:50  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

출처 : http://dstein.egloos.com/viewer/2335201

 

내용2 : http://sungod0.egloos.com/viewer/3920875

이 내용은 공부할려고 reversecore님 소스 써봣는데 안돼가지고... 이게머지.. 하면서 찾아다니다가 알게된 내용이다..

 

WriteProcessMemory를 이용하여 인젝션 시킬때 release 모드로 실행하면 정상 동작하지만 debug 모드로 컴파일된 파일로 실행하면 crash를 일으킨다고 한다. 그 설명은.. 저기 출처에 잘되어있다..

 

간단하게 debug 모드에서는 런타임 체크 코드가 자동으로 삽입되어있는데 이코드가 주입되서 실행되면 아무것도 없는 주소 공간을 참조하거나 실행해서 crash가 난다고한다..

 

그래서 알아본 debug 모드와 release 모드..

 

vs 설정에 debug 모드와 release 모드가 있는데..

 

debug 모드의 특징은

1. 파일 용량이 크고

2. 실행 속도가 느린 반면

3. 디버깅이 가능하다는 점ㅇ.

 

release 모드는 

1. 파일 용량이 작고

2. 실행 속도가 디버그 모드보다 빠르고

3. 디버깅이 불가능 하다.

 

둘의 차이점은 디버깅 정보를 실행코드에 넣냐 안넣냐 ..

그리고 동적으로 메모리를 할당받앗을떄 guard byte(0xfd) ㄹ를 자동으로 추가할당하여 잘못된 접근에도 crash가 일어나지 않을수도 있다. 

릴리즈에서는 초기화 시키지 않지만 디버그 모드에서는

초기화 하지않은 포인터 메모리 변수를 0xccccccc로 채우고 deallocate를 하면 0xdd로 채워진다.

 

주의할점도 release 시에는 변수 선언과 동시에 초기화 해주는게 좋고.'

debug mode에 방어용 공간을 확보하는것..

 

그 안됬던 애는 아래에 있다

 

 

 요거요거 릴리즈일떄

 

 

 

 

요거요거 디버그 일때

 

 

#include 
#include 
#include 


typedef HMODULE (WINAPI *PFLOADLIBRARYA)( LPCSTR lpLibFileName );
typedef FARPROC (WINAPI *PFGETPROCADDRESS)( HMODULE hModule, LPCSTR lpProcName );
typedef BOOL (WINAPI *PFTERMINATEPROCESS)( HANDLE hProcess, UINT uExitCode );
typedef int (WINAPI *PFMESSAGEBOXA) 
	(
	HWND hWnd,
	LPCSTR lpText,
	LPCSTR lpCaption,
	UINT uType
	);

int g_dwPID;

BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode);

typedef struct _THREAD_PARAM
{
	FARPROC pFunc[2]; // loadlibrary , getprocaddress
	char szBuf[4][128];      // dll, procname, mesaagebox param
} THREAD_PARAM, *PTHREAD_PARAM;
DWORD WINAPI ThreadProc(LPVOID lParam)
{
	// lParam 은 내가 만들어둔 구조체야... 이 구조체에 함수 주소를 구하기 위해 필수적인
	// LoadLibrary 주소와, getprocaddress 주소를 가지고 있다.
	PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
	HMODULE hMod = NULL;
	FARPROC pFunc = NULL;

	hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);
	if(!hMod)
	{
		return 1;
	}

	pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);
	if(!pFunc)
	{
		return 1;
	}

	((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);

	return 0;
}
BOOL Inject_code();

int main(int argc, char* args[])
{
	if(argc != 2)
	{
		printf("How to use ? \n");
		printf("%s [pid]\n", args[0]);

		return 1;
	}

	g_dwPID = atoi(args[1]);

	if(g_dwPID <= 0)
	{
		printf("check PID\n");
		return 1;
	}

	Inject_code(); // g_dwPID 사용.

	return 0;
}

BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode)
{
	// 묻지도 따지지도 않고 return 해드립니다.
	return FALSE;
}

BOOL Inject_code()
{
	HMODULE hMod = NULL;
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;

	LPVOID pRemoteBuf[2];
	DWORD dwSize = 0;
	BOOL bRet = FALSE;

	THREAD_PARAM param = {0, };

	hMod = GetModuleHandleA("kernel32.dll");
	if(!hMod)
		return FALSE;

	param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
	param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
	strcpy(param.szBuf[0], "user32.dll");
	strcpy(param.szBuf[1], "MessageBoxA");
	strcpy(param.szBuf[2], "www.ludwings.tistory.com");
	strcpy(param.szBuf[3], "ludwings");

	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_dwPID);
	if(!hProcess)
	{
		printf("OpenProcess() failed !\n");
		return FALSE;
	}
	dwSize = sizeof(THREAD_PARAM);
	pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if(!pRemoteBuf[0])
	{
		printf("VirtualAllocEx() Failed !\n");
		return FALSE;
	} // 사용이 필요한 인자들 메모리 공간 확보.. 이제 write 해줘야지

	if( !WriteProcessMemory(hProcess, pRemoteBuf[0], (LPVOID)¶m, dwSize, NULL))
	{
		printf("WriteProcessMemory Failed ! \n");
		return FALSE;
	}
	// 이제 중요한 createremotethread 해줄 함수를 상대 공간에 적어줘야겟지
	dwSize = (DWORD)Inject_code - (DWORD)ThreadProc;
	pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

	if(!pRemoteBuf[1])
	{
		printf("VirtualAllocEx() Failed !\n");
		return FALSE;
	}

	if( !WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)ThreadProc, dwSize, NULL))
	{
		printf("WriteProcessMemory Failed ! \n");
		return FALSE;
	}

	hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
		pRemoteBuf[0], 0, NULL);

	WaitForSingleObject(hThread, INFINITE);

	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;
}

//*/

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

코드인젝션시 주의사항  (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
아나 하이라이터 ㅡㅡ  (0) 2013.11.01
Posted by ludwings

댓글을 달아 주세요

  1. 2014.01.13 10:09 신고 QBeom  댓글주소  수정/삭제  댓글쓰기

    reversecore 님 블로그꺼 똑같이 베끼셨네요 ㅡㅡ;

  2. 2014.03.27 20:50 NINA  댓글주소  수정/삭제  댓글쓰기


    초대장 부탁드립니다~~
    티스토리에서 활동하고싶어요
    ninapark5577@daum.net

  3. 2014.04.10 10:38  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  4. 2014.05.16 14:50  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

작업관리자에서 메모장 종료하는 것을 막아보도록 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  댓글주소  수정/삭제  댓글쓰기

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

/*
시스템 수준의 디버깅 목적으로 제공된다..

This privilege allows the caller all access to the process, including the ability to call TerminateProcess(),
CreateRemoteThread(), and other potentially dangerous Win32 APIs on the target process.

보안상의 이유로 액세스 토큰을 사용한다.
이 권한을 상승 시키기 위해서
1. openprocesstoken() with TOKEN_ADJUST_PRIVILEGE and TOKEN_QUERY flags
2. LookupPrivilegeValue() to get the LUID of the privilege i want to adjust
3. AdjustTokenPrivileges() to adjust the Tokens
4. DO whatever
5. Call AdjustTokenPrivileges() again to set the old privileges back
6. close the token handle
*/

#define RTN_USAGE 1
#define RTN_ERROR 13

#include 
#include 

BOOL SetPrivilege(
	HANDLE hToken,          // token handle
	LPCTSTR Privilege,      // Privilege to enable/disable
	BOOL bEnablePrivilege   // TRUE to enable.  FALSE to disable
	);

void DisplayError(LPTSTR szAPI);

int main(int argc, char *argv[])
{
	HANDLE hProcess;
	HANDLE hToken;
	int dwRetVal=RTN_OK; // assume success from main()

	// show correct usage for kill
	if (argc != 2)
	{
		fprintf(stderr,"Usage: %s [ProcessId]\n", argv[0]);
		return RTN_USAGE;
	}

	if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
	{
		if (GetLastError() == ERROR_NO_TOKEN)
		{
			if (!ImpersonateSelf(SecurityImpersonation))
				return RTN_ERROR;

			if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
				DisplayError("OpenThreadToken");
				return RTN_ERROR;
			}
		}
		else
			return RTN_ERROR;
	}

	// enable SeDebugPrivilege
	if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
	{
		DisplayError("SetPrivilege");

		// close token handle
		CloseHandle(hToken);

		// indicate failure
		return RTN_ERROR;
	}

	// open the process
	if((hProcess = OpenProcess(
		PROCESS_ALL_ACCESS,
		FALSE,
		atoi(argv[1]) // PID from commandline
		)) == NULL)
	{
		DisplayError("OpenProcess");
		return RTN_ERROR;
	}

	// disable SeDebugPrivilege
	SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);

	if(!TerminateProcess(hProcess, 0xffffffff))
	{
		DisplayError("TerminateProcess");
		dwRetVal=RTN_ERROR;
	}

	// close handles
	CloseHandle(hToken);
	CloseHandle(hProcess);

	return dwRetVal;
}
BOOL SetPrivilege(
	HANDLE hToken,          // token handle
	LPCTSTR Privilege,      // Privilege to enable/disable
	BOOL bEnablePrivilege   // TRUE to enable.  FALSE to disable
	)
{
	TOKEN_PRIVILEGES tp;
	LUID luid;
	TOKEN_PRIVILEGES tpPrevious;
	DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);

	if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;

	// 
	// first pass.  get current privilege setting
	// 
	tp.PrivilegeCount           = 1;
	tp.Privileges[0].Luid       = luid;
	tp.Privileges[0].Attributes = 0;

	AdjustTokenPrivileges(
		hToken,
		FALSE,
		&tp,
		sizeof(TOKEN_PRIVILEGES),
		&tpPrevious,
		&cbPrevious
		);

	if (GetLastError() != ERROR_SUCCESS) return FALSE;

	// 
	// second pass.  set privilege based on previous setting
	// 
	tpPrevious.PrivilegeCount       = 1;
	tpPrevious.Privileges[0].Luid   = luid;

	if(bEnablePrivilege) {
		tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
	}
	else {
		tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
			tpPrevious.Privileges[0].Attributes);
	}

	AdjustTokenPrivileges(
		hToken,
		FALSE,
		&tpPrevious,
		cbPrevious,
		NULL,
		NULL
		);

	if (GetLastError() != ERROR_SUCCESS) return FALSE;

	return TRUE;
}
BOOL SetPrivilege( 
	HANDLE hToken,  // token handle 
	LPCTSTR Privilege,  // Privilege to enable/disable 
	BOOL bEnablePrivilege  // TRUE to enable. FALSE to disable 
	) 
{ 
	TOKEN_PRIVILEGES tp = { 0 }; 
	// Initialize everything to zero 
	LUID luid; 
	DWORD cb=sizeof(TOKEN_PRIVILEGES); 
	if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
		return FALSE; 
	tp.PrivilegeCount = 1; 
	tp.Privileges[0].Luid = luid; 
	if(bEnablePrivilege) { 
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
	} else { 
		tp.Privileges[0].Attributes = 0; 
	} 
	AdjustTokenPrivileges( hToken, FALSE, &tp, cb, NULL, NULL ); 
	if (GetLastError() != ERROR_SUCCESS) 
		return FALSE; 

	return TRUE;
}
void DisplayError(
	LPTSTR szAPI    // pointer to failed API name
	)
{
	LPTSTR MessageBuffer;
	DWORD dwBufferLength;

	fprintf(stderr,"%s() error!\n", szAPI);

	if(dwBufferLength=FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		GetLastError(),
		GetSystemDefaultLangID(),
		(LPTSTR) &MessageBuffer,
		0,
		NULL
		))
	{
		DWORD dwBytesWritten;

		// 
		// Output message string on stderr
		// 
		WriteFile(
			GetStdHandle(STD_ERROR_HANDLE),
			MessageBuffer,
			dwBufferLength,
			&dwBytesWritten,
			NULL
			);

		// 
		// free the buffer allocated by the system
		// 
		LocalFree(MessageBuffer);
	}
}
Posted by ludwings

댓글을 달아 주세요

winapi] 64bit dll injector

WIN API / 2014. 1. 8. 23:58

이거도해봐야지...

 

지금 dll injector는 32bit dll을ㅇ 32bit process에 인젝트하는 것만 ㄷ ㅗ ㅣ는데..

 

아니근데 64비트 dll은 어케 만드는거지? 구성관리자에서 x64로 해놓고 컴파일해도 32비트로 생성되는데 dll이?

 

일단 64bit 프로세스 만들어보고 64bit dll 만들어본 다음에 인젝션 시켜봐야지...

 

우선 reversecore에서 64bit injector하고 64bit dll 가져와서 실험해봣다.. 그런데 fail한다 ㅋㅋ 일단 dll은 64bit가 맞으니 injector에 문제가 있는거 같고

 

내가 만든 32bit에서 되던 dll injector로 reversecore에서 가져온 dummy64.dll 을 64bit 메모장에 인젝션 시도해봤는데 안된다 .. 그렇다 나의 인젝터에도 문제가 있었던 것이다..

 

그렇다면 할일..

1. 테스트용으로 64bit 프로세스 만들어보고

2. 64bit dll 만들어내고

3. 인젝터 수정하거나 만들기

 

--

 

1. 64프로세스 됨

 

 

 

2. 근데 64bit dll 이면 이런창 한번 떠야하는데

 

 

 

x64로 설정하고 해도 안뜸ㅋㅋ

 

ㅅㅂ 알고보니까 개삽질이야 프로젝트\debug\64.dll 이 아니라 프로젝트\x64\debug\64.dll 여기 들어있었네 ㅋㅋㅋㅋㅋㅋㅋ 이힣ㅅ

 

3.인젝터는..

'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

댓글을 달아 주세요

  1. 2014.03.27 02:17 고구마  댓글주소  수정/삭제  댓글쓰기

    저도 안되서 계속 코드 수정하고 컴파일하고 ... 결국 님 블로그 보고 알게 됐어요.

    x64 폴더가 따로 있더라는........... -_- 삽질 멈추게 해줘서 고맙습니다!

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

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

코드인젝션시 주의사항  (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
아나 하이라이터 ㅡㅡ  (0) 2013.11.01
Posted by ludwings

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함