티스토리 뷰


#include <windows.h>

#include <stdio.h>
#include <conio.h>
#include <typeinfo.h>

// 1. 윈도우의 번호를 안다면 해당 윈도우를 조작할 수 있다.

#if 0
int main(){

	HWND hwnd = FindWindow(0, "계산기");

	printf("윈도우 번호 : %x\n", hwnd);
	getch();

	MoveWindow(hwnd, 10, 10, 300, 300, TRUE);
	getch();

	ShowWindow(hwnd, SW_HIDE);
	getch();
	ShowWindow(hwnd, SW_SHOW);
	getch();
	SetMenu(hwnd, 0);
	getch();
	HRGN h = CreateEllipticRgn(0, 0, 300, 300);
	SetWindowRgn(hwnd, h, TRUE);

	return 0;
}
#endif

#if 0
int main(){

	HWND hwnd = FindWindow("Shell_TrayWnd", 0);

	printf("윈도우 번호 : %x\n", hwnd);
	getch();

	MoveWindow(hwnd, 10, 10, 300, 300, TRUE);
	getch();

	ShowWindow(hwnd, SW_HIDE);
	getch();
	ShowWindow(hwnd, SW_SHOW);
	getch();
	SetMenu(hwnd, 0);
	getch();
	HRGN h = CreateEllipticRgn(0, 0, 300, 300);
	SetWindowRgn(hwnd, h, TRUE);

	return 0;
}
// 핸들 갖고오는 함수
// FindWindow()
// WindowFromPoint()
#endif


// 속성 변경하기, 윈도우는 구조체
#if 0
void ModifyStyle(HWND hwnd, UINT remove, UINT add){

	int style = GetWindowLong(hwnd, GWL_STYLE);

	style = style | add;
	style = style & ~remove;

	SetWindowLong(hwnd, GWL_STYLE, style);

	SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);

}

void main(){

	HWND hwnd;
	hwnd = FindWindow(0, "계산기");
	getch();
	ModifyStyle(hwnd, WS_CAPTION, WS_THICKFRAME);
}
#endif


// HWND의 정체는 무엇일까?
// 1. 32비트 정수이므로 아래 처럼 하면 어떨까?

#if 0

typedef unsigned int HWND;
typedef unsigned int HICON;

void MoveWindow(HWND hwnd, int x, int y){

}

void main(){

	HICON hIcon = 0;
	MoveWindow(hIcon, 10, 10);

}

#endif

// 핸들 타입 받아오기
#if 0

int main(){

	printf("%s\n", typeid(HWND).name());
	printf("%s\n", typeid(HANDLE).name());
	printf("%s\n", typeid(DWORD).name());

}

#endif

// 프로세스 -> 윈도우만듦 -> 윈도우핸들이 생김
// 즉 프로세스의 핸들을 잡는게 낳음
// 프로세스는 아이디가 있음 PID
// 하지만 아이디만으로는 할 수 없음
// 그렇기 때문에 핸들을 요구해야함 (핸들발급) 그럼 모든것을 할 수 있음.


// ProcessID
#if 0

int main(){

	HWND hwnd = FindWindow(0, "계산기");
	
	
	// 특정 윈도우를 만든 프로세스의 ID를 구한다.
	DWORD pid;
	DWORD tid = GetWindowThreadProcessId(hwnd, &pid);

	// 프로세스 ID를 가지고 프로세스 핸들을 얻는다. // 모든 권한
	// 윈도우XP 서비스팩3일때는 모든권한이면 권한을 안준다.
	// 하지만 윈도우7은 가능함
	// 그렇기 때문에 최소권한을 요청하는것이 낫다.
	//HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
	HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pid);
	

	printf("윈도우 번호 : %x	프로세스 ID : %d 프로세스 핸들 %x \n", hwnd, pid, hProcess);

	getch();

	// 프로세스 핸들을 얻어서 죽이는 함수
	// ID하고 핸들하고 헷갈려하지 말자
	TerminateProcess(hProcess, 0);	

}

#endif

// 요즘은 page table을 생성하여 실제주소와 가상주소를 매핑
// page table에 없을 시 page fault 에러 발생
// 윈도우중에 ReadProcessMemory()라는 메모리가 있고, 이것은 상대방의 메모리를 읽어 올 수 있다.


// 암호입력 프로그램

#if 0

int main(){

	// 이 주소를 감춰야 한당 (메모리의 주소)
	char passwd[256];

	printf("프로세스 ID : %d\n", GetCurrentProcessId()); // 자신의 프로세스 ID 읽기
	printf("암호를 담은 변수의 주소 : %p\n", passwd);

	while(1){

		gets(passwd);
	}
}

#endif

//  암호 읽어오기 다른 코드에서 실행해야함

#if 0

int main(){
	DWORD pid = 1010;
	char *addr = (char*)0x123123;

	HANDLE hProcess = OpenProcess(PROCESS_VM_READ, 0, pid);

	while(1){
		getch();
		char buffer[256] = {0};
		DWORD len;
		
		// 다른 프로세스의 메모리를 읽어오는 함수임
		// 디버거 만들 때 사용하는 함수
		ReadProcessMemory(hProcess, addr, buffer, 256, &len);

		printf("읽어온 data : %s\n", buffer);

	}
}
#endif

// 올리디버거를 사용하면은 프로세스의 전역변수(data영역) 등 알 수 있다.
// 지뢰찾기 crack
// WindowsXP용 지뢰찾기를 받아야 한다.
// Windows7이랑은 메모리 구조가 조금 다름
// 지뢰찾기 크랙 숙제
// OpenProcess가 굉장히 위험한 함수임

