somma 님이 만든 지뢰찾기 핵이다. thread injection이라는 기법을 사용하여 원격의 프로세스에 원하는 코드를 실행시킨다고 한다.
http://somma.egloos.com/2881725
기존 소스에서 프로세스를 찾아주는 코드와
증분링크테이블(ILT)체크를 위한 조건을 추가하였다.(http://hongyver.pe.kr/ttblog/entry/증분링크)
================================================================================================
__declspec( naked )
DWORD __stdcall injetor_stub(void* pBlock)
{
__asm /* prolog */
{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
__asm
{
mov eax, 0x0A
push eax
mov eax, 0x01002F80
call eax
}
__asm /* epilog */
{
xor eax, eax // always return 0 (33 C0)
mov esp, ebp
pop ebp
/* epilog signature */
xor eax, eax
xor eax, eax
ret 4 // 0xC3
}
}
int main(int argc, char* argv[])
{
HWND hwnd;
DWORD dwPid;
hwnd = FindWindow(0, "지뢰 찾기");
//지뢰찾기게임이 열려있을경우 윈도우 핸들러를 얻는다.
GetWindowThreadProcessId(hwnd, &dwPid);
//알아낸 핸들러 값을 통해 지뢰찾기 프로세스ID를 얻는다.
HANDLE hProc = OpenProcess(
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
dwPid);
//지뢰찾기 프로세스에 대한 핸들을 얻는다.
DWORD FunctionRVA = (DWORD)injetor_stub;
if (FunctionRVA < 0x80000000 && *(PBYTE)FunctionRVA == 0xE9)
{
FunctionRVA = ((DWORD)(FunctionRVA) + (*(DWORD *)((PBYTE)FunctionRVA+1)) + 5);
}
//삽입할 함수(injetor_stub)의 주소값을 구한다.
//컴파일시 증분링크 테이블이 존재하면 injetor_stub은 증분링크 주소를 나타내기 때문에
//정확하게 함수가 정의된 주소를 알려주기 위한 코드이다.
int proc_size = 51;
// 삽입할 코드사이즈(대충;;)
char* proc_buf = (char *) VirtualAllocEx( hProc,
0,
proc_size,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
// 지뢰찾기 프로세스에 51만큼 메모리공간을 할당한다.
if (hProc == NULL)
{
printf("openprocess error");
}
DWORD dwBytesWritten = 0;
if (0 == WriteProcessMemory(hProc,
proc_buf,
(char *)FunctionRVA,
proc_size,
&dwBytesWritten))
{
printf("writeprocessmemory error");
}
// 할당한 메모리영역에 삽입할 코드를 입력한다.
DWORD dwTid = 0;
HANDLE hThread = CreateRemoteThread( hProc,
NULL,
0,
(LPTHREAD_START_ROUTINE)proc_buf,
NULL,
CREATE_SUSPENDED,
&dwTid);
if(hThread==0)
{
printf("createremotethread error");
}
//지뢰찾기 프로세스에 스레드생성
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread); hThread = NULL;
VirtualFreeEx(hProc, proc_buf, proc_size, MEM_RELEASE);
proc_buf = NULL;
CloseHandle(hProc); hProc = NULL;
return 0;
}
================================================================================================