드라이버 쪼물딱 거리기 3탄 시스템 프로그래밍

드라이버 쪼물딱 거리기 2탄

bkdp3_ssdt_hook.zip
fxloader.zip

오늘은 SSDT hooking 입니다.



최근에는 SSDT 에 대한 내용은 정말 인터넷에 많이 널려있습니다.
사실 SSDT 훅에 대한 이야기는 아주 오래된(?) – undocumented windows 2000 secrete 에서 첨 본거 같기도 하고.. - 이야기이긴 합니다.
어떤 해킹을 다루거나 하는 커뮤니티(?)에 보면 뭐 최신의 기법인 것 처럼 이야기 하는 사람도 있긴 하지만 말이지요.

여기서는 실제 SSDT (System Service Descriptor Table) 을 후킹해서 원하는 기능을 구현하는 가장 간단한 형태의 코드를 예제로 보일 것입니다.
요즘은 좀 구식(?) 기술로 취급 받기도 합니다만.. windows 의 내부구조를 엿보는 좋은 경험이 될 수도 있습니다.
그러나 이 예제를 완벽히 내것으로 만들기 위해서는 Windows 에서 제공하는 Windows API 의 구조나 Native Api 등등 꽤 많은 사전 지식이 필요합니다.
이런 사전 지식들은 대한 내용은 “Technical Report - Windows system call 분석”문서와 구글 신의 힘을 빌면 충분히 필요한 만큼의 정보를 얻을 수 있을 것입니다.



http://www.windowsitlibrary.com/Content/356/07/1.html
undocumented Windows NT 의 전문이 실려있습니다.
루트킷 개발에 핵심이 되었던 기술들에 대한 설명이 아주 잘 되어있지요.
훌륭한 책입니다.

우리가 후킹 할 SSDT 의 위치는 아래의 그림에 설명되어 있습니다.
Ntoskrnl.exe 는 KeService* 의 두개의 심볼을 export 하고 있구요.



WinDbg 를 통해 해당 심볼들이 export 되었는지 확인해 봅시다.

두 심벌이 export 되어있지만 type information 이 없지만 뭐 찾아보면 다 있겠죠?
조사하면 다 나옵니다. ^.^


KeServiceDescriptorTable 을 위한 SERVICE_DESCRIPTOR_ENTRY 구조체.
ServiceTableBase :
각 서비스 별 매핑 함수 포인터들의 목록이 저장된 테이블의 포인터
ServiceCounterTableBase:
무시 -_-
NumberOfService:
이 테이블이 가지고 있는 서비스의 개수
ParamTableBase:
각 서비스별 파라미터의 크기를 나타내는 값을 가진 테이블의 포인터
--- Windows 의 구조와 원리. 정덕영 저 에서 베껴옴

정리해 보면 Windows System Call 정보를 관리하는 무언가가 있는데 이것은
KeServiceDescriptorTable 이라는 이름으로 export 가 되어있고, 이 테이블의 구조는
위에서 설명한 구조체 모양입니다.
즉 KeServiceDescriptorTable 의 정보를 바꿔치기 하면 윈도우가 제공하는 시스템 콜을 내가 원하는 함수로 대체할 수 있다는 것이죠.
이것이 흔히들 말하는 SSDT HOOK 의 개념입니다.

사실 ring3  ring 0 로의 권한 이행, 즉 유저레벨에서 windows api 호출 -> system call 호출까지의 과정에 대한 이해가 필요합니다. 그러나 여기서 그런 것 까지 설명하기엔.. 이야기가 너무 길어질 것 같고..
Windows 의 구조와 원리(정덕영 저)를 보면 아주 자세히 잘 설명되어 있습니다.
(정말 좋은 책이죠)
아니면 전에 작성한 “Technical Report - Windows system call 분석”를 참고하길 바랍니다.