// 추천 서적 : Windows Via C/C++
// 쉬운 책 : "뇌를 자극하는 윈도우 시스템"

#if 0

// API Hooking

UINT __stdcall foo(HWND hwnd, char* s1, char *s2, int btn){

	printf("%s %s\n", s1, s2);
	return 0;
}

int main(){

	// 이 함수는 User32.dll 에 있습니다.
	// exe파일의 섹션에 .idata 필드에 user32가 필요하다가 나와있음
	// exe파일의 헤더에 image?? 필드에 가상주소가 적혀 있음 default 400000
	// page table에서 가상주소와 실제주소를 맵핑
	
	// 실행파일의 .idata섹션에는 MessageBoxA의 주소가 있다.
	// 그곳을 다른 함수의 주소로 덮어 쓴다.

	// 이걸 함수로 알아 낼 수 있다.
	*((int*)0x12312312) = (int)&foo;

	// 내가 남의 프로세스를 후킹하려면
	// e.g. 지뢰찾기
	// 지뢰찾기의 시간함수는 SetTimer( x, x, mSec )

	// 이것은 DLL injection 기술
	// dll로 만든 후 지뢰찾기에 심기

	MessageBoxA(0, "aaa", "bbb", 0);
}

#endif

// DLL injection
// 윈도우 API중에 LoadLibrary(DLL name)라는 함수가 있다.
// 이 함수는 Kernal32.dll
// 모든 프로그램은 이 dll를 사용하고, 이것은 항상 같은 메모리에 적재 된다.


#if 0


void DllInject(DWORD pid, char* dllname){

	// 지뢰찾기의 핸들 구하기
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);


	// 모든 프로세스의 LoadLibraryA의 주소는 같다.
	HMODULE hDll = GetModuleHandle("Kernal32.dll");
	PTHREAD_START_ROUTINE f = (PTHREAD_START_ROUTINE)GetProcAddress(hDll, "LoadLibraryA");

	// 다른 프로세스에 메모리를 할당한다.
	void *addr = VirtualAllocEx(hProcess, 0, strlen(dllname)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

	DWORD len;
	WriteProcessMemory(hProcess, addr, dllname, strlen(dllname)+1, &len);


	// CreateThread는 자신에게 스레드를 만드는 함수이고, CreateRemoteThread는 다른 프로세스에다가 thread를 만드는 함수임
	//HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, foo, 0, 0, 0);
	// foo는 지뢰찾기에 있는 함수이름을 적는다.
	HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, f, addr, 0, 0);

}


int main(){

	HWND hwnd = FindWindow(0, "지뢰 찾기");

	DWORD pid;
	DWORD tid = GetWindowThreadProcessId(hwnd, &pid);

	DllInject(pid, "C:\\spy.dll");
}

#endif


// 모든 DLL은 프로세스에 들어갈때 DllMain함수가 호출된다.
// 강석민 강사님 소스 확인

// 하드웨어 얘기
// CPU에는 interrupt 핀이 있다.
// 하지만 하나밖에 없기 때문에 8259칩을 이용하여 인터럽트 개수를 늘린다.
// 8259는 8개의 입력 하나의 출력
// IVT는 8비트, 요즘은 IDT
// IDT는 IRQ가 있고, 대응되는 주소(함수)가 있다.

// SHIQ(System Hardware Input Queue)는 딱 하나, 전기적인 신호를 여기에다가 저장
// RIT(Raw Input Thread)가 하나씩 꺼냄
// 계산기나 메모장의 큐가 따로 존재
// GetMessage()함수를 통해 큐에서 내용을 꺼냄

// 키보드나 마우스를 흉내내기 위한 함수는 SHIQ
// SendInput()를 통해 메시지 흉내를 낼 수 있다.



#if 0

int main(){

	while(1){

		INPUT input = {0};
		input.type = INPUT_KEYBOARD;
		input.ki.wVk = 'A';

		// 배열의 갯수, 배열의 주소, 구조체 크기
		SendInput(1, &input, sizeof(INPUT));
		
		Sleep(1000);
	
	}
}

#endif

//특정프로그램에 하기 위해서는 SendMessage()를 이용

#if 0

int main(){

	getch();

	HWND hwnd = FindWindow("notepad", 0);

	// 메모장 안에 있는 자식윈도우 핸들을 얻는다.
	HWND hEdit = FindWindowEx(hwnd, 0, "edit", 0);

	char s[] = "hello, world";

	for(int i=0; i<strlen(s); i++){

		SendMessage(hEdit, WM_CHAR, s[i], 0);
		Sleep(1000);
	}
}

#endif

// MS는 RIT 일 때 혹은 GetMessage()할 때 훅 할 수 있다. 하지만 DLL로 해야함.
// Local hook과 Global hook 이 있다.
// hook 예제


// 보안


// OpenProcess()는 kernal32.dll에 있음 (Win32API)
// NtOpenProcess()를 실제로 부름 (Native API)
// os는 ZwOpenProcess를 불름

// UserMode와 특권모드가 있고, callgate를 통해 특권모드를 접근할 수 있음.
// table이 있는데, 번호와 함수가 있다.
// SSDT(System Service Descriptor Table)
// Device Driver를 만들면 SSDT의 주소를 알 수 있음. 그렇기 때문에 그것에 대한 내용을 변경하면 SDT훅이 된다.
// 훅 중 SDT Hook이 가장 강력하다.

#if 1



#endif





댓글
04-28 18:46
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday