예전에도 글로 쓴 적이 있지만, 16비트 윈도우 바이너리(exe/dll), 소위 NE 파일의 형태는 보면 볼수록 참 이상야릇하다고 느껴져서 흥미가 갑니다.

MZ로 시작하는 도스 EXE는 구조가 사실 매우 간단합니다. 맨 처음 32바이트 남짓한 구조체에다 몇몇 오프셋, 사이즈, 레지스터 초기값 따위를 넣고 재배치 정보(optional)만 넣어 주고 나면 그 뒤부터는 공통분모라는 게 없이 전적으로 프로그래머/컴파일러 재량입니다. COM은 아예 헤더란 것이 없고 곧장 코드+데이터가 등장하는 형태이니 초간단 패치 내지 램 상주 유틸리티, 혹은 심지어 바이러스를 만들 때 이보다 더 좋은 수단이 없었습니다.

하지만 좀더 복잡한 운영체제는 바이너리 파일에도 더 정교한 체계대로 구간별 역할을 딱딱 나누고 있습니다.
가령, EXE 뒤에다가 별도의 내장 데이터를 덧붙이는 것은 도스 시절에는 전적으로 컴파일러/링커 내지 해당 기능을 수동으로 제공하는 라이브러리의 재량이었습니다. 가령 볼랜드 컴파일러로 *.bgi 드라이버나 글꼴을 *.obj로 바꿔서 embed시키는 것은 운영체제보다 훨씬 더 상위 계층에서 행해지는 일이었죠.
하지만 윈도우에서는 운영체제 차원에서 바이너리 파일 안에 리소스라는 데이터 영역을 별도로 구분하여 관리해 주며, 이를 불러오는 API도 운영체제 차원에서 제공됩니다.

16비트 중에서도 윈도우 1.x(무려 1985년에 나온 바로 그것!), 2.x, 3.x의 포맷이 모두 서로 살짝 다르다고 하는데, 2.x 이상 바이너리는 오늘날 윈도우 운영체제의 NTVDM 하에서도 바로 실행 가능하다고 들었습니다. (9x 계열에서는 말할 나위도 없음.) 하지만 1.x도 리소스 데이터를 좀 변환하고 버전 플래그 같은 몇몇 값만 수정하면 곧장 실행할 수 있다고 하더군요. 윈도우가 하위 호환성을 상당히 잘 지키면서 버전업되어 왔다는 얘기가 되겠습니다.

0x3C 오프셋에 도스 바이너리가 아닌 실제 바이너리가 시작되는 위치가 기록되어 있다는 것은 NE(16비트 윈도우 바이너리), PE(오늘날의 32/64비트 바이너리) 모두 공통입니다. NE에도 PE와 마찬가지로 최소 운영체제 버전과 자신을 빌드한 링커의 버전이 헤더에 명시되어 있습니다.

윈도우 3.x 바이너리들은 대개 링커 버전이 5~6 정도로 잡혀 있던데 이건 비주얼 C++ 버전이 아니라 그 전신인 MS C 버전 기준이라고 보는 게 타당하겠습니다. 비주얼 C++ 1.5x는 MSC_VER의 값이 600밖에 안 되거든요. 그 반면 요즘 비주얼 C++ 200x는 이미 무려 1300~1500대까지 올라갔죠.

최소 운영체제 버전은 물론 3.10으로 잡으면 윈도우 3.1에서 실행 가능합니다. 하지만 이 수치를 더 높게 4.0으로 잡으면 “윈도우 3.1에서 실행되지 않는 16비트 윈도우 바이너리”를 만들 수 있습니다.

그런 예가 무엇이 있냐 하면 바로 윈도우 9x 이후에 제공되는 SysEdit.exe입니다. 이 프로그램은 16비트 EXE이지만 정작 윈도우 3.1에서는 실행이 안 됩니다. 하지만 윈도우 9x에서 실행하면 비록 16비트 EXE이지만 대화상자의 배경을 다른 32비트 프로그램들처럼 회색 입체 효과로 입혀 주며 16비트 프로그램과 호환되지 않는 일부 신규 메시지/API를 32비트 프로그램과 같은 스타일로 날려 줍니다. Win32s도 아니고 참 난감한 케이스이죠? 윈도우 9x가 나오던 당시, MS에서 내부적으로 기존 16비트 프로그램들의 외형 껍데기의 이질감을 줄이려고 넣은 꽁수에 가깝다고 보면 되겠습니다.