자 우리가 하고자 하는 것은 KeServiceDescriptorTable 을 변조하는 것이죠?
먼저 무엇을 해야 할까요? 그렇습니다. 변조하고자 하는 KeServiceDescriptorTable 의 주소를 알아야 할 것입니다.
SSDT 의 경우 앞에서 본 것처럼 ntoskrnl 이 export 하고 있기 때문에 별다른 코딩 없이 바로 import 해서 사용할 수 있습니다.
나중에 export 되지 않는 symbol 을 찾아 쪼물딱 거리는 꽁수에 대해서도 보여줄 것이니 너무 조급해 하지 말기를..
아무튼 아래의 코드 한 줄로 땡입니다.


// direct import KeServiceDescriptorTable
//
__declspec(dllimport) SERVICE_DESCRIPTOR_ENTRY KeServiceDescriptorTable;




이걸로 끝이면 얼마 좋겠습니까 만은 뭐 그렇게 만만하지 않죠.
KeServiceDescriptorTable 의 권한 문제가 있습니다.
SSDT 의 겨우 xp 나 2003 에서 read only 이란 것이죠.따라서 read only 로 설정된 커널 메모리 영역을 쓰기가 가능하도록 만들어 주어야 합니다.
만일 read only 영역에 write 를 하면 어떻게 될까요?
기억하시죠 ? 우린 현재 커널 레벨에서 놀고 있답니다. 실수는 용서가 안돼요.
시원스럽게 펼쳐진 파~아란 화면을 만날 수 있을겁니다.
WinDbg 같은걸 연결해 놓은 상태라면 아래와 같은 메시지를 만날 수 있을 것이구요.


kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

ATTEMPTED_WRITE_TO_READONLY_MEMORY (be)
An attempt was made to write to readonly memory. The guilty driver is on the
stack trace (and is typically the current instruction pointer).
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: 8057659e, Virtual address for the attempted write.
Arg2: 00576121, PTE contents.
Arg3: f9c66be0, (reserved)
Arg4: 0000000b, (reserved)


몇 가지 방법이 있는데 지금 2가지 밖에 기억이 안 나네요. (세가지 넘게 있었던거 같은데..)
한가지는 MDL (Memory Descriptor List) 를 이용하는 것입니다.
뽀대 나는 엘레강스한 코드를 보여주지만 좀 복잡해 보이는 방법이죠.
SSDT 가 가리키는 physical memory 에 대한 포인터(?) 를 하나 더 만들어서 접근하는 것입니다. SSDT 가 가리키는 메모리 영역에 대한 심볼릭 링크 같은녀석을 하나 더 만들고요 이 심볼릭 링크는 쓰기 가능으로 두는 겁니다.
SSDT 는 읽기 전용이었지만 새로 만든 심볼릭 링크는 읽기 쓰기가 되므로 쓰기가 되지요.
실제 Write operation 이 발생하는 physical memory 는 동일하구요.

아무튼 이런 방법도 있다 정도로 넘어가죠. 나중에 실제 코드를 보여드릴 기회가 있을겁니다.

또 다른 방법은 CR0 레지스터를 이용해서 SSDT 의 write protection 을 제거하는 것입니다. 예제에서도 사용할 방법입니다.
커널 모드 루트킷이나 IceSword 같은 툴을 분석해 보신분들은 CR0 를 이용해서 write protection 을 제거하는 루틴을 봤을 지도 모르겠습니다.
(예전에 http://somma.egloos.com/2131561 에서도 소개한 바 있지요)


위 그림은 x86 의 Control register 들입니다.
각 레지스터의 용도는 따로 알아서들 공부하시고, 우리가 관심 가질 것은 CR0 레지스터입니다. 그 중에서도 관심 가질 것은 WP 비트입니다.
이 비트는 Write Protection 비트란 말씀입니다.. Copy-On-Write 를 구현하는데도 사용되는 플래그라고 하고요.
완벽한 레퍼런스를 원하시는 분들은 IA-32 매뉴얼 volume 3 chapter 2.5 를 보세요 :)


