일부 보안 모듈의 경우 윈도우 API 를 조금 더 안전한(?) 채널을 통해 사용하기 위해...

필요한 모듈을 다른 이름으로 복사 후 로딩하는 경우가 있습니다.


여기선 kernel32.dll 을 복사해서 로딩할 때 조심해야 될 부분을 가볍게(?) 살펴보고자 합니다.

kernel32.dll 이 로딩될 때 ntdll.dll 모듈의 데이터 영역에 영향을 미치는 부분을 확인했는데요...


다음과 같은 부분들이 영향을 받더군요.


일반적인 상태의 ntdll.dll 의 데이터 영역



프로세스를 실행하면 보통~ ntdll.dll 의 데이터 영역은 위와 같이 kernel32.dll 의 함수를 가리킵니다.



이후 kernel32.dll 을 복사해서 로딩하면...


새로운 kernel32.dll 로딩 후 ntdll.dll 의 데이터 영역



붉은 박스 표시한 부분의 데이터가 바뀌면서 새로 로딩한 kernel32.dll 의 함수를 가리키더군요...



호기심에 kernel32.dll 의 코드를 살짝 봤습니다.


실행의 시작은 EntryPoint ...




kernel32.dll 의 초기화 코드의 일부



kernel32.dll 의 초기화 코드 중 위와 같은 부분이 있더군요... @_@


자기자신의 함수 주소를 RtlSetThreadPoolStartFunc, LdrSetDllManifestProber 등을 이용해...

설정을 하는 부분인데요..

호출되는 함수의 코드는 다음과 같습니다.


RtlSetThreadPoolStartFunc, LdrSetDllManifestProber



RtlSetThreadPoolStartFunc LdrSetDllManifestProber 는 ntdll.dll 의 함수이구요...

ntdll.dll 의 특정 영역에 인자로 전달받은 함수 주소를 쓰는 것을 알 수 있습니다.

( RtlpStartThreadFunc, RtlpExitThreadFunc, LdrpManifestProberRoutine, LdrpCreateActCtxLanguageW )



즉... kernel32.dll 을 복사해서 로딩을 하면 개발자의 의도(?)와는 전혀 상관없이...

ntdll.dll 의 일부 데이터가 복사본을 가리키도록 되어있고... 

그 순간부터 시스템 내부적으로 동작하는 일부 코드들은 복사본에 대한 의존성이 생기게 됩니다.


나만 사용해야지(?) 하고 로딩한 모듈인데... 실제로는 그게 아닌거죠...;;;

개발자가 인지하기 힘든 백그라운드에서 알게 모르게 복사본 코드가 실행이 될 수 있다는 거...


요런 상황에서 복사본을 Free 시켜버리면 문제가 발생합니다.

복사본이 로딩될 때 변경한 ntdll.dll 의 데이터들은 여전히 복사본을 가리키고 있거든요...

복사본이 Free 된 후에 해당 데이터들을 호출하려는 코드에서는 Access Violation 이 발생하는거죠.. @_@



일단 kernel32.dll 복사본을 로딩했으면... 

이 녀석은 프로세스 종료될 때 알아서 증발하도록 내버려두는게 상책입니다... @_@ ;;



ps... 

꼭 kernel32.dll 모듈이 아니더라도 시스템 모듈의 경우 비슷한 문제가 발생할 수 있습니다.