요즘은 파일 포맷을 설계할 때 최대한 확장성을 고려하여 chunk 테이블부터 넣는 게 일반적입니다. MIDI(음악), TTF(글꼴), PNG(그래픽)들이 다 그렇죠. PE도 마찬가지여서 text, data, reloc, rsrc 같은 청크 식별자가 존재합니다. 하지만 NE는 나중에 등장한 PE와는 달리 그런 구분은 존재하지 않으며 헤더, 세그먼트 테이블, 리소스 테이블, 이름 테이블 등 미리 정해진 정보가 순차적으로 쭉~ 등장하는 형태입니다.

kernel, user, gdi처럼 내가 참조하여 import하는 다른 모듈의 API에 대한 정보는 있지만 PE처럼 함수명이 그대로 기록되어 있지는 않고 그냥 서열 번호만 들어가는 것 같습니다. 또한 윈도우 1.x가 맨 처음에 파스칼로 개발되어서 그 영향을 받아서인지, export하는 심볼 이름들은 다 대문자로만 적혀 있고 대소문자 구분은 딱히 안 하는 걸로 보입니다. 물론 윈도우 내부 API가 SDK 형태로 최초로 정식 공개된 3.0 시절에는 이미 다 C언어 기반으로 바뀌었지만.

끝으로, NE에는 PE에 전혀 없는 개념인 name table이라는 게 있습니다. 프로젝트 빌드할 때 *.DEF 파일로부터 링커가 생성해 주는 테이블일 겁니다.
그것도 resident name, non-resident name이라 하여 언제나 메모리에 상주하는 것, 아니면 언제나 상주시키지 않기는 때문에(메모리 아끼기 위해) 불러오는 데 시간이 좀 걸릴 수도 있는 것으로 종류도 나뉘어 있습니다. 둘 다 자신이 export하는 함수들의 명칭 같은데 정확한 용도가 무엇인지, 그리고 또 왜 이런 식으로 분류를 했는지는 알 길이 없습니다. 인터넷으로도 이런 게 있다는 식으로 기계적으로 설명해 놓은 자료만 있지, NE 포맷을 왜 이런 식으로 만들 수밖에 없었는지 같은 친절한 설명은 정말 찾을 수 없더군요.

또한 이 테이블에는 꼭 export symbol만 들어가는 게 아니라, non-resident name의 1순위로는 이 프로그램의 full name도 같이 들어갑니다. 즉, 버전 리소스를 굳이 안 뒤져도 여기를 찾아봐도 “Microsoft Visual C++”, “FontMania” 같은 정보를 얻을 수 있다는 것이죠. 오늘날 쓰이는 PE에는 이런 정보가 없습니다.

윈도우 3.1의 기본 프로그램인 문서 작성기, 페인트 등의 EXE를 들여다보면 마치 DLL처럼 프로그램의 내부 함수로 추정되는 명칭(특히 윈도우/대화상자 프로시저)을 상당수 non-resident name table에다가 export해 놓은 것을 알 수 있습니다. PageInfoWndProc, DialogGoto, BroadcastChildEnum 등. 왜 이렇게 해 놓은지는 저는 16비트 윈도우 개발 경험이 없으니 알 길이 없습니다. 메모리가 캐 부족하던 시절에 아마 한 번 만들어 놓은 코드는 EXE, DLL을 불문하고 최대한 많이 재사용하려고 이렇게 한 게 아닌가 싶습니다.

그나마 resident name table은 거의 쓰지도 않는 거 같던데 왜 만들었는지도 모르겠고.. 수수께끼이군요. 참고로 32비트 시대로 와서는 리소스 같은 건 free 한다는 개념 자체가 없어졌습니다. 당연히 resident, non-resident 같은 구분도 전혀 필요 없죠.

대략 이렇게 NE 포맷에 대해서 살펴봤는데, PE까지 그대로 이어지고 있는 개념도 있는 반면 어떤 것은 완전히 다른 것도 존재한다는 걸 알 수 있었습니다. 역시 16비트와 32비트 사이에는 넘사벽 같은 gap이 있는 듯이 보입니다.

Posted by 사무엘

2010/01/11 00:18 2010/01/11 00:18
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/48

훅킹 프로그래밍

윈도우 훅킹은 운영체제의 내부 메커니즘(주로 메시지)을 가로채어 시스템 전체의 동작 방식을 바꾸는 매우 강력한 기법입니다.