//
// 콘트롤 레지스터 관련 (IA-32 manual vol3, ch 2.5
// CR0 (Control Register Zero) 레지스터의 WP 비트(16)는 쓰기 속성제어에 사용됨
//
#define CR0_WP_MASK 0x0FFFEFFFF

/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
VOID ClearWriteProtect(VOID)
{
__asm
{
push eax;
mov eax, cr0;
and eax, CR0_WP_MASK; // WP 클리어
mov cr0, eax;
pop eax;
}
}

/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
VOID SetWriteProtect(VOID)
{
__asm
{
push eax;
mov eax, cr0;
or eax, not CR0_WP_MASK; // WP 비트 세팅
mov cr0, eax;
pop eax;
}
}



편의를 위해서 두 개의 함수를 작성했구요 함수 이름만 봐도 알 기능을 알 수 있을 것입니다.


게임 해킹에 자주 사용되는 T-Search 같은 툴을 보면 게임 프로세스의 데이터 영역이나 코드 영역을 수정하는 것을 볼 수 있는데 이런 툴은 어떻게 만들 수 있을까요?

게임 프로세스의 핸들 획득 -> Read/Write process memory 류의 api 를 통해서 해당 메모리 읽기/쓰기 오퍼레이션을 수행할 것이다. 물론 이 방법이 유일한 방법은 아니다.
다른 방법으로도 구현할 수 있을 것입니다. 뭐 간단하죠. 사실 대부분의 툴들이 이렇게 만들어집니다.
이번 예제에서는 이런 툴들을 차단하기 위한 기능을 구현할 것입니다. SSDT hook 을 이용해서 말이죠. 이름 하여 메모리 디펜더 !
좀더 폼 나는 이름 없을까 잠깐 고민했지만 어차피 PoC 수준의 코드이니 대충 넘어가도록 하지요.

메모리 디펜더를 구현하기 위해 OpenProcess () 를 후킹할 것입니다.
Kernel32::OpenProcess() 함수는 ntdll::Zw/NtOpenProcess() 를 호출하는데요
Ntdll::Zw/NtOpenProcess 는 다시 ntoskrnl::ZwOpenProcess() 로 다시 매핑됩니다.
이때 ntdll 의 Zw/NtOpenProcess() 는 service call index 를 사용하고.. sysenter 인스트럭션을 통해 ring0 로 넘어가고, MSR 레지스터를 참조하고…등등..
여러 단계를 거치는데 이에 대한 내용은 위에서 설명한 참고자료를 활용하세요.

아무튼 우리는 ntoskrnl::ZwOpenProcess() 함수를 후킹 할 것입니다.

먼저 후킹할 ZwOpenProcess() 함수의 주소를 얻어야 할 것입니다.
여러 가지 방법을 쓸 수 있겠지만 이 함수 또한 exported 된 함수이므로 아래의 코드로 쉽게 사용할 수 있을 것입니다.



Ntoskrnl.exe 는 ZwOpenProcess() 함수를 export 하고 있는데

이 그림은 IDA 5.0.0.879 버전으로 본 그림인데 IDA 의 버그인 것 같네요. ORZ ..
db 2 dup(0)
이 코드는 헥사 코드로 보면 아래와 같습니다.

B8 에 해당 하는 opcode 를 찾아 보면

Mov 인스트럭션이지요.
여기서 +rd, +rw 지시자는 0xB8 을 베이스로 해서 0-7 사이의 레지스터 인덱스를 더한 값이 opcode 자체가 완성되는데 ZwOpenProcess 의 헥사 코드를 보면 B8 로 시작하는데 레지스터 인덱스의 값이 0 (B8 과 B8 의 차는 0 이므로) 되겠지요.
레지스터 인덱스 0 은 IA 32 메뉴얼을 보면..

