완전한 후크 프로그램의 키워드 예: 후크, 차단, 서비스
제가 입사지원 시 받은 xx회사의 "Senior Windows Program Analyst" 시험문제입니다. 구체적인 요구사항(즉, 프로그램 설명)은 다음과 같습니다.
1. 클라이언트 프로그램의 이름은 Client입니다. 시스템 작동을 모니터링하십시오. 시스템에 "메모장" 프로세스(notepad.exe) 또는 "계산기" 프로세스(calc.exe)가 있는 경우 해당 프로세스를 즉시 종료하고 이벤트를 데이터베이스에 기록하십시오. 주기적으로 1분 간격으로 데이터베이스를 확인하여 아직 서버에 업로드되지 않은 이벤트 기록을 업로드합니다.
1. 대상 운영 환경은 Windows 2000 운영 체제입니다.
2. 시스템에 맞게 프로그램을 설계해주세요.
3. 프로그램은 삭제 방지, 프로세스 강제 종료 방지 등 공격 방지 기능을 갖추고 있어야 합니다.
(1) 프로그램을 지속적으로 실행하고 다른 프로그램이 현재 프로그램 실행을 강제로 종료하지 못하도록 방지합니다.
(2) 이벤트 데이터베이스와 주요 실행 파일이 삭제되지 않도록 보호합니다.
(3) 이상이 발견되면(프로세스 종료, 파일 삭제 등) 즉시 프로그램을 강제로 재로드/실행합니다.
(4) 연속해서 세 번 이상이 감지되면 데몬 프로세스는 시스템을 다시 시작한 후 운영 체제를 강제로 다시 시작하여 프로그램이 정상적으로 로드되고 실행되는지 확인합니다.
(가) 위의 기능을 구현하기 위해 프로그램은 EXE 형식에 국한되지 않고 필요에 따라 구현 형식을 자체적으로 결정할 수 있습니다.
(B) 위의 기능은 모두 Windows 2000의 일반 운영 환경에서 관리자 권한으로 구현되며 Windows 보안 모드나 권한 및 기타 문제를 고려할 필요가 없습니다.
4. Access, xBase 및 기타 파일 데이터베이스와 같은 간단한 데스크톱 데이터베이스를 사용하십시오.
5. 생성된 각 이벤트에는 이벤트 발생 시간과 이벤트 처리 개체라는 두 가지 이상의 정보가 포함됩니다.
이벤트 데이터는 데이터베이스의 tEvent 테이블에 저장됩니다. tEvent 테이블에는 최소한 두 개의 필드가 포함되어 있습니다.
(1) EventTime 필드: 시간/날짜 유형입니다. 사건이 발생한 시간을 기록합니다.
(2) EventTarget 필드 : 문자형. 사건으로 인해 사망한 개체를 기록합니다. 고려해야 할 개체는 메모장 프로세스와 계산기 프로세스입니다.
다른 테이블이나 필드가 필요한 경우 필요에 따라 추가할 수 있습니다.
6. 네트워크 데이터 전송 형식이 사용자 정의됩니다. 귀하의 필요에 따라 구체적인 전송 내용과 형식을 결정하십시오. 특별한 요구 사항은 없습니다. 클라이언트 네트워크는 서버 네트워크와 함께 작동해야 합니다.
7. 사용되는 개발 언어 및 통합 개발 환경에는 제한이 없으며, 직접 선택할 수 있습니다.
8. 데이터베이스 연결 방법은 필요에 따라 선택하십시오.
2. 서버 측 프로그램의 이름은 Server입니다. 네트워크를 모니터링하고 클라이언트가 데이터를 업로드하면 이벤트 정보가 즉시 추출되어 사용자 인터페이스의 목록에 표시됩니다.
1. 대상 운영 환경은 Windows 2000 운영 체제입니다.
2. 프로그램은 일반 Windows 2000 GUI 응용 프로그램으로 설계되어야 합니다. 사용자 인터페이스에는 이벤트 발생 시간, 이벤트 처리 개체, 이벤트 소스 등 세 가지 이상의 정보가 포함된 이벤트 정보 목록이 하나 이상 포함되어야 합니다.
(1) 이벤트 발생 시간 : 클라이언트 이벤트 발생 시간과 동일합니다.
(2) 이벤트 처리 객체: 클라이언트 이벤트 처리 객체와 동일합니다.
(3) 이벤트 소스: 현재 이벤트를 업로드한 클라이언트 머신의 IP 주소입니다.
3. 네트워크 데이터 전송 형식은 클라이언트와 함께 작동합니다.
4. 사용되는 개발언어와 통합개발환경에는 제한이 없으며, 직접 선택하실 수 있습니다.
프로그램 실행 지침:
client.ini는 C 드라이브의 루트 디렉터리에 있어야 합니다. 다른 파일은 어디에든 둘 수 있지만, Survival.exe와 client.exe는 같은 폴더에 있어야 합니다. 생존.exe를 시작하기 전에 서버 IP(interval_server)를 구성하십시오. ) client.ini에서 ), ADServer.exe를 시작합니다.
소스코드 설명 1. 서버 ADServer.exe
서버사이드는 간단하니까 먼저 서버사이드부터 얘기해보겠습니다 :)
서버의 역할은 네트워크로부터 데이터를 수신하고 전송을 차단하는 TServerSocket을 사용하는 것입니다. TServerSocket은 클라이언트로부터 연결 요청을 받을 때마다 TServerClientThread 스레드를 생성합니다. 클라이언트 데이터를 읽고 쓰려면 이 스레드에 새로운 TWinSocketStream을 생성해야 합니다. 기본 코드는 이 스레드의 ClientExecute 부분에 작성됩니다.
TWinSocketStream이 클라이언트에 데이터를 쓰는 데는 문제가 없지만 클라이언트에서 데이터를 읽으면(read 메소드를 사용하여) WaitForData를 사용하는 경우에도 읽기를 마치기 전에 반환되는 경우가 많습니다. 그래서 데이터가 읽힐 때까지 기다리는 waitDateComplete 함수를 작성했습니다.
2. 클라이언트 클라이언트는 좀 더 귀찮습니다. Client.exe는 서비스이고,survival.exe는 서로를 모니터링합니다. 하나가 종료되면 다른 하나는 다시 시작됩니다. HookDll.dll은 후크에 사용됩니다. 전역 후크는 독립적인 dll 모듈로 작성되어야 합니다(몇 가지 후크를 제외하고는 다음 문서를 참조하십시오: http://www.pconline.com.cn/pcedu/empolder/gj/vc/) 0403/340480.html).
Client.exe에는 몇 줄의 코드가 없습니다. 주로 CreateProcess를 사용하여 프로세스를 시작합니다. 서비스가 이 프로그램에 의해 시작된 Hookdll.dll에서 사용되는 후크와 같이 Windows 셸과 관련된 작업을 수행하려는 경우 ServiceType을 stWin32로 설정하고 TService::Interactive 속성을 true로 설정해야 합니다.
생존.exe는 서비스를 시작하고, Hookdll.dll을 로드하고, 이벤트를 서버에 보고하는 데 사용됩니다.
1. 서비스를 시작하려면 먼저 관리 도구에서 "서비스"의 백엔드인 서비스 컨트롤러를 엽니다. OpenSCManager를 사용하여 서비스 관리자 핸들을 얻은 다음 OpenService(서비스 관리자 핸들, 서비스 이름)를 사용합니다. , SERVICE_START | SERVICE_QUERY_STATUS)를 사용하여 지정된 서비스의 핸들을 얻은 다음 마지막으로 StartService(...)를 사용하여 서비스를 열 수 있습니다. 최소한 SERVICE_START 및 SERVICE_QUERY_STATUS 두 가지 권한을 얻어야 합니다.
2. Hookdll.dll 로드 측면에서 이 프로그램은 암시적 연결, 즉 BCB의 프로젝트프로젝트에 추가를 사용하여 dll의 lib 파일을 가져오는 방식을 사용합니다. 가져온 후 코드에서 dll의 함수가 호출되지 않으면 dll이 로드되지 않습니다. 이 프로그램은 startTrace(HWND 호스트) 함수를 호출하여 생존.exe의 창 핸들을 전달하고, dll은 이 핸들을 통해 생존.exe에 일부 메시지를 보냅니다.
3. 서버에 이벤트를 보고하는 측면에서 주로 메시지 전송 -> 메시지 수신 수신 프로세스를 담당하는 TMSocketClient 클래스가 특별히 작성되었습니다. 주요 코드는 TMSocketClient::Command(….)에 있습니다. ADServer.exe의 코드는 매우 간단합니다. #define 다양한 명령 상수를 통해 이 모듈은 다양한 유형의 전송 작업을 완료할 수 있습니다. 사실 이 모듈은 제가 예전에 TNMFTP를 시뮬레이션하기 위해 작성한 클래스입니다. #define을 많이 삭제하여 단순화하고 가상 LAN에서 파일을 전송하는 데 사용했습니다(TNMFTP는 가상 LAN에서는 작동하지 않습니다).
3. HookDll.dll
코드는 매우 간단합니다. 한 가지만 주의하세요. 즉, N 프로세스가 동일한 dll을 호출하면 이 dll이 N 번 복사됩니다. 일반적으로 말해서 이러한 N dll의 서로 다른 복사본에는 각각 자체 데이터 세그먼트가 있습니다. 즉, 각 복사본의 동일한 변수 값은 다르며 서로 간섭하지 않습니다. 그러나 실제로 Windows에는 프로세스 공간을 초월하는 포인터처럼 dll에서 이러한 변수를 선언하고 dll의 N 인스턴스 간에 데이터 일관성을 유지할 수 있는 메커니즘이 남아 있습니다. 이러한 변수를 선언하려면 먼저 dll과 동일한 이름으로 .def 파일을 만들고 파일에 씁니다.
섹션
SHSEG 읽기 쓰기 공유됨
그런 다음 프로세스 간에 공유하려는 dll 변수를 전역 변수로 선언하고 해당 변수를 초기화합니다. 공유하는 것과 공유하지 않는 것의 차이는 초기화 여부에 있다는 점 참고하세요!
이 프로그램은 CCRun의 "Apply of Hooks: Program Running Monitoring"을 참조합니다. 작성자 Victor Chen에게 감사드립니다.
좋아요, 기본적으로 설명할 내용은 이게 다인 것 같습니다. 그 외에도 프로그램에 쓸데없는 변수가 있어서 정리할 시간이 없네요. 양해 부탁드립니다. :) 시청해주셔서 감사합니다!
확장하다