이런 훅은 우리 프로세스 안의 특정 스레드 안에다가만 설치할 수도 있고 시스템의 모든 스레드에다가 설치할 수도 있는데, 32비트 운영체제로 오면서 후자 같은 global 훅(혹은 시스템 훅)을 설치하기 위해서는 훅 프로시저는 반드시 DLL에 따로 존재해야 하는 약간의 번거로움이 생겼습니다.

global 훅은 동작 방식의 특성상 모든 프로세스들에 나의 코드를 주입하는 가장 간편한 방법입니다. 굳이 윈도우 메시지 훅킹이 아니더라도 다른 종류의 훅킹을 위해서라도 윈도우 훅이 사용됩니다. 한컴사전의 노클릭 단어 인식이라든가 과거의 한스타, 그리고 Dependency Walker의 EXE 프로파일 기능처럼 API 훅킹이 동원되는 프로그램도 살펴보시면 별도의 DLL 파일이 존재하는 것을 알 수 있는데, 이는 API 호출을 변조하는 코드 자체를 삽입하기 위해서 윈도우 훅을 사용한 것입니다.

Global 훅은 완전히 특이한 프로그래밍 패러다임을 제공합니다. 다른 프로세스에서 완전 제각기 따로 실행되는 함수를 만들 수 있습니다.
가령, A라는 프로세스에서 B라는 DLL에 들어있는 훅 프로시저로 global 훅을 설치했습니다. 그러면 A와 B 사이의 통신 방법이 문제가 됩니다. 통상 A는 B의 동작 방식을 결정하는 입력 데이터를 주고, B는 훅킹을 통해 얻은 결과를 A에다 전달해야 할 것입니다.

이를 위해 보통 메시지를 쓰면 무난하죠. B에서 A로 통신할 때야 우리끼리만 쓰는 WM_USER+n이라든가, 심지어 WM_COPYDATA를 바로 보내도 무난하지만, 다른 프로세스 안에 존재하기 때문에 메시지가 겹칠 우려가 있는 B를 “향해서” 메시지를 보낼 때는 RegisterWindowMessage로 값이 안 겹치는 게 보장되는 별도의 메시지를 등록해서 쓰는 게 안전합니다.

또한 프로세스 A가 자신의 주소 공간에 로드되어 있는 DLL B의 변수값을 바꾼다고 해서 다른 프로세스들의 주소 공간에 로딩되어 있는 DLL B의 인스턴스의 변수값이 바뀌지는 않는다는 것도 조심해야 합니다. global 훅 프로시저는 메시지를 받는 그 프로세스의 주소 공간을 기준으로 호출된다는 것!
이걸 헷갈려서는 안 됩니다. 변수 초기화 같은 걸 잘못하면 훅을 설치한 프로세스 A 안의 B만 제대로 동작하게 되고, 다른 프로세스에 침투한 B는 그렇지 못하게 됩니다.

이것 때문에 과거에 굉장히 주의가 필요했던 점이 뭐냐 하면 훅 핸들 값을 공유하는 것이었습니다.
훅 프로시저는 자신에게 걸린 메시지를 처리한 뒤, CallNextHookEx 함수로 그 메시지를 다음 훅에다가 전달도 해 줘야 했습니다. 운영체제에 갈고리질을 하는 놈이 나만 있는 것 아니기 때문에... 그런데 윈도우 9x는 유독 이때 자신이 받은 훅 핸들값도 알아서 전달해 줘야 했습니다.

프로세스 A가 자신의 주소 공간에 있는 B DLL에다가 훅 핸들을 넘겨준다고 해도, 다른 주소 공간에 복제된 다른 B DLL의 인스턴스는 그 값을 알 수 없었습니다.
그래서 이 값은 숫제 메모리 맵드 파일 같은 공유 메모리를 만들어서 넘겨주거나, #pragma data_seg 같은 전처리기로 별도의 공유 섹션을 만들어서 그 전역변수에다 핸들을 공유해야 했지요.

