티스토리 뷰
#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
'Programming Languages > C,C++' 카테고리의 다른 글
ProcessID를 갖고 윈도우핸들 얻어오기 (0) | 2011.04.23 |
---|---|
Assembly의 기초 공부 (0) | 2011.04.23 |
TEXT Encoding에 대하여. (2) | 2011.04.23 |
MS Visual C++ 10.0 에서 CString을 char * 타입으로 캐스팅 방법 (0) | 2011.03.26 |
Visual Studio 2010에서 Subversion 사용하기. (SVN) (0) | 2011.03.22 |
댓글
01-05 09:04
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday