정말 오랫만의 포스팅이네요!

... 이전에 포스팅 하려고 임시 저장해놓은 글이 있는데 30일이 지나서 사라졌습니다......


각설하고 바로 본론으로 들어가겠습니다.

며칠전, SecureString 을 살펴보던 도중 흥미로운 API를 발견했습니다.

바로 SystemFunction040, SystemFunction041 로 명명된 API입니다.


SystemFunction040 < - > RtlEncryptMemory

SystemFunction041 < - > RtlDecryptMemory


그리고 MSDN 페이지에는 RtlEncryptMemory 로 나옵니다. 하지만 RtlEncryptMemory 를 호출하면? 호출이 안됩니다..

C# 이나 VB의 경우엔 DllImport 특성을 적용하고 EntryPoint 매개 변수에 SystemFunction040, SystemFunction041 이렇게 해야겠지요.



(이러라고 만든 DirectX 프로그램이 아닐텐데......)


예제에서 보시면 아시겠지만 메모리의 값을 0x1080DEADBEEF0801 로 주었습니다.

값을 암호화하기 전에는 0x1080DEADBEEF0801 이라는 값이 정상적으로 나오지만, 암호화한 경우 0x7BA0B380360C3842 라는 값이 나오게 됩니다.



이 API의 원리는 간단합니다.

이 API는 세 개의 매개 변수를 필요로 하는데

첫째 매개 변수에서는 암호화 또는 복호화할 메모리를,

둘째 매개 변수에서는 메모리의 길이를,

마지막 매개 변수에서는 암호화 또는 복호화 옵션입니다.


이 마지막 매개 변수가 아주 중요한 역할을 하는데,

0 - API를 호출한 프로세스만 메모리를 암호화, 복호화할 수 있는 옵션

1 - API를 호출한 프로세스 및 다른 프로세스가 메모리를 암호화, 복호화할 수 있는 옵션

2 - API를 호출한 프로세스 및 같은 로그온 세션에 있는 프로세스가 메모리를 암호화, 복호화할 수 있는 옵션

이렇게 세 가지가 있습니다.



암호화 또는 복호화할 메모리의 공간 및 두 번째 매개 변수로 넘겨주는 길이 값은 반드시 RTL_ENCRYPT_MEMORY_SIZE (8) 의 배수가 되어야 합니다.

즉, 길이가 4인 문자열을 암호화하려는 경우엔 "abcd    " 와 같은 식으로 넘겨줘야 하겠죠!



SystemFunction040 및 SystemFunction041 의 C# 선언은 다음과 같습니다.

[DllImport("advapi32")]
static extern Int32 SystemFunction040([In, Out] Byte[] buffer, Int32 bufferLength, Int32 flags);
[DllImport("advapi32")]
static extern Int32 SystemFunction041([In, Out] Byte[] buffer, Int32 bufferLength, Int32 flags);


[In, Out] Byte[] 대신 IntPtr 를 사용해도 됩니다.



이 API는 정말 신기한게 호출하고 나서 메모리에 접근을 하면 완전 다른 값으로 바뀌어 있습니다.

저는 처음 이 API를 봤을 때 호출하고 나면 VirtualProtectEx API등으로 접근 권한을 없애나보다 싶었는데 그게 아니였습니다 .. 

잘만 활용하면 로컬 컴퓨터에서 괜찮은 인증 방법을 새로 구현할 수도 있겠네요 :)


다음 글에는 자세한 사용 방법을 소개하도록 하겠습니다.


.. 오랫만의 포스팅이라 그런지 설명도 부족. 내용도 부족. ㅠㅠ 죄송합니다 ... 힘내겠습니다. 읽어 주셔서 감사합니다 :)

+ Recent posts