파란 박스 부분입니다.
즉 다시 말해서 B8 7A 00 00 00 은
mov ax, 0x7A 또는 mov eax, 0x7A 로 해석되는게 맞다는게 제 결론입니다.
(B8 opcode 는 +rd, +rw 를 모두 받을 수 있는데 지금 같은 경우 +rd 로 해야 하는지 +rw 로 해야 하는지 모르겠다. 아는 분이 있으면 좀 알려주세요. 꼭 ~~~ )

아무튼 IDA 가 만들어낸 코드가 잘 못된 것이 맞는 듯 하네요.


참고로 ntoskrnl.exe 의 다른 함수들을 살펴보면 위와 같이
mov eax, service_index_number
명령으로 시작하지요.
유추해 보건데 NtOpenProcess() 의 맨 처음 명령은
mov eax, 0x0000007A
인게 거의 확실합니다. 진짭니다. 믿으세요.

여기서 중요한 사실 하나를 발견할 수 있는데요.
System call 의 서비스 인덱스 번호는 system call 의 두 번째 바이트에 4바이트 형태로 존재한다는 것입니다.
ZwOpenProcess 함수의 헥사 코드를 살펴보면 아래와 같습니다.

B8 은 mov eax 이고, 뒤에 4바이트 즉, 7A 00 00 00 이 서비스 인덱스 번호인 것이지요.
Little endian 이므로 0x0000007A 값이 바로 ZwOpenProcess() 함수의 인덱스 번호가 됩니다.

앞에서 KeServiceDescriptorTable.ServiceBase 필드는
각 서비스 별 매핑 함수 포인터들의 목록이 저장된 테이블의 포인터
라고 했는데 다시 말하면 서비스 인덱스별 서비스 콜의 주소의 배열이란 얘기가 됩니다. 즉 KeServiceDescriptorTable.ServiceBase[0x7A] == NtOpenProcess 란 겁니다.
참고로 ZwXXX 의 경우 외부 export 용도이고, NtXXX 의 경우 실제 구현코드를 가집니다. 물론 ntdll 의 경우에는 두가지 모두 동일한 주소를 가리키고 있지만 말입니다. Ntdll 은 단순히 proxy 역할만을 한답니다.
궁금하신 분들은 ntdll 과 ntoskrnl 을 직접 열어서 확인해 보기 바랍니다.

앞에서 알아낸 아주 유용한 규칙을 제대로 써먹어 보도록 합시다.
아래의 매크로는 위에서 알아낸 규칙을 코드로 만든 것 뿐입니다.
SSDT 훅을 할 때 아주 유용하게 써먹을 수 있을 것입니다.
(이것은 제 아이디어가 아니라 ntrootkit 의 코드에서 얻은 것 입니다.)

#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function + 1)
#define ORG_SYSCALL_PTR(_orgFunc) \
&(((PLONG) KeServiceDescriptorTable.ServiceTableBase)[SYSCALL_INDEX(_orgFunc)])


후킹할 ZwOpenProcess 의 주소도 얻었고, Write Protection 도 무력화 할 수 있고,
ZwOpenProcess 의 인덱스 번호를 통해서 구현 코드의 주소값도 알아낼 수 있겠고..
아 한가지 빠졌네요.
ZwOpenProcess 를 대체할 hook procedure 를 작성해야죠. ^^ 가장 중요한 걸 빼먹었군요.


뚝딱 ! 다 짰습니다. -_-;;
ZwOpenProcess() 함수 – 정확히 말하면 NtOpenProcess 겠네요 – 의 원형은 인터넷에 한번만 검색하면 잔뜩 나옵니다. Undocumented api 정리해 놓은 책도 있을 정도니까요.
아니면 NtOpenProcess 를 아주 잠깐만 리버싱 해 보면 알 수 있겠죠.

