2012-05-18 2 views
1

작은 모니터링 응용 프로그램을 구현 중이므로 CreateWindowExA/W를 처리 중이므로 Windows 생성을 제어 할 수 있습니다. 내가 후킹하는 데 사용하는 방법은 어셈블러 JMP 명령어가있는 호출의 처음 5 바이트를 my hook 함수로 바꾸는 것입니다. (네, 어셈블러를 알고, 전에 여러 번 같은 방법을 사용했습니다). 내 후크 코드의 시작 부분에 EnterCriticalSection을 사용하고 InterlockedExchange를 사용하여 도난당한 바이트를 일괄 대체합니다. CreateWindowExA/W의 시작 부분에서 실제 5 바이트를 썼습니다. 그래서 함수를 올바르게 호출 할 수 있습니다. 내 경험에 따르면, 모든 일이 잘되고있다,하지만 그 순간에 내가 JMP를 실제 바이트로 대체 한 순간에, 다른 스레드가 함수를 호출하고, 바이트가 바뀐 것처럼 보인다.스레드 안전 걸이 기능

나는 IAT/EAT 테이블 후킹을 사용할 수 있지만 현재의 방법에 문제가 있는지 알고 싶습니다. 아마도 InterlockedExchange가 작동하지 않는 문제는 CreateWindowExA/W가 dll (comctl32 .dll, shell32.dll ...)하지만 주 실행 모듈은 아닙니다.

나는 당신이 내 설명을 잘 이해하지 못한다면 나에게 도움을 요청하고 다시 설명 할 것이기를 바랍니다.

답변

2

Windows 기능을 연결하는 경우 IAT 후크가 훨씬 더 안전합니다. 그러나, 당신이 우회로를 사용하는 것을 주장한다면, 그것은 일반적으로 사물의 창쪽에 내장 된 핫 패칭을 사용하는 것이 더 낫다. (이것은 우회적으로 가능하다.

문제는 정확히 말하면 잠금은 실행 스레드 만 일시 중단하지만 사용자가 제어하는 ​​스레드는 일시 중단하지 않습니다. 이 문제를 해결하려면 (PSAPI/toolhlp32를 통해) 모든 스레드를 일시 중지하거나 더 효율적으로, 호출 수신자 주소가 우회 할 모듈의 주소 공간에있는 경우 해당 검사를 우회 한 기능에 점검을 추가하십시오. GetModuleHandle, WinNT의 일부 PE 함수 및 _ReturnAddress 내장 함수를 사용하여 수행 할 수 있습니다.

+1

무엇을해야 할 것 같아요으로

스레드를 일시 중단하는 것은 나쁜 솔루션을 보이는, DXHooks에서 http://dxhook.googlecode.com/svn/trunk/dxhook.cpp에서보세요. 나에게 더 나은 방법은 간단한 길이 디스어셈블러를 사용하여 처음 몇 가지 어셈블러 명령어를 jmp로 대체 한 다음 나중에 복원하는 것이지만 스택에 params를 밀어 넣어 도난당한 명령어와 JMP를 CreateWindowExA/W, JMP JMP 바로 뒤에 실제로 코드로 연결됩니다. 누군가 모든 OS에서 모든 API의 첫 번째 어셈블러 지침이 "MOV EDI, EDI", "PUSH EBP", "MOV EBP, ESP"인지 확인할 수 있습니까? (나는 그 ntdll.dll에 대한 경우가 아니라는 것을 알고있다) – VisaToHell

+0

user32.dll의 EAT와 IAT를 현재 프로세스에있는 다른 모든 모듈의 IAT에 연결하면, 나중에 새 모듈이로드 될 때 나중에 괜찮을 것이다. .dll은 CreateWindowEx/A/W에 대한 나의 후크 주소를 새 모듈에서 얻을 수 있습니까? – VisaToHell

+1

@VisaToHell : 현재 프로세스의 모든 모듈에 우회 경로를 적용하려면 (** 귀하의 질문이 의미하는 것이 아닌 **), 시스템 dll에있는 코드 만 핫 패칭하면됩니다 ('mov edi, edi'와 선행 바이트는 RLD가 필요 없음), 모든 프로세스가 시스템 dll의 복사본을 가져옵니다. 이 기능을 사용하기 전에 다른 기능이 사용되기 전에 일반적으로 로더가 일시 중단 된 상태에서 프로세스를 시작하거나 패치가 완료 될 때까지 init을 차단해야합니다. – Necrolis

0

CreateWindowEx에 대한 모든 단일 호출을 제어 할 수 있으면 중요한 섹션으로 래핑 할 수 있습니다. 그러나 그렇게 할 수 있다면 함수를 연결하지 않아도됩니다.

남은 것은 다른 스레드가 시작되기 전에 함수를 후크하는 것입니다. 응용 프로그램을 시작할 때 정적 초기화를 사용하여이 작업을 수행하십시오.

이 특정 기능에 대한 다른 생각 하나. 많은 응용 프로그램에서 모든 창은 주 스레드에서 만들어집니다. 그것이 당신을 위해 그렇게한다면 당신은 동기화 할 필요가 없습니다.

1

바이트를 다시 변경하면 후킹이 손실되고 jmp 이후이므로 중요한 섹션이 도움이되지 않습니다. 나는 당신이 내가 당신의 요점을 파악 해달라고, 모든 모듈에서 호출 후크 할

+0

나는 Windows Detours 라이브러리를 보았는데, 좋아 보인다. 나는 오늘 밤 그것을 시험해 볼 것이고, IAT/EAT를 연결하고 첫번째 바이트를 바로 패치 할 수 있을까? Detours 도서관의 부족한 점이나 단점이 있습니까? – VisaToHell