그런데 윈도우 2000 이상, 아니 NT 계열은 그럴 필요가 없습니다. CallNextHookEx 함수를 호출하는 것 자체만으로 이 문맥에서의 훅 핸들은 알아서 감지가 됩니다. 당연히 그렇게 되는 게 이치에 맞죠. 그럼, 윈도우 95보다 NT가 3.1 시절부터 먼저였는데 왜 애시당초 아무 쓸모없던 HHOOK 인자를 받는 게 있었을까? 그건 아마 16비트 시절의 훅킹 API의 프로토타입을 그대로 베끼다 보니 그렇게 된 게 아니었나 싶군요. 32비트 윈도우로 와서 WinMain의 hPrevInstance 인자가 완전 무의미해졌지만 여전히 그대로 남아있는 것처럼.

그럼에도 불구하고 훅킹 API에 관한 한 윈도우 9x는 NT를 100% 닮지 못하고, 그렇다고 해서 아예 3.1 시절처럼 단일 주소 공간도 아니면서(핸들 값 공유도 어려운 환경에서) 꽤 불편한 프로그래밍 관행을 개발자에게 강요하게 되었던 것 같습니다.

윈도우 9x 시절에만 해도 global 훅 프로그래밍은 굉장히 조심스럽게 해야 했습니다. 훅 프로시저에서 뭔가 뻑이 났다간 그건 90% 이상 운영체제 다운으로 연결됐습니다. 디버깅은 더욱 힘들었음. 보호 모드 운영체제란 말이 무색할 정도였어요. 그만큼 운영체제가 안전보다는 열악한 PC 환경에서 효율 내지 도스와의 호환성 위주였으며, 불안정하고 응용 프로그램의 위험한 동작에 대해 취약했습니다.

하지만 XP 정도 되니, 특히 비스타는 이 정도로 안정성이 강화될 줄은 몰랐습니다. 훅 프로시저에 굉장히 어이없는 실수가 들어있었는데 그냥 그 훅만 싹 없어지고 프로그램은 잘 돌아가더군요. 깜짝 놀랐음. 윈도우 9x였으면 당장 blue dead screen이었을 겁니다.
윈도우 2000 때만 해도 IME/TSF 모듈이 해당 응용 프로그램을 뻗게 만들 수 있었는데, XP 이후부터는 안 그렇더군요. 자체적으로 예외 핸들링을 합니다.

global 훅 프로그래밍을 할 때 괴로운 점.
훅을 거둬들이고 모든 프로그램을 종료한 뒤에도 훅 프로시저가 들어있는 DLL의 lock이 즉시 풀리지 않는 경우가 많다는 것입니다. 훅을 해제한 뒤에도 이 DLL이 여전히 몇몇 프로세스의 주소 공간에서 사라지지 않고 상주해 있기 때문입니다. 그런데 3~5분 정도 기다리고 나면 없어져 있어요. 그러니 DLL을 이것저것 고치면서 자주 리빌드를 하기가 힘듭니다. -_-;;

비슷한 예로 글꼴도 있답니다. 프로젝트 파일로부터 최종 TTF 파일을 만들어서 여타 프로그램에서 테스트를 했습니다. 그런데 한번 그러고 나면, 그 프로그램을 종료한 후에도 내가 새로 설치한 TTF 파일이 여전히 in use 상태여서 지워지거나 교체가 안 되는 겁니다. 그러니 글꼴을 빈번히 수정하고 테스트하기가 힘들죠.

이럴 때 VMware가 해결책이 될 수 있습니다. 가상 머신을 만들어서 훅 프로그램을 실행하거나 글꼴을 설치하기 직전 순간의 스냅샷을 만든 후, 테스트를 하고 나서 스냅샷 시점으로 revert 하기. -_-;; 그게 저절로 파일 lock이 풀리길 기다리거나 재부팅을 하는 것보다 더 빠르더군요. ㄱㅅ!

뭐, global 훅 얘기로 길어졌습니다만, 내 응용 프로그램 안에서의 작은 규모의 훅도 충분히 쓰일 일이 있으며 특히 MFC에서는 내부적으로 이런 훅을 사용합니다. 일반적인 방법으로 잡기 힘든 메시지들도 MFC의 단일 프레임워크 하에서 일관성 있게 처리시키기 위한 목적이기도 하고요,
또 모든 대화상자들을 부모 윈도우 기준으로 중앙에다 재배치시키기 위해서도 훅을 사용해 대화상자가 생성되는 시점을 가로챕니다.

그냥 DialogBox 같은 함수만 호출해 보면 잘 알다시피 대화상자가 중앙에 뜨지 않습니다. MFC는 modal 대화상자만 중앙으로 옮겨 주기 때문에, 그냥 Create 함수로 modeless 대화상자를 만들어 보면 당장 그 위치 차이를 감지할 수 있습니다.

