|
pro 님이 쓰신 글 :
: 그지같은 C++ 빌더가 64비트를 지원하지 않아서
: 비쥬얼 스튜디오 64비트 C++ 컴파일러를 이용해서
: 쉘인 Explorer.exe를 후킹 하는데 성공했습니다 ^^
:
: 이번엔 서비스를 인젝션해서 후킹하려고 하는데요
: 서비스를 OpenProcess로 오픈하면 프로세스가 정상적으로 오픈됨에도 불구하고
: 리모트 스레드 생성에서 실패하네요.
:
: XP에선 되는데 Win 7 64비트에선 왜 안되는 건가요.
:
: 컴파일도 비쥬얼 스튜디오 64비트 C++ 컴파일러로 했거든요.
답변:
Protected Mode Context로 실행되고 있는 프로세스(서비스)에 리모트 쓰레드를 생성하기 위해선 Token Access Right 등
충분한 권한이 확보 되어있는 상태라야 하는데, OpenProcess로 프로세스 핸들을 여는데 까진 성공했다는 것은
권한과 관련한 사전작업 들은 이미 처리하고 있는 것으로 보여지네요.
리모트 쓰레드 생성에 실패하는 이유는... 비스타 이후 부터 바뀐 OS 구조 때문 입니다.
비스타 이후 부터 프로세스 들은 Session과 연계 되어 처리되게 되는데... 타겟 대상인 서비스와 Injector 프로세스의 Session이
다르기 때문에 리모트 쓰레드 생성에 실패하고 있을 겁니다.
문제를 해결하기 위한 방법을 찾아 보자면... 대략 세가지 정도 생각해 볼 수 있을텐데...
첫번째 방법...
더미로 서비스를 하나 만들어 주어서, 이 서비스가 Injector 프로세스를 실행하도록 해주는 겁니다.
이 경우 Injector 프로세스가 서비스의 세션으로 실행되기 때문에 리모트 쓰레드 생성이 가능해 집니다.
Injector 프로세스가 실행되면 역할을 다한 서비스는 제거해 주면 되고요.
서비스 형태로 실행되어야 해서 관리자 권한이 필요해 지게 됩니다.
두번째 방법...
CreateRemoteThread API 자체를 Trampoline 방식으로 패치해서 Session Validation 처리를 하지 않도록 해주는 방법 입니다.
API를 디스어셈블링해서 코드를 패치해줘야 하니까 번거롭겠죠.
세번째 방법...
'NtCreateThreadEx'라는 Undocumented API를 직접 이용하는 방법입니다.
CreateRemoteThread API가 Session Validataion Check에 성공하면 'NtCreateThreadEx'라는 Undocumented API를
내부적으로 호출하게 되어 있으니까... 이 시스템 API를 직접 이용해서 리모트 쓰레드를 생성해 주는 겁니다.
Undocumented API인 'NtCreateThreadEx'는 'NTDLL.DLL'에서 Export 하고 있고, API의 프로토타입은 다음과 같습니다.
typedef DWORD (WINAPI *PFNTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID Unknown
);
API를 사용하기 위해선 아래와 같은 식으로 펑션의 주소를 얻어서 사용하면 됩니다.
HMODULE hNtDLL = LoadLibraryA("NTDLL.DLL");
PFNTCREATETHREADEX pFunc = NULL;
pFunc = (PFNTCREATETHREADEX)GetProcAddress(hNtDLL, "NtCreateThreadEx");
pFunc( &hRemoteThread,
0x1FFFFF,
NULL,
hTargetProc,
reinterpret_cast< LPTHREAD_START_ROUTINE >( pRemoteFunc ),
pRemoteArgs,
FALSE,
0,
0,
0,
NULL);
...
|