성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>한 대의 PC에서 여러 개의 키입력 매크로 프로그램이 가능할까?</div><br /> <br /> 저는 SDK 레벨의 개발자입니다. 그래서 때로 DDK 레벨의 개발자들이 부럽습니다. ^^<br /> <br /> 마침, 이번 마소 3월호의 248 페이지에 "리버싱으로 분석하는 온라인 게임 해킹툴"이라는 재미있는 ^^ 기사를 읽게 되었는데요. 역시 DDK하는 사람들은 리버싱 실력 자체가 다릅니다. 너무 너무 멋있다는! ^^<br /> <br /> 이야기를 좀 벗어나서.<br /> <br /> 한때 저도 "모" 게임에 푹 빠졌을 때가 있었다는 사실... 아셨나요? ^^<br /> 그 게임에서 구현한 3차원 세계는 정말이지 온라인 게임을 처음 접한 저에게는 신세계와 같았습니다. (결과적으로 지금 생각해 보면, 이때 온라인 게임의 폐해를 알았기에 나중에 WOW가 나왔어도 심드렁할 수 있었던 것 같습니다. ^^;)<br /> <br /> 제가 그렇게 게임에 빠져있을 때, 나름대로 ^^ 만든 매크로 프로그램을 만들어서 아주 잘 활용했었습니다. 그렇다고 무슨 자동 사냥하는 프로그램은 아니었고, 컴퓨터 2대에서 게임 클라이언트를 각각 실행하고, 한 대에서 제가 게임을 하면서 다른 한대에 실행된 캐릭터를 같이 조정할 수 있는 프로그램이었습니다. 예를 들어, 제 컴퓨터의 "a" 키를 누르면 다른 PC의 캐릭터가 같이 공격해 주고, "h" 키를 누르면 제 캐릭터에 에너지를 보충 할 수 있도록 한 것이었습니다.<br /> <br /> "리버싱으로 분석하는 온라인 게임 해킹툴" 기사를 보면서, 그때 제가 만든 그 프로그램이 생각났습니다. 기사에서는 "고전적인 매크로 구현 방법"이라고 하면서 "keybd_event", "mouse_event"를 예로 들었는데 실제로 제가 만든 그 프로그램에서도 "keybd_event" API를 사용해서 구현했었습니다.<br /> <br /> 기사에서 언급되고 있지만, "keybd_event, mouse_event" API는 게임 보안 솔루션에서 사용을 막았기 때문에 이젠 구식이 되어버린 기술이라고 합니다. <br /> <br /> 그때 기억도 되새길 겸. 정말로 모 업체의 3-D 게임 하나를 다운로드 받아서 테스트를 해봤습니다. 오호... 정말 안됩니다. ^^; 재미있게도 게임 프로그램이 전면에 뜰 때만 keybd_event 함수가 동작 안하고 다시 다른 응용 프로그램이 전면으로 오면 동작을 합니다. keybd_event 유의 함수가 다른 프로그램에서는 "유용한" 매크로로 쓰인다는 점에 대한 세심한 배려가 돋보입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 해보는 김에. 기사에서 언급된 0x64, 0x60 포트를 이용해서 제어를 해보고 싶었습니다. 말씀드린 데로 저는 SDK 개발자이기 때문에 드라이버 개발은 해본적이 없습니다. (사실 Hello World 수준의 dummy 드라이버는 실습해봤지만, 그 이상은 해본 적이 없습니다.)<br /> <br /> 그래서 검색을 해봤더니. 아하... ^^ 공개된 프로그램이 하나 눈에 띄입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > NTPort Library ; <a target='_tab' href='http://www.zealsoftstudio.com/ntport/'>http://www.zealsoftstudio.com/ntport/</a> </pre> <br /> 평가판을 다운로드 할 수 있는데, 그렇다고 기능 제약이 있는 것은 아니고 최초 구동시에 라이선스 알림 대화창이 뜬다는 제약만 있기 때문에 테스트 용으로는 전혀 손색이 없습니다.<br /> <br /> 그럼. 일단 포트를 읽고 쓰는 드라이버는 구했고. 다음 문제는 어떻게 사용해야 키 입력을 흉내낼 수 있느냐는 것인데.<br /> <br /> 생각보다, 이 방법을 언급하고 있는 자료를 찾기가 쉽지 않았습니다. 겨우 찾은 방법이 아래 문서의 11페이지에 나온 정도입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Keylogging Analysis ; <a target='_tab' href='http://codeengn.com/?module=file&act=procFileDownload&file_srl=233&sid=7f06fd348c558e70720143533138db07'>http://codeengn.com/?module=file&act=procFileDownload&file_srl=233&sid=7f06fd348c558e70720143533138db07</a> </pre> <br /> 위의 내용을 NTPortLibrary 코드로 다시 쓰면.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > bool is_buffer_empty(void) { int timeout; for(timeout = 200; timeout && (Inport(0x64) & 0x02); timeout--) { Sleep(1); } retrn timeout != 0; } if (is_buffer_empty() == false) { return; } Outport(0x64, 0xD2); if (is_buffer_empty() == false) { return; } Outport(0x60, <b style='COLOR: blue'>scanCode</b>); </pre> <br /> 위의 코드에서 scanCode 값은 아래 문서의 16페이지에서 찾아볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Keyboard Scan Code Specification ; <a target='_tab' href='http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc'>http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc</a> </pre> <br /> <img alt='keyboard_port_io_scancode_1.png' src='/SysWebRes/bbs/keyboard_port_io_scancode_1.png' /><br /> <br /> 즉, scanCode 값에 10을 넣으면 키보드로 "9" 숫자키를 입력한 것과 동일한 효과를 발생합니다.<br /> <br /> 자, 이 정도 하고 다시 게임 프로그램을 실행시키고 테스트 해봅니다. 우와~~~ 이번에는 정상적으로 문자가 전달됩니다. ^^ 아직 여기까지는 보안 프로그램이 막지 않았나 봅니다. (이 프로그램에 쓰인 보안 프로그램만 이것을 막지 않은 것인지, 아니면 이것을 원천적으로 막을 수 없는 것인지는 잘 모르겠습니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그런데. 재미있는 방법이 하나 더 있습니다. <br /> "Remote Desktop" 아시죠? mstsc.exe 프로그램으로 원격 접속하는.<br /> <br /> 예전에는 RDS 환경이 그다지 좋지 않아서 RDS 세션 환경에서는 3-D 프로그램이 실행되지 않았었는데, 어느새 시간은 흘러 ^^ 그것도 이젠 옛날 이야기가 되어버렸습니다. 그러니까, Windows Server 2008 R2에서 제공되는 RDS 환경에서는 3-D 프로그램도 정상적으로 실행이 됩니다. (제가 테스트 해본 바에 의하면 Vista 원격 접속 지원에서도 3-D 프로그램이 실행되었기 때문에 아마도 Windows Server 2008에서도 되지 않을까... 예상합니다.)<br /> <br /> 그렇다면 RDS 환경에서 게임 프로그램을 실행한 경우에는 키 입력을 위한 매크로 프로그램이 어떻게 작동할 수 있을까요? 우선, RDS 환경 내에서 포트 제어를 통한 키입력 방법은 효과가 없습니다. 짐작으로는, RDP 클라이언트 측에서 마우스/키 입력이 RDS 세션으로 전달되어 처리되는 방식이기 때문에 물리적인 하드웨어의 포트를 제어하는 방식으로는 RDS 세션 내의 프로그램에 영향을 주지는 않는 것 같습니다.<br /> <br /> 또한, "keybd_event, mouse_event" API도 RDP 환경 내에서 동작은 하지만 여전히 보안 프로그램이 설치된 게임 클라이언트에는 동작하지 않습니다.<br /> <br /> 그런데! ... 이쯤 되면 눈치채신 분도 계시겠지만.<br /> <br /> 어차피 게임 클라이언트는 그것이 실행된 윈도우 세션 내에서의 "keybd_event, mouse_event"에 대해서만 막을 수 있기 때문에, "RDP 클라이언트가 실행된 환경"에서 "keybd_event, mouse_event" API를 실행시켜 전달하는 것은 가능하다는 것입니다. 말로 설명하는 것보다 아래의 화면을 보면 이해가 되시겠죠. ^^<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='keyboard_port_io_scancode_2.png' src='/SysWebRes/bbs/keyboard_port_io_scancode_2.png' /><br /> <br /> 위의 그림에서는 Windows 7 운영체제에 키 입력을 keybd_event 함수를 이용해서 발생시키는 "MainWindow"라는 제목을 가진 프로그램과 mstsc.exe 프로그램이 실행되어 있습니다. 보는 것처럼, MainWindow 프로그램에서 발생하는 keybd_event에 의해서 mstsc.exe에 숫자 키 "9"가 전달되는 것을 확인할 수 있습니다. 일단 메모장을 실행시켜서 테스트하고 있지만 게임 클라이언트라고 하더라도 정상적으로 키 입력을 "받아들일 수밖에" 없습니다. 왜냐하면 그 입력이 keybd_event에 의한 것인지 사용자에 의한 것인지 "RDS 세션에서 작동 중인 게임 프로그램에 설치된 보안 프로그램 입장"에서는 구별할 수 있는 방법이 없기 때문입니다.<br /> <br /> 그렇다면!<br /> 손쉬운 자동 사냥 프로그램을 못하게 하려고 keybd_event 함수를 막았던 보안 업체는, 위와 같은 방식의 자동 사냥 프로그램은 어떻게 막을 수 있을까요? 아마도, 아예 RDS 환경에서는 게임이 실행되지 못하도록 만들어야 하지 않을까 싶은데요. 정말... 그렇게 막아버리게 될까요? ^^<br /> <br /> 한 가지 더 재미있는 사실이 있습니다.<br /> <br /> 그동안, "전면에 띄워진 윈도우"에만 키 입력이 전달되었기 때문에 "하나의 PC"에서 하나의 매크로 프로그램만을 동작시킬 수 있었지만 RDS 세션을 활용하게 되면 "하나의 PC"에서 다중 RDS 세션을 열어서 여러 개의 매크로 프로그램을 돌리는 것이 가능합니다.<br /> <br /> 이런 거 보면, 정말이지 ^^ 컴퓨터는 다양한 기술의 조합에 따른 운영의 묘미가 있는 것 같습니다.<br /> <br /> 이게 끝일까요? ... 알 수 없습니다. 언제나 기술은 변화하기 때문에.<br /> 2003년 PDC에서 언급된 "<a target='_tab' href='/2/0/488'>Multiple Input Queues</a>"가 구현된다면... 위와 같이 다중 세션을 열어놓을 필요도 없을 테니까요.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 마지막으로 한 가지 더 재미있는 사실.<br /> Windows Server 2008 R2의 RDS 연결 제한은 기본적으로 "Administration" 모드로 제공되는 라이선스로 인해 2개이고, 라이선스 서버를 제공하는 경우에만 2개의 제한을 없앨 수가 있습니다.<br /> <br /> 그런데, 예전에 제가 Windows 7의 RDP 연결에서 1개의 연결 제한을 해제하는 (정식이 아닌) 패치를 알려드렸었지요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Windows 7 - 다중 원격 접속(Remote Desktop) 허용 ; <a target='_tab' href='/2/0/782'>http://www.sysnet.pe.kr/2/0/782</a> </pre> <br /> 재미있게도 그 패치를 적용하면 RDP 연결 수에 제한이 없습니다.<br /> <br /> 이번 글을 쓰면서, VPC에 설치해 둔 Windows Server 2008 R2에도 해당 termsrv.dll을 테스트해 보았습니다. 오호... 2개의 연결 제한을 갖는 "Administration Mode"가 해제되었다는!<br /> <br /> <hr style='width: 50%' /><br /> <br /> 첨부한 파일은 본문에서 설명한 2개의 문서와 소스 코드입니다.<br /> <br /> <a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=525&boardid=331301885'>polling.pdf</a>: 위에서 설명한 Keylogging Analysis PPT 문서<br /> <a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=526&boardid=331301885'>scancode.doc</a>: 위에서 설명한 Keyboard Scan Code Specification 문서<br /> <a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=524&boardid=331301885'>Console.zip</a>: NTPortLibrary를 이용한 키입력 테스트 프로젝트 (VS2010)<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6846
(왼쪽의 숫자를 입력해야 합니다.)