Posted by 사무엘

2010/01/10 23:29 2010/01/10 23:29
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/37

지금은 오나전 아련한 추억이 됐죠. ㄱ-

1. 포트 충돌이 일어나면 모뎀과 마우스를 동시에 못 쓰던 것. ㄲㄲㄲㄲㄲㄲㄲㄲ
(시스템 종료 후 컴이 자동으로 꺼지기 시작,
마우스 휠과 USB 포트, 키보드와 마우스 단자가 PS 포트로 변경...
한 97~99년을 전후해서 다 그렇게 바뀐 것 같더군요.)

2. 도스를 완전히 못 벗어난 윈도우 9x 특유의 블루 데드 스크린과
64KB 리소스 제약..
이건 지구상의 어떤 운영체제에도 없던 이상한 제약이 아니었나 싶습니다.
16비트에서는 도스, 아니면 풀 32비트에서 유닉스, OS/2급의 빵빵한 운영체제 이런 구도였지, 둘을 저렇게 짬뽕한 OS는 윈도우 9x 부류가 유일했으니까요. MS가 고객 수요에 맞춰 장사를 정말 잘 한 것입니다.

3. 물론 이건 운영체제라기보단 드라이버 탓이 더 크겠지만
윈도우 98 시절까지만 해도 멀티웨이브 안 되던 컴도 많았어요. -_-;;
사운드 카드가 동시에 한 프로그램밖에 쓸 수 없는 자원이었던 캐암울한 시절도 있었습니다. ㄱ-

윈도우 2000/ME로 넘어오면서부터

- 소프트웨어 시뮬만으로 미디 신시사이저 지원
- 멀티웨이브 본격 지원
- 메모리 스틱, 외장하드 등 어지간한 USB 기억장치를 자동 인식. "이 장치를 안전하게 제거" 메뉴 자체가 생김 (98 SE는 아직 그런 거 없음.)

꽤 많은 변화가 생겼던 것 같습니다. 과거의 제약이 차츰 사라졌죠.
윈도우 ME는 비록 악명은 높지만 최신 하드웨어 인식 잘 하는 건 98보다 뛰어나다는 걸 확실히 인정함.

그리고 마우스 포인터.
제 기억이 맞다면, 아마 윈도우 2000은 VGA 640*480 16 컬러에서 돌아갈 때도 마우스 포인터가 그래픽이 바뀌는 곳에서 깜빡거리지 않을 거에요. 그거 보고 무척 놀랐던 기억이 납니다.
XP부터는 이제 안전 모드에서도 VGA 16컬러는 볼 일이 없어졌고... ㄱ-

하드웨어 지원을 받아서 마우스 포인터가 깜빡거리는 게 없어진 것이 한 90년대 중반부터인데, 이때도 지원이 완전하지는 못해서 흑백 monochrome 기본 커서가 아닌 커스텀 포인터는 여전히 깜빡거리기도 했었습니다.

CD롬 부팅 후 곧바로 운영체제 설치가 가능해진 것도 2000부터이죠?
NT에 그런 기능 있었을 리는 없고,
9x 계열에도 그런 거 없습니다. 그래서 vmware에서 세팅할 때도 먼저 도스 + fdisk 파티션부터 만들어야 합니다.

Posted by 사무엘

2010/01/10 23:21 2010/01/10 23:21
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/34

윈도우 운영체제가 NT 초창기 시절 이래로 지금까지 사용해 오고 있는 실행 파일 포맷은 잘 알다시피 portable executable 형식입니다. 헤더도 이니셜인 PE로 시작합니다. 물론 네이티브 EXE이기 때문에 코드 부분은 기계마다 다르겠지만, 헤더 구조체라든가 리소스 같은 공통된 부분은 최대한 일치시켜서 이식성을 고려해서 설계했다는 뜻이지요.

늘 인텔 CPU에서만 돌아가는 EXE만 보다가 MIPS 같은 RISC CPU에서 돌아가는 PE 실행 파일을 헥사 에디터로 들여다보니 진짜로 기계어 코드가 한눈에 보기에도 일정 바이트 간격으로 아주 균일하게 나열돼 있더군요. 그걸 보고 놀랐던 기억이 납니다.