우리의 hook procedure 는 아주 간단합니다.
모든 OpenProcess() 를 실패로 처리해 버립니다. 와우~ 멋지죠 -_- (돌 날라오는 소리가 막 드릴네요~)
실제로 써 먹기 위해서는 동적으로 보호할 프로세스의 ID 나 핸들을 받아서 처리해야 겠죠. 물론 예외처리 (B 프로세스는 A 프로세스를 Open 할수 있게 하는등의)도 필요할 테구요. 이런 구현을 위해서는 DeviceIoControl() 등을 써서 통신을 해야 할 것입니다.
그런 예제는 다른 곳에서 많이 보실 수 있을 것이구요.

이제 잘 동작하는지 테스트를 해봐야 겠죠?
드라이버 로더는 지난번에 사용한 FxLoader 를 씁니다.


디버그 메시지를 확인 하기 위해 Dbgview 로 실행해 주세요.

FxLoader 를 열고 드라이버를 선택하고,
Init -> Register -> start 버튼을 차례로 누르면 됩니다. 아시죠?

이제 Cheat Engine 프로그램으로 테스트를 해봅시다.
Cheat Engine 은 범용 게임 해킹 도구입니다. T-Search 처럼 프로세스의 특정 값을 찾는데에도 쓰이고, 메모리를 조작하는데도 사용할 수 있구요.
스피드 핵도 되지요.
앞에서 설명한 것처럼 모든 기능을 제공하기 위해서는 프로세스의 핸들을 얻어야 하는데 그것을 커널에서 차단하고 있기 때문에 불가능합니다.
오~ 훌륭하단 생각이 들지 않습니까?


이것 뿐만 아니라 작업 관리자에서 프로세스 종료를 눌러도 프로세스가 종료되지 않습니다.


SSDT 를 이요하면 참 많은 재밌는 일을 할 수 있습니다. 프로세스 숨기기, 파일 폴더 숨기기 등등 하고 싶은건 다 할 수 있지요. 보시다 시피 별로 어려운 것도 없거든요.
벌써 부터 사악한 짓 할 생각에 벌써 부터 즐거워 지시는 분들이 꽤 보이는것 같군요.
그런데 후킹 하는것도 쉽지만 탐지하는것도 무진장 쉽답니다. 일반 적인 API 후킹 탐지랑 똑같거든요.
당연히 복원또한 어렵지 않고요.

사실 많은 보안 제품들 (PC 용 방화벽, DRM 등등) 이 많이 사용하는 기술중에 하나가 SSDT 훅입니다.
해킹에 쓰인다면 더 없이 강력한 도구가 되지요. 그러나 hook 이 가지는 단점을 그대로 안고 가는 문제도 있습니다. 내가 후킹한 걸 복원시켜 버리거나 아니면 제 3의 드라이버가 다시 후킹해 버리면 말짱 꽝이되지요.
그래서 몇 몇 제품들은 자신만의 SSDT 를 만들어서 사용하고는 합니다.
그렇게 되면 SSDT 훅에 상관없이 자신만의 코드를 사용할 수 있게 되지요.
이를 SSDT relocation 이라 부르기도 합니다.
나중에 기회가 된다면 보여드리지요.


