사실 예~~~전에 처음 Syntax Highlighter 적용할 떄~


그 당시 최신 버전을 적용하려고 했는데... 


제 블로그에서만 이~~상한 형태로 코드가 출력이 되는걸 보고...


최신 버전을 버리고 구버전(2.0.320)을 설치를 했습니다. 



토큰별로 개행되는 신기한 현상



그러다가 오늘 문득...=_=;; 다시 생각이 나서 시도를 했고...


결국은 성공했습니다~!!!



블로그의 skin.html, style.css 파일을 PC 로 가져와서~~


직접 하나하나 테스트를 해봤더니 유독 <div class= "article"> ~ </div> 안에서만 문제가 생기고...


다른 곳에서는 정상적으로 출력이 되더군요..



이게 원하는 출력!!!



꽤 오래전 일입니다...


Syntax Highlighter 적용하기 전에 VI 에서 코드를 HTML 로 변환해주는 툴을 써서~


코드를 올린 적이 있는데 그 당시 css 에 추가한 코드때문에 문제가 발생하더군요..



문제의 코드... oTL;;;


저 코드를 제거한 후 3.0.83 버전으로도 정상적으로 출력이 될 때의 그 희열이란~!!!



결국 위의 코드를 제거하고 예전에 소스코드를 올렸던 글들 하나하나 들어가서~~


<code> ~ </code> 로 감쌌던 부분에 Syntax Highlighter 를 적용시키는 삽질을 조금 전에 완료했습니다.. =_=v...

( 물론 오래된 글 중 귀찮아서 안한것도..;;; )



ps... 

페이스북 / 트위터 연동시켜둔 바람에 예전 글들이 주르륵 공유된 걸 보고...

다시 하나하나 삭제했다는게 함정...



저작자 표시 비영리 변경 금지


Sublime Text 3



예전에 우연한 계기로 Sublime Text(http://www.sublimetext.com)라는 에디터를 알게 됐고~

공식 홈페이지 첫화면에 나오는 대표기능(?) 영상을 보고 감동을 받은 후로~~

지금까지 계속 사용하고 있습니다 ㅎㅎㅎ ~ :))


보란듯이 등록 유저 인증 -_-v



Sublime Text 3 를 처음 설치하면 기본적으로 C++ 에 대해서는 gcc/g++ 을 컴파일러로 인식하도록 되어있습니다.

운영체제가 리눅스거나 윈도우라도 MinGW (or Cygwin) 가 설치된 상태라면 상관없겠지만...

Visual C++ 만 설치된 환경이라면 조금 답답하죠~ :((


그래서 Visual C++ 사용자들 입맛(?)에 맞게 빌드 환경을 설정하는 과정을 정리해봤습니다.


Sublie Text 3 가 설치된 폴더를 보시면 "Packages" 라는 폴더가 있고...

그 폴더 안에 '.sublime-package' 확장자를 가진 파일들이 많이 있는데, 

이 파일들이 Sublie Text 3 에서 제공하는 기본 설정 파일들입니다.


Sublime Text 3 가 설치된 경로의 "Packages" 폴더



파일들 중 '[언어].sublime-package' 파일들이 각 언어에 대한 기본 설정 파일입니다.

이 파일들은 ZIP 포맷으로 압축이 되어있으며~ ZIP 포맷을 지원하는 압축 관련 유틸로 풀 수 있습니다.


우리가 설정하려고 하는 언어는 'C++' 이니 'C++.sublime-package' 압축을 풀어봅시다~


"C++.sublime-package" 파일 안에 들어있는 내용들


위에 보이는 'C++.sublime-build' 파일이 빌드 환경에 대한 설정 파일입니다. :)

JSON 형식이라 일반 텍스트 에디터로도 편집이 가능한데요~

저 파일을 열어보면 기본적으로는 아래와 같이 되어있을 겁니다.


'C++.sublime-build' 파일의 내용


g++ 이 설정되어있는 게 보이시죠...?? 

여기서 g++ 로 빌드 명령을 조합하는 부분들을 Visual C++ 에 맞게 고쳐주면~

Visual C++ 를 기본 컴파일러로 사용할 수 있습니다.


참고로 저는 아래와 같이 설정을 해두었습니다.


Visual C++ 용 빌드 환경 설정


{
	"cmd":
	[
		"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\bin\\vcvars32.bat",
		"&&",
		"cl.exe", "/EHsc", "/O2", "/GS", "/Fm", "${file}"
	],
	"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
	"working_dir": "${file_path}",
	"selector": "source.c, source.c++",
	"encoding": "cp949",

	"variants":
	[
		{
			"name": "Run",
			"cmd":
			[
				"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\bin\\vcvars32.bat",
				"&&",
				"cl.exe", "/EHsc", "/O2", "/GS", "/Fm", "${file}",
				"&&",
				"${file_path}/${file_base_name}.exe"
			],
		},
		{
			"name": "Build_Dll",
			"cmd":
			[
				"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\bin\\vcvars32.bat",
				"&&",
				"cl.exe", "/EHsc", "/O2", "/GS", "/Fm", "/LD", "${file}",
			],
		},
		{
			"name": "Build_sys",
			"cmd":
			[
				"C:\\Windows\\System32\\cmd.exe", "/k",
				"C:\\WinDDK\\7600.16385.1\\bin\\setenv.bat", "C:\\WinDDK\\7600.16385.1\\", "fre", "x86", "WNET",
				"&&",
				"DDKBUILD.cmd", "-WNETXP", "fre", "${file_path}", "-cZ",
			],
		}
	]
}



'C++.sublime-build' 파일을 자신에 맞게 수정했으면~

다시 원래대로 다른 파일들과 함께~ 'C++.sublime-package' 라는 이름으로 ZIP 포맷으로 압축을 하고 

"Packages" 폴더에 넣어주시면 됩니다.

( 혹시라도 잘못 수정할 경우를 대비해 원래 파일은 백업해 두시는걸 권장합니다. ㅎㅎ )


위와 같은 일련의 과정들이 끝나면 C++ 에 대해서 Visual C++ 컴파일러가 동작하는 것을 볼 수 있습니다. :))


( 개인적으로는 Sublime Text 에 손이 익숙해지니 Visual C++ IDE 에서 작업하는게 엄청 답답하더군요;;;.. )


보너스로... 빌드를 조금 더 쉽게(?)하기 위한 단축키 설정입니다.

( 'Preferences -> Key Binding - User' 에서 설정할 수 있습니다. )


단축키 설정


[
	// Alignment
	{ "keys": ["ctrl+alt+a"], "command": "alignment" },

	// Build
	{ "keys": ["f5"], "command": "build" },
	{ "keys": ["ctrl+f5"], "command": "build", "args": {"variant": "Run"} },	
	{ "keys": ["ctrl+b", "ctrl+b"], "command": "build" },
	{ "keys": ["ctrl+b", "ctrl+d"], "command": "build", "args": {"variant": "Build_Dll"} },	
	{ "keys": ["ctrl+b", "ctrl+s"], "command": "build", "args": {"variant": "Build_sys"} },	
]


[ Sublime 기능 관련 영상 ]







저작자 표시 비영리 변경 금지


일부 보안 모듈의 경우 윈도우 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 모듈이 아니더라도 시스템 모듈의 경우 비슷한 문제가 발생할 수 있습니다.


저작자 표시 비영리 변경 금지