본문 바로가기

My Study/Programming&Theory

ZwProtectVirtualMemory 의 악몽 2

아놔......... ZwProtectVirtualMemory가 끝까지 사람을 괴롭히네요!!

이것 때문에 또 한시간 반을 날렸습니다 ㅠㅠ


NTSTATUS NTAPI ZwProtectVirtualMemory (

IN HANDLE ProcessHandle,

  IN OUT PVOID *BaseAddress,

  IN OUT PSIZE_T ProtectSize,

IN ULONG NewProtect,

OUT PULONG OldProtect

);


이게 해당 함수의 원형입니다.

http://ezbeat.tistory.com/449

여기 글에선 두 번째, 세 번째 IN OUT 특성을 갖는 인자 때문에 빡쳤었습니다.

이번엔 다른 이유입니다.


돌아가는 환경은

Windows 7 x64 환경입니다.


아래 코드에서 이상한 점을 찾아보세요. ( user 영역 코드입니다 )

NTSTATUS        ntReturnStatus;

DWORD            dwOldProtect;


ntReturnStatus = NtProtectVirtualMemory

GetCurrentProcess(), 

(PVOID*)&pOriFunc, 

&ulHookOrgCodeSize, 

PAGE_EXECUTE_READWRITE, 

&dwOldProtect 

);


( pOriFunc 인자와 ulHookOrgCodeSize 는 정상적인 값이 들어있습니다. )


위 코드가 실행되면 0xC0000018 이라는 에러가 발생합니다.

0xC0000018 에러는 STATUS_CONFLICTING_ADDRESSES 입니다.


..

..

..


정답은 dwOldProtect 인자를 0 으로 초기화를 해주지 않아서 오류가 났던 것입니다.

IN OUT 인자가 아니라 단순 OUT 인자이고 주소를 넘기기 때문에 0 으로 초기화 안해도 될꺼라 생각했었죠.


x86 환경에서는 OldProtect 가리키고 있는 값이 0 이 아니어도 잘 되지만

x64 환경에서는 꼭 0 또는 PAGE 메크로 관련 값 이어야 성공적으로 호출이 됩니다.


시간이 많으면 x64 kernel debugging 해보면서 이유를 알아보겠지만 

학생이 아니니 그런 시간적 여유가 없네요..;; 아쉽습니다. ( reactos 는 x64 버전은 안나오려나요? ㅋㅋ )