64비트 PE도 일부 구조체만 64비트로 확장되었을 뿐 기본적인 골격은 초창기 32비트 PE와 같습니다. 더구나 윈도우 운영체제가 인식하는 리소스(스트링 테이블, 대화상자, 메뉴 등)의 포맷은 매우 다행스럽게도 32비트 PE와 완전히 일치합니다.

EXE와 DLL은 자신만의 프로세스 공간을 만들어서 단독 실행이 가능하냐의 차이가 존재하는데, 기술적으로는 헤더의 비트 몇 군데만 다르지 똑 같은 PE 바이너리입니다. 이런 바이너리를 ‘모듈’이라고 부릅니다.

c, cpp 같은 소스 코드를 컴파일하면 기계어 코드인 obj 파일이 생깁니다. 이런 obj 파일과 lib를 링크하면 그런 모듈 파일이 결과물로 생성됩니다. lib는 또다른 obj의 묶음일 뿐 obj와 완전히 다른 파일이 아닙니다. 또한 모듈 역시 그런 obj, lib에 들어있는 코드를 PE 규격에 맞게 재배치하고 묶은 파일일 뿐이지 원시 파일과 그렇게 큰 차이가 없습니다.

윈도우 운영체제에서 개발 환경을 만든 사람들의 생각은, 링커가 특별히 할 일이 없게 하는 것이었던 것 같습니다. 물론 요즘은 전역 최적화처럼 링크 타임에도 코드를 생성하는 기술도 도입되어 사정이 그렇게 간단하지만은 않게 됐지요.

PE는 text(실행되는 기계어 코드), rdata(스트링 리터럴처럼 읽기전용 상수나 초기화 값), rsrc(윈도우 리소스 데이터), DLL 심볼 import/export 테이블, reloc(재배치 정보) 등 여러 섹션으로 나뉩니다. 특히 재배치 정보는 Win32s 시절에는 exe에도 필요했지만 지금은 dll에만 넣어 주면 됩니다.

PE의 헤더에는 자신의 기본 어드레스, 자신이 돌아가는 데 필요한 최소한의 운영체제 버전 같은 여러 정보가 들어가고 심지어 자신을 빌드한 링커의 버전을 기입하는 공간도 있습니다. 가령 비주얼 C++로 빌드하면 6.0, 7.1 (닷넷 2003), 8.0 (2005) 같은 번호를 쉽게 식별할 수 있지요.

원래 MS 자체에서 만든 프로그램 바이너리들의 링커 버전은 비주얼 C++의 버전과 거의 일치하지 않았습니다.
가령 윈도우 95는 까마득한 2.5, 그리고 98/ME는 3.1, 윈도우 2000은 5.12, 오피스 XP는 6.2였습니다. 비주얼 C++과는 별도로 자신들만 쓰는 컴파일러/링커가 있었던 것 같습니다.

하지만 이것이 언제부턴가, 한 02~03년부터 버전이 일치하기 시작했습니다. MS에서도 내부적으로 비주얼 스튜디오를 쓰기라도 했는지?
윈도우 XP는 7.0으로 당대의 최신 비주얼 C++이던 닷넷 2002와 일치합니다.
그리고 XP sp2 (sp1은 모르겠음)와 오피스 2003은 비주얼 C++ 닷넷 2003의 버전과 같은 7.1입니다.

그 후 윈도우 비스타와 오피스 2007의 모든 바이너리들은 비주얼 C++ 2005의 버전인 8.0으로 물갈이되어 있습니다. 하지만 CRT 라이브러리는 살짝 다릅니다. 오피스는 msvcr80을 쓰지만 운영체제는 자신만의 msvcrt를 고수하고 있습니다. 하지만 이제는 msvcrt에도 비주얼 C++ 2005에서 새로 추가된 strcpy_s 같은 보안 강화 함수들이 추가되어 있습니다.

msvcrt는 이제 운영체제가 혼자 마음대로 바꿔 쓰는 CRT DLL로 격리시키고 응용 프로그램들은 이제 msvcr??을 알아서 배포해서 쓰든가, 싫으면 스테틱 링크하라는 구도가 된 셈입니다.

Posted by 사무엘

2010/01/10 23:17 2010/01/10 23:17
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/31

« Previous : 1 : ... 17 : 18 : 19 : 20 : 21 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2026/10   »
일 월 화 수 목 금 토
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Site Stats

Total hits:
4198108
Today:
1750
Yesterday:
2133