덧글

  • seyool 2006/10/07 23:55 # 삭제 답글

    제가 일등이네요 ㅎㅎ
    형수님 쾌유하시길 바랍니다 ^^
  • Mins 2006/10/11 15:50 # 삭제 답글

    소마형 블로그 rss feed 가 제대로 동작되지 않는거 같네요....
    제가 너무 많이 긁어대서 그런건가봐요 -_-;;;;;
  • somma 2006/10/16 23:53 # 답글

    음..왜 안댄대?
    난 몰라.. (rss 가 먼지도 잘 모름.. -_-)
  • chp 2006/10/20 00:51 # 삭제 답글

    SSDT후킹이 이렇게 하는거였군요~
    매우 재미있는 부분이내요
  • QA 2006/10/20 07:14 # 삭제 답글

    SSDT Hook 내용 잘봤습니다.
    질문이 있습니다. 마지막에 언급하신 SSDT relocation 에 대해서 설명을 좀 해주실수 있으신지요.
    요즘 제가 구현할려고 하는 기능과 비슷한것 같아서 질문 드립니다.

    A라는 프로그램이 ZwOpenProcess, ZwTerminateProcess 를 hooking 하여 자신의 프로그램 종료를 막고 있는 상태에서
    나의 App가 A 프로그램을 종료 할려고 합니다.
    제가 SSDT를 restore 시키니 A 프로그램이 강제로 shut down 시키더라구요. 전 O/S가 shutdown 되는걸 원치 안고, A 프로그램을
    gracefull 하게 종료 시키고 싶습니다. 한 수 가르침을 주십시오.
    님의 예제가 올라오길 간절히 기다리고 있지만, 시간이 많이 걸릴것 같고해서, 간단하게나마 좀 가르쳐 주실수 없으신지요?

    메일: crdel골벵이daum.net
  • somma 2006/10/20 13:20 # 답글

    chp / 재밌죠 ^^
    QA / SDT relocation 듀얼님의 홈페이지에 가면 찾을 수 있을 것 같네요..
    http://dualpage.muz.ro/
    듀얼님의 소스코드를 살펴보진 않았지만.. 아마 님이 원하는 코드를 찾을 수 있을 것 같습니다.
    단순하게 (개념은 똑같지만) 해당 함수 코드를 복사해서 nonpaged pool 에 복사해 두시고, 유저레벨단에서 해당 프로세스 종료를 위한 ioctl 코드를 날려주면 될것 같은데요.. 드라이버는 ioctl 을 통해 넘어온 pid 를 가지고, 복사된 (깨끗한 상태의) NtTerminateProcess 를 호출하게 되는거지요.
  • 까마구 2006/10/23 03:17 # 답글

    오오~ 멋진 내용입니다. 정리가 상당히 잘되어있네요 ^^
  • somma 2006/10/24 10:17 # 답글

    까마구/ ^.^ 감사합니다.
  • nabty63 2006/10/26 08:10 # 삭제 답글

    강의 잘 봤습니다.
    영어로 된 문서들을 보면서 뭐가먼지 헤메다가 이곳에서 이제야 감이 좀 오는거 같네요,ㅋ
    귀.찮.으시더라도 강의 좀 더 해주세요. *^^*
  • 미친감자 2007/01/05 22:38 # 답글

    정말 정말 훌륭하십니다...
  • somma 2007/01/06 00:14 # 답글

    훌륭하긴여.. SSDT 훅 예제코드는 인터넷에 널려있는데요...ㅎ~
    요즘 미친감자님 만화(?) 잘 보고 있습니다.
    나날이 그림이 멋져지는듯 하네요 ^^;; (그러다 직업 바꾸시는건 아닌지..ㅎㅎ)
  • baekjae 2007/10/31 20:25 # 삭제 답글

    소마님 글 잘 보고 있습니다.
    글을 보던 중 궁금한 사항이 있어서요. 이 글 중간에 보면

    “Technical Report - Windows system call 분석”

    이라는 문서가 언급되어 있는데요. 저 문서가 따로 있는건지요?
    구글링을 해도 문서는 안나오내요;;; 완전 관심있는 문서입니다 ^--^
  • somma 2007/10/31 23:18 # 삭제 답글

    baekjae / 안녕하세요. ^^
    원래 "드라이버 쪼물닥거리기 " 시리즈(?) 가 내부 교육용 자료로 처음에 만들기 시작했던 거였는데...
    그러다 보니 내부 문서제목이 나왔습니다. ^^
    별내용은 아니고요.. 그냥 windows api 가 호출되면 커널까지 어떤 과정을 거쳐서 내려가고 어떻게 실행되는지에 대한 문서입니다.
    정덕영씨가 쓴 "windows 구조와 원리" 에 나온 내용과 크게 다르지 않습니다. ^^
  • binish 2008/01/03 01:40 # 삭제 답글

    대단히 잘 봤습니다 ^^ 감사합니다.
  • somma 2008/01/03 14:26 # 삭제 답글

    binsh/ 감사합니다. ^^
  • 너부리 2008/01/29 22:26 # 삭제 답글

    안돌아가는데요.

    좀 더 자세히 말하면 후킹 부분의 디버깅 메세지 KdPrint( ("[*] pid : %d protected", cid.UniqueProcess) ); 이거는 뜨는데, 결정적으로 프로그램 실행이 다 됩니다.
    그리고 ProcDD: Device I/O Control Processed. status = C0000022 이 말이 디버깅창에 뜹니다.
    (여기서 C0000022라고 나온건 ACCESS_DENIED로 제가 임의로 바꿔서 그렇습니다.)
  • somma 2008/01/30 19:35 # 삭제 답글

    너부리 / 예제에서는 ZwOpenProcess() 가 항상 실패하도록 만든것입니다.
    만일 어떤 프로그램이 OpenProcess() 가 실패하는 경우 실행이 안되는 경우라면 문제가 되겠지만 그렇지 않은경우는 프로그램 실행이 다 될 것입니다.
    (대부분이 다 될겁니다. OpenProcess() 가 fail 된 경우에 대한 처리를 다 할테니까요)
  • kvirus 2010/05/04 22:37 # 삭제 답글

    somma님 컴파일도중 에러가 생겨서 문의드립니다.
    에러는 error 2275 : 'ZOPENPROCESS' : illigal use of this type as an expression 이라는 에러가 나는데요,
    oldZwOpenProcess(ZWOPENPROCESS)ORG_SYSCALL_PTR(ZwOpenProcess);
    이부분에서 에러표시가되네요 .. 도대체 무슨문제인지 전혀 감을 못잡겠습니다 ㅠ..
    도움 부탁드립니다.
  • somma 2010/05/04 22:43 # 삭제

    타입을 식으로 썻다는 에러네요.
    oldZwOpenProcess(ZWOPENPROCESS)ORG_SYSCALL_PTR(ZwOpenProcess);
    ==>
    oldZwOpenProcess = (ZWOPENPROCESS)ORG_SYSCALL_PTR(ZwOpenProcess);
    요렇게 써야 할 것 같은데요 ??
  • kvirus 2010/05/04 22:54 # 삭제 답글

    ㅠㅠㅠㅠㅠㅠ....정말 매우 너무나도 감사하고 또 감사드립니다.
    내일모래 SSDTHooking 발표가있었는데 이거하나 못찾아서 몇시간째 고생하고있었는데 ㅠㅠ.....
    정말 감사드립니다....절살려주셧어요 ㅠㅠ.........
    실례가 되지않는다면 제블로그에 링크를 걸어놔도 괜찮을까요?
    다시한번 감사합니다.
  • somma 2010/05/07 17:11 # 삭제

    ㅎㅎ 도움되셨다니 저도 좋군요...링크는 마음대로 하셔도 되요. 저야 좋죠 ~ 어차피 공개된 블로그인데요.. ^^
  • 하이요 2013/03/09 11:18 # 삭제 답글

    엔진의 openprocess를이용한 종료불가를 만들수 있을까요?
    댓글에 아신다면 답글좀달아주시면감사하겟습니다
  • 2019/07/12 19:23 # 삭제 답글

    음 의견을 드리자면, B8을 Intel 메뉴얼 부록에 수록된 Opcode Table에서 찾아보면 MOV eAX, Iv 죠. 인텔문서에서 I는 Immediate v는 Word, doubleword or quadword (in 64-bit mode), depending on operand-size attribute.로 설명되어있는데 즉, x86에서는 Operand Size 관련 Prefix가 없는 경우 디폴트로 Operand Size는 32비트가 되고, MOV EAX, DWORD Immediate로 해석되는 거지요.
  • somma 2019/08/15 01:56 # 삭제

    우와 대박!
    13년전 글에 댓글을, 그것도 정확히 답을 알려주시다니!
    감사합니다!!!!!!
댓글 입력 영역