본문 바로가기
C & C++/C & C++

[API] 프로세스 관리 02

by izen8 2011. 11. 24.
반응형
  1. #include <windows.h>   
  2.   
  3. #include <stdio.h>   
  4. #include <conio.h>   
  5. #include <typeinfo.h>   
  6.   
  7. // 1. 윈도우의 번호를 안다면 해당 윈도우를 조작할 수 있다.   
  8.   
  9. #if 0   
  10. int main(){   
  11.   
  12.     HWND hwnd = FindWindow(0, "계산기");   
  13.   
  14.     printf("윈도우 번호 : %x\n", hwnd);   
  15.     getch();   
  16.   
  17.     MoveWindow(hwnd, 10, 10, 300, 300, TRUE);   
  18.     getch();   
  19.   
  20.     ShowWindow(hwnd, SW_HIDE);   
  21.     getch();   
  22.     ShowWindow(hwnd, SW_SHOW);   
  23.     getch();   
  24.     SetMenu(hwnd, 0);   
  25.     getch();   
  26.     HRGN h = CreateEllipticRgn(0, 0, 300, 300);   
  27.     SetWindowRgn(hwnd, h, TRUE);   
  28.   
  29.     return 0;   
  30. }   
  31. #endif   
  32.   
  33. #if 0   
  34. int main(){   
  35.   
  36.     HWND hwnd = FindWindow("Shell_TrayWnd", 0);   
  37.   
  38.     printf("윈도우 번호 : %x\n", hwnd);   
  39.     getch();   
  40.   
  41.     MoveWindow(hwnd, 10, 10, 300, 300, TRUE);   
  42.     getch();   
  43.   
  44.     ShowWindow(hwnd, SW_HIDE);   
  45.     getch();   
  46.     ShowWindow(hwnd, SW_SHOW);   
  47.     getch();   
  48.     SetMenu(hwnd, 0);   
  49.     getch();   
  50.     HRGN h = CreateEllipticRgn(0, 0, 300, 300);   
  51.     SetWindowRgn(hwnd, h, TRUE);   
  52.   
  53.     return 0;   
  54. }   
  55. // 핸들 갖고오는 함수   
  56. // FindWindow()   
  57. // WindowFromPoint()   
  58. #endif   
  59.   
  60.   
  61. // 속성 변경하기, 윈도우는 구조체   
  62. #if 0   
  63. void ModifyStyle(HWND hwnd, UINT remove, UINT add){   
  64.   
  65.     int style = GetWindowLong(hwnd, GWL_STYLE);   
  66.   
  67.     style = style | add;   
  68.     style = style & ~remove;   
  69.   
  70.     SetWindowLong(hwnd, GWL_STYLE, style);   
  71.   
  72.     SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);   
  73.   
  74. }   
  75.   
  76. void main(){   
  77.   
  78.     HWND hwnd;   
  79.     hwnd = FindWindow(0, "계산기");   
  80.     getch();   
  81.     ModifyStyle(hwnd, WS_CAPTION, WS_THICKFRAME);   
  82. }   
  83. #endif   
  84.   
  85.   
  86. // HWND의 정체는 무엇일까?   
  87. // 1. 32비트 정수이므로 아래 처럼 하면 어떨까?   
  88.   
  89. #if 0   
  90.   
  91. typedef unsigned int HWND;   
  92. typedef unsigned int HICON;   
  93.   
  94. void MoveWindow(HWND hwnd, int x, int y){   
  95.   
  96. }   
  97.   
  98. void main(){   
  99.   
  100.     HICON hIcon = 0;   
  101.     MoveWindow(hIcon, 10, 10);   
  102.   
  103. }   
  104.   
  105. #endif   
  106.   
  107. // 핸들 타입 받아오기   
  108. #if 0   
  109.   
  110. int main(){   
  111.   
  112.     printf("%s\n"typeid(HWND).name());   
  113.     printf("%s\n"typeid(HANDLE).name());   
  114.     printf("%s\n"typeid(DWORD).name());   
  115.   
  116. }   
  117.   
  118. #endif   
  119.   
  120. // 프로세스 -> 윈도우만듦 -> 윈도우핸들이 생김   
  121. // 즉 프로세스의 핸들을 잡는게 낳음   
  122. // 프로세스는 아이디가 있음 PID   
  123. // 하지만 아이디만으로는 할 수 없음   
  124. // 그렇기 때문에 핸들을 요구해야함 (핸들발급) 그럼 모든것을 할 수 있음.   
  125.   
  126.   
  127. // ProcessID   
  128. #if 0   
  129.   
  130. int main(){   
  131.   
  132.     HWND hwnd = FindWindow(0, "계산기");   
  133.        
  134.        
  135.     // 특정 윈도우를 만든 프로세스의 ID를 구한다.   
  136.     DWORD pid;   
  137.     DWORD tid = GetWindowThreadProcessId(hwnd, &pid);   
  138.   
  139.     // 프로세스 ID를 가지고 프로세스 핸들을 얻는다. // 모든 권한   
  140.     // 윈도우XP 서비스팩3일때는 모든권한이면 권한을 안준다.   
  141.     // 하지만 윈도우7은 가능함   
  142.     // 그렇기 때문에 최소권한을 요청하는것이 낫다.   
  143.     //HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);   
  144.     HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pid);   
  145.        
  146.   
  147.     printf("윈도우 번호 : %x 프로세스 ID : %d 프로세스 핸들 %x \n", hwnd, pid, hProcess);   
  148.   
  149.     getch();   
  150.   
  151.     // 프로세스 핸들을 얻어서 죽이는 함수   
  152.     // ID하고 핸들하고 헷갈려하지 말자   
  153.     TerminateProcess(hProcess, 0);     
  154.   
  155. }   
  156.   
  157. #endif   
  158.   
  159. // 요즘은 page table을 생성하여 실제주소와 가상주소를 매핑   
  160. // page table에 없을 시 page fault 에러 발생   
  161. // 윈도우중에 ReadProcessMemory()라는 메모리가 있고, 이것은 상대방의 메모리를 읽어 올 수 있다.   
  162.   
  163.   
  164. // 암호입력 프로그램   
  165.   
  166. #if 0   
  167.   
  168. int main(){   
  169.   
  170.     // 이 주소를 감춰야 한당 (메모리의 주소)   
  171.     char passwd[256];   
  172.   
  173.     printf("프로세스 ID : %d\n", GetCurrentProcessId()); // 자신의 프로세스 ID 읽기   
  174.     printf("암호를 담은 변수의 주소 : %p\n", passwd);   
  175.   
  176.     while(1){   
  177.   
  178.         gets(passwd);   
  179.     }   
  180. }   
  181.   
  182. #endif   
  183.   
  184. //  암호 읽어오기 다른 코드에서 실행해야함   
  185.   
  186. #if 0   
  187.   
  188. int main(){   
  189.     DWORD pid = 1010;   
  190.     char *addr = (char*)0x123123;   
  191.   
  192.     HANDLE hProcess = OpenProcess(PROCESS_VM_READ, 0, pid);   
  193.   
  194.     while(1){   
  195.         getch();   
  196.         char buffer[256] = {0};   
  197.         DWORD len;   
  198.            
  199.         // 다른 프로세스의 메모리를 읽어오는 함수임   
  200.         // 디버거 만들 때 사용하는 함수   
  201.         ReadProcessMemory(hProcess, addr, buffer, 256, &len);   
  202.   
  203.         printf("읽어온 data : %s\n", buffer);   
  204.   
  205.     }   
  206. }   
  207. #endif   
  208.   
  209. // 올리디버거를 사용하면은 프로세스의 전역변수(data영역) 등 알 수 있다.   
  210. // 지뢰찾기 crack   
  211. // WindowsXP용 지뢰찾기를 받아야 한다.   
  212. // Windows7이랑은 메모리 구조가 조금 다름   
  213. // 지뢰찾기 크랙 숙제   
  214. // OpenProcess가 굉장히 위험한 함수임   
  215.   
  216. // 추천 서적 : Windows Via C/C++   
  217. // 쉬운 책 : "뇌를 자극하는 윈도우 시스템"   
  218.   
  219. #if 0   
  220.   
  221. // API Hooking   
  222.   
  223. UINT __stdcall foo(HWND hwnd, char* s1, char *s2, int btn){   
  224.   
  225.     printf("%s %s\n", s1, s2);   
  226.     return 0;   
  227. }   
  228.   
  229. int main(){   
  230.   
  231.     // 이 함수는 User32.dll 에 있습니다.   
  232.     // exe파일의 섹션에 .idata 필드에 user32가 필요하다가 나와있음   
  233.     // exe파일의 헤더에 image?? 필드에 가상주소가 적혀 있음 default 400000   
  234.     // page table에서 가상주소와 실제주소를 맵핑   
  235.        
  236.     // 실행파일의 .idata섹션에는 MessageBoxA의 주소가 있다.   
  237.     // 그곳을 다른 함수의 주소로 덮어 쓴다.   
  238.   
  239.     // 이걸 함수로 알아 낼 수 있다.   
  240.     *((int*)0x12312312) = (int)&foo;   
  241.   
  242.     // 내가 남의 프로세스를 후킹하려면   
  243.     // e.g. 지뢰찾기   
  244.     // 지뢰찾기의 시간함수는 SetTimer( x, x, mSec )   
  245.   
  246.     // 이것은 DLL injection 기술   
  247.     // dll로 만든 후 지뢰찾기에 심기   
  248.   
  249.     MessageBoxA(0, "aaa""bbb", 0);   
  250. }   
  251.   
  252. #endif   
  253.   
  254. // DLL injection   
  255. // 윈도우 API중에 LoadLibrary(DLL name)라는 함수가 있다.   
  256. // 이 함수는 Kernal32.dll   
  257. // 모든 프로그램은 이 dll를 사용하고, 이것은 항상 같은 메모리에 적재 된다.   
  258.   
  259.   
  260. #if 0   
  261.   
  262.   
  263. void DllInject(DWORD pid, char* dllname){   
  264.   
  265.     // 지뢰찾기의 핸들 구하기   
  266.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);   
  267.   
  268.   
  269.     // 모든 프로세스의 LoadLibraryA의 주소는 같다.   
  270.     HMODULE hDll = GetModuleHandle("Kernal32.dll");   
  271.     PTHREAD_START_ROUTINE f = (PTHREAD_START_ROUTINE)GetProcAddress(hDll, "LoadLibraryA");   
  272.   
  273.     // 다른 프로세스에 메모리를 할당한다.   
  274.     void *addr = VirtualAllocEx(hProcess, 0, strlen(dllname)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);   
  275.   
  276.     DWORD len;   
  277.     WriteProcessMemory(hProcess, addr, dllname, strlen(dllname)+1, &len);   
  278.   
  279.   
  280.     // CreateThread는 자신에게 스레드를 만드는 함수이고, CreateRemoteThread는 다른 프로세스에다가 thread를 만드는 함수임   
  281.     //HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, foo, 0, 0, 0);   
  282.     // foo는 지뢰찾기에 있는 함수이름을 적는다.   
  283.     HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, f, addr, 0, 0);   
  284.   
  285. }   
  286.   
  287.   
  288. int main(){   
  289.   
  290.     HWND hwnd = FindWindow(0, "지뢰 찾기");   
  291.   
  292.     DWORD pid;   
  293.     DWORD tid = GetWindowThreadProcessId(hwnd, &pid);   
  294.   
  295.     DllInject(pid, "C:\\spy.dll");   
  296. }   
  297.   
  298. #endif   
  299.   
  300.   
  301. // 모든 DLL은 프로세스에 들어갈때 DllMain함수가 호출된다.   
  302. // 강석민 강사님 소스 확인   
  303.   
  304. // 하드웨어 얘기   
  305. // CPU에는 interrupt 핀이 있다.   
  306. // 하지만 하나밖에 없기 때문에 8259칩을 이용하여 인터럽트 개수를 늘린다.   
  307. // 8259는 8개의 입력 하나의 출력   
  308. // IVT는 8비트, 요즘은 IDT   
  309. // IDT는 IRQ가 있고, 대응되는 주소(함수)가 있다.   
  310.   
  311. // SHIQ(System Hardware Input Queue)는 딱 하나, 전기적인 신호를 여기에다가 저장   
  312. // RIT(Raw Input Thread)가 하나씩 꺼냄   
  313. // 계산기나 메모장의 큐가 따로 존재   
  314. // GetMessage()함수를 통해 큐에서 내용을 꺼냄   
  315.   
  316. // 키보드나 마우스를 흉내내기 위한 함수는 SHIQ   
  317. // SendInput()를 통해 메시지 흉내를 낼 수 있다.   
  318.   
  319.   
  320.   
  321. #if 0   
  322.   
  323. int main(){   
  324.   
  325.     while(1){   
  326.   
  327.         INPUT input = {0};   
  328.         input.type = INPUT_KEYBOARD;   
  329.         input.ki.wVk = 'A';   
  330.   
  331.         // 배열의 갯수, 배열의 주소, 구조체 크기   
  332.         SendInput(1, &input, sizeof(INPUT));   
  333.            
  334.         Sleep(1000);   
  335.        
  336.     }   
  337. }   
  338.   
  339. #endif   
  340.   
  341. //특정프로그램에 하기 위해서는 SendMessage()를 이용   
  342.   
  343. #if 0   
  344.   
  345. int main(){   
  346.   
  347.     getch();   
  348.   
  349.     HWND hwnd = FindWindow("notepad", 0);   
  350.   
  351.     // 메모장 안에 있는 자식윈도우 핸들을 얻는다.   
  352.     HWND hEdit = FindWindowEx(hwnd, 0, "edit", 0);   
  353.   
  354.     char s[] = "hello, world";   
  355.   
  356.     for(int i=0; i<strlen(s); i++){   
  357.   
  358.         SendMessage(hEdit, WM_CHAR, s[i], 0);   
  359.         Sleep(1000);   
  360.     }   
  361. }   
  362.   
  363. #endif   
  364.   
  365. // MS는 RIT 일 때 혹은 GetMessage()할 때 훅 할 수 있다. 하지만 DLL로 해야함.   
  366. // Local hook과 Global hook 이 있다.   
  367. // hook 예제   
  368.   
  369.   
  370. // 보안   
  371.   
  372.   
  373. // OpenProcess()는 kernal32.dll에 있음 (Win32API)   
  374. // NtOpenProcess()를 실제로 부름 (Native API)   
  375. // os는 ZwOpenProcess를 불름   
  376.   
  377. // UserMode와 특권모드가 있고, callgate를 통해 특권모드를 접근할 수 있음.   
  378. // table이 있는데, 번호와 함수가 있다.   
  379. // SSDT(System Service Descriptor Table)   
  380. // Device Driver를 만들면 SSDT의 주소를 알 수 있음. 그렇기 때문에 그것에 대한 내용을 변경하면 SDT훅이 된다.   
  381. // 훅 중 SDT Hook이 가장 강력하다.   
  382.   
  383. #if 1   
  384.   
  385.   
  386.   
  387. #endif  

반응형

댓글