오늘 팀 동료를 통해 bash 취약점이 있다는 내용을 들었고, cnet.com 링크를 통해 확인할 수 있다.

bash 보안 취약성 패치하기

제가 배치한 버전은 bash 4.3.25 (이 버전의 패치 코드 25개) 이며, 이 버그는 원격 코드 실행 버그로 매우 위협적인 버그이다.

맥에서는 당시(2014–09–26) MacPort, Homebrew 에서 패치 버전을 제공하지 않는 관계로, 직접 소스 코드를 컴파일 하는 방법으로 해결하였다.

최신 bash 버전으로 패치하고 컴파일 하는 스크립트 코드를 필자의 github 에 커밋하였다.
- https://github.com/powerumc/Patch-Bash-Vulnerability

맥/리눅스 에서 아래의 명령을 실행하면 바로 패치 하도록 했다.

curl https://raw.githubusercontent.com/powerumc/Patch-Bash-Vulnerability/master/patch-bash-4.3.25.sh | sh

참고 (버그 내용)

bash 원격 코드 실행 취약성

쉘에서 아래의 명령을 실행하여 echo 메시지가 확인되면 원격 실행 코드 버그가 있는 버전입니다.

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

코드 실행 결과 (원격 코드 실행 가능한 취약성)

vulnerable
echo this is a test

패치 후 원격 코드 실행 불가능

패치가 완료되면 원격가 실행되지 않는다.

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

코드 실행 결과

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for \`x'
this is a test


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 이반린 2014.09.29 10:59 Address Modify/Delete Reply

    안녕하세요. 서버관리자 입니다. 제가 관리하는 서버가 BASH 취약점이 있는데요.
    외부적으로 포트를 열수가 없어서 수동으로 bash 쉘을 패치해야 하는데
    어떻게 해야 하는지 알려주시면 감사하겠습니다.
    부탁드립니다.

  2. 123124124 2014.09.29 14:59 Address Modify/Delete Reply

    RedHat, CentOS 일 경우
    rpm -Uvh bash............. 하시면 되요

  3. 최혁선 2014.09.29 15:42 Address Modify/Delete Reply

    안녕하세요. 영문페이지로가서 그대로 설치하였더니.....
    $ env x='() { :;}; echo vulnerable' bash -c "echo this is a test" 명령어를 입력하면 결과에
    sh: error importing function definition for `BASH_FUNC_module()'
    위에 오류가 납니다.. 모듈이 Import되어 있지 않다고 나오는것 같은데. 혹시 이런 증상 해결 방법이 있을까요? 쉘스크립트가 정상적으로 실행이 되는지 테스트 해봐야겠네요..

DeskBoard 앱은 프레젠테이션 등으로 발표를 자주 하는 분들을 위해 필자가 만든 앱입니다. (지난 블로그 글)

이번에 $9.99의 앱 가격을 이달 4월 말까지 $2.99 로 할인합니다.

DeskBoard 앱은 유료/무료 버전 두 가지가 있습니다.
무료 버전도 모든 기능을 지원 하지만 멀티 모니터(두 대 이상 모니터)를 지원하지 않습니다.
그러므로 외부 모니터에 연결하거나 멀티 모니터 지원이 필요한 분만 유료 버전을 구매하시면 됩니다.

자세한 사항은 아래의 AppStore 아이콘을 클릭하면 됩니다.

DeskBoard (유료 $2.99 <- $9.99)
DeskBoard Free (무료)

[동영상] DeskBoard 앱을 사용하는 예

이하 앱에 대한 설명입니다.


여러분의 성공적인 발표나 세미나를 위해 당신에게 더 집중할 수 있도록 DeskBoard 앱을 사용해 보세요.
여러분이 전달하고자 하는 메시지를 다양한 도형을 사용하여 청중들에게 정확하게 전달할 수 있어요.
그럼 청중들은 당신이 무엇을 강조하는지 쉽게 알 수 있답니다.
DeskBoard 앱은 다음과 같은 분들이 사용하는 것을 권장합니다. ^_^

  1. 여러 사람 앞에 발표할 기회가 많은 분
  2. 맥을 프로젝터나 원격으로 공유하여 회의 하시는 분
  3. 강의를 하거나 직업을 가지신 분
  4. 개발자, 프로그래머 중 라이브 코딩을 해야 하는 분


Posted by 땡초 POWERUMC

댓글을 달아 주세요

[GDB] Hopper Disassembler 앱

C++ 2014.02.12 02:21 |

필자는 소프트웨어 개발에 필요한 앱은 라이선스를 구매해서 쓴다. 자랑은 아니지만 앱스토어와 그 외 구매한 앱의 개수가 200개가 넘어간다. 히힣; 오늘 소개하는 앱 처럼 제값어치 하는 앱에겐 뭔가 모를 희열을 느낀다. 여성분들이 쇼핑을 좋아하는 것처럼 -0-

Hopper Disassembler

이 앱은 윈도우의 WinDbg, 그리고 GNU gdb처럼 디버거 명령줄(Command Line)에 익숙하지 않은 디버거에게 유용한 앱이다. 몇 달 전, Objective-C with LLVM 어셈블리 코드를 분석하기 위해 구매했다. Objective-C 내부적인 언어적 매커니즘을 이해하기 위해 역어셈블리 분석은 필수이기 때문이다. 그 중 이 앱은 기대한 것 보다 기능은 적지만, 사소한 곳에서 감동을 주는 앱이라 생각된다.

역어셈블리 앱 중 윈도우에선 OllyDbg 가 있다면, 맥에서는 바로 이 Hopper Disassembler 가 있다. OllyDbg는 작지만 기능에 충실한 서민적인 앱이라면, Hopper Disassembler는 비주얼적인 면이 좀 더 부각된 매니아 앱 같다. 기능적인 면에서 Hopper Disassembler가 조금 떨어지긴 하지만, 맥에서 이 정도면 충분히 쓸만하다고 판단된다.

특히 Hopper Disassembler는 윈도우, 맥 그리고 리눅스까지 지원하는 효자 앱이다. 이 세 가지 운영체제 버전을 모두 구입해도 12만원 정도면 된다. 더 고가의 프로페셔널한 상용 버전에 비하면 저렴한 편에 속한다. 필자처럼 맥, 리눅스, 윈도우, 이렇게 여러 운영체제를 사용한다면 Hopper Disassembler는 충분히 매력적이다.

앱 훑어보기

Hopper Disassembler 런타임(runtime) 디버깅을 하려면 전용 디버거 서버 앱을 사용해야 한다. 그러니까 클라이언트-서버 구성으로 Remote(or Pipe) 통신으로 디버깅을 진행하는데 이 인터페이스가 썩 좋지만은 않다.

클라이언트/서버로 구성

아래의 스크린샷 처럼 메인 윈도우, 서버 에이전트, 어셈블리 레지스터 윈도우 이렇게 세 개를 띄어야 한다. 멀티 모니터에서는 장점이 될 수도 있고, 싱글 모니터에서는 단점이 될 수 있다.



비주얼 및 기타

디버거 앱 답지 않게 좀 더 다양한 색상을 사용하였지만, 거부감 없이 알아보기 더 쉽다. Flow Graph와 Pseudo Code도 비교적 깔끔하다. 초기에 사용할 일이 잦지만 Objective-C의 기계어(?) 코드 스타일에 익숙해 지다보면 거의 사용하지 않는 번들 기능 중 하나다. Objective-C with LLVM 구성인 경우 .NET과 Java와 같이 가상머신(virtual machine)에서 동작하지만, 이보다 좀 더 하위 레벨인 LLVM 컴파일 바이너리는 거의 일관적으로 유사성이 있기 때문이다.

검색 기능과 참조된 주소를 분석하는 기능은 기대 이상으로 빠르고 정확하다. 특히 call, je, jne, jmp 그리고 meta data, symbols, 마지막으로 xref 등을 쉽게 찾아가거나 검색할 수 있다. xref의 참조 주소의 원본을 툴팁으로 보여주는 등 예상하지 못한 곳에 꼼꼼한 비주얼을 보여준다.

눈안의 가시, 버그

일부 코드를 디버깅 하다보면 특정 인스트럭션(instructions)에서 Step Over를 Step Into로 동작하는 경우가 발생한다. 이게 은근히 신경을 곤두세우는데 아직까지 별다른 패치나 업데이트가 없고, 앞으로도 없을 것 같다. 필자는 이 버그와 앱의 가격과 협상했지만, 보다 세세한 디버깅을 제어해야 한다면 다른 앱(gdb? -_-)을 사용하는 것이 좋을 것 같다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

OSX 매버릭스(maverics)에서 마운틴 라이언(mountain lion)으로 다운그레이드 해야 할 필요가 생겼다. 매버릭스 환경에서 OSX 1.8 SDK 버전으로 맥 앱을 개발하면 OSX 1.9(매버릭스)에서 잘 실행되지만, OSX 1.8(마운틴 라이언)에서 맥 앱이 crash가 발생하는 경우가 있다.

crashing이 발생하는 경우의 대부분이 OSX SDK의 일부 obsulete 함수가 있는데, 이 함수를 사용하는 경우다. 이런 crashing 상태를 확인하기 위해 OSX 마운틴 라이언이 설치된 운영체제가 필요하다.

1. OSX 마운틴 라이언 다운로드

OSX 마운틴 라이언은 맥 앱스토어에서 유료로 판매된다. 이것을 다운로드 받고 응용 프로그램 폴더를 확인하면 찾을 수 있다.



2. 응용 프로그램 폴더에 다운로드 된 OSX 앱 확인

3. hdiutil 명령어로 dmg를 iso로 변환

다음의 경로로 이동한다.

$ cd /Applications/Install OS X Mountain Lion.app/Contents/SharedSupport

파일 목록을 확인하면 InstallESD.dmg 파일을 확인한다.


$ ls -al
 total 8690344
 drwxr-xr-x 4 root wheel 136 12 23 23:37 .
 drwxr-xr-x 11 root wheel 374 12 23 23:37 ..
 -rw-r--r-- 1 root wheel 4448808132 12 23 23:37 InstallESD.dmg
 -rw-r--r-- 1 root wheel 646916 9 30 15:44 OSInstall.mpkg

hdiutil 명령어로 dmg to iso 파일로 변환한다.[1] 변환된 .cdr 확장자는 .iso로 변경하면 된다.

$ hdiutil convert ./InstallESD.dmg -format UDTO -o ~/Downloads/InstallESD.iso
Driver Descriptor Map(DDM : 0) 읽는 중...
(Apple_Free : 1) 읽는 중...
Apple(Apple_partition_map : 2) 읽는 중...
disk image(Apple_HFS : 3) 읽는 중...
........................................................................................
경과 시간:  1m 40.307s
속도: 46.2M바이트/초
저장: 0.0%
created: /Users/powerumc/Downloads/InstallESD.iso.cdr

설치 디스크로 굽기

USB 설치로 구워도 되고, 필자의 경우는 Parallels에 가상 환경에 OSX 마운틴 라이언을 설치했다.

굽는 방법은 다음의 링크를 참고한다.
How to "burn" an ISO to USB flash drive? - http://forums.macrumors.com/showthread.php?t=598291


Posted by 땡초 POWERUMC

댓글을 달아 주세요

매버릭스 업데이트 후 개발 중인 맥 앱에서 발생하는 문제

OSX 매버릭스로 업데이트한 후 XCode로 개발 중인 유틸리티 프로그램의 일부 기능이 작동하지 않는 현상이 발생한다. 원래 Alpha 버전으로 곧 배포할 예정이었는데, 이 문제로 배포가 늦어질 것 같다.

문제는 Objective-C와 Cocoa를 사용하여 전역 마우스 및 키보드 후킹(hook global mouse and keyboard event)을 사용하는 코드가 있는데, 그 중 키보드 이벤트만 캡춰링(capturing)할 수 없는 현상이 발생한다.

해결 방법

의외로 해결 방법은 간단하다. 먼저 OSX 매버릭스에서 변경된 보안 사항에 대해서 알 필요가 있다. 기술적인 내용은 아니므로 쉬엄쉬엄 다음의 글을 참고하기 바란다.

OS X 10.9 매버릭스(Mavericks)의 바뀐 메뉴 구조 때문에 정상 작동하지 않는 앱 실행하기 (보조 장비에 대한 접근 활성화)

즉, 기본적으로 매버릭스를 설치하면 ‘손쉬운 사용’에 의해 응용 프로그램이 맥이나 기타 장비를 제어하는 것이 차단된다. 필자는 매버릭스로 업데이트 이전에 ‘손쉬운 사용’을 활성화하여 장비에 접근할 수 있도록 설정되어 있었다. 하지만, 업데이트 후에 ‘손쉬운 사용’의 활성화 방법이 변경되면서 이 설정이 초기화 된 것으로 볼 수 있다.

해결 방법은 ‘시스템 환경 설정 -> 보안 및 개인정보’로 들어간 후, ‘손쉬운 사용’ 항목에서 Xcode를 체크해 주면 된다. 그럼 특정 응용 프로그램에서 사용하는 APIs 가 블럭 당하지 않는다.

[그림1] 손쉬운 사용의 Xcode 항목을 체크하면 APIs 가 블럭 당하지 않는다

Posted by 땡초 POWERUMC

댓글을 달아 주세요

반 객체지향(Half-of-OOP)

가장 먼저 명심하자. 오브젝티브-C는 C언어의 슈퍼셋(Super Set)이고 C++의 객체 지향과는 거리가 멀다. 오브젝티브-C 언어는 마치 객체지향 프로그래밍(OOP, Object-Oriented Programming) 처럼 보이지만 객체지향 언어가 아니다. 그렇다고 완전히 함수형 언어도 아니다.

하지만, 오브젝티브-C는 객체지향의 가장 대표적인 특징인 상속(Inheritence)이 가능하고 인터페이스 구현이 가능하다. ANSI-C 입장에서 바라보면 상속과 인터페이스 구현은 함수형 언어로서 가당치도 않은 언어적 특성임에 틀림 없을 것이다. (이 문장의 인터페이스는 오브젝티브-C의 @protocol을 의미함.)

물론, C 언어에서도 구조체(struct), 포인터(pointer) 등을 조합하여 객체처럼 다룰 수 있지만, 오브젝티브-C 처럼 상속과 인터페이스의 구현은 객체지향 언어가 아님에도 불구하고 완전히 객체지향 프로그래밍 처럼 개발하는데 모자람이 없을 지경이다.

정리해 보면 오브젝티브-C의 객체지향 특징은 다음과 같다.

1. 상속성(Inheritance)

상속성은 부모의 특징을 물려 받음과 동시에 재정의(override), 부모 호출(super 또는 base)를 지원한다. 더 자세히 말할 필요는 없을 것 같아서 걍~ 넘어간다.

// 오브젝티브-C 의 상속
@interface MFAppController : NSObject
{
   // .. 생략 ..
}

2. @protocol - 인터페이스 구현

오브젝티브-C의 프로토콜(protocol)은 C#과 Java의 interface와 같지만, 한 가지 다른 점은 인터페이스에 정의된 메서드 구현이 필수가 아니라는 점이다. 프로토콜의 모든 메서드를 굳이 구현하기 싫으면 하지 않아도 오브젝티브-C는 너그럽게 용서해 준다.

어떻게 이런 것이 가능할까? 지난 아티클 ‘[Objective-C] 아름다운을 추구하는 오브젝티브-C 언어 1/N’ 에서 다룬 것 처럼 메시지를 기반으로 메서드 호출을 위임하는 언어적인 특성 때문에 가능하다. 모든 프로토콜의 메서드를 정의하든 말든 컴파일러는 컴파일 할 뿐이고, 런타임에서 메시지를 통해 메서드를 호출해서 메서드가 구현되지 않았으면 예외를 발생하던가 아니면 씹던가 하게 된다. (단, @optional과 @required 참고)

// 오브젝티브-C 프로토콜 및 다중 상속
@protocol Animal

   -  (void)say;

@end

@protocol Duck <Animal, NSObject>

    - (void)swim;

@end

3. @category - 확장 메서드

카테고리(@category)는 C#에서의 확장 메서드(Extension Methods)와 똑같다. 확장 메서드는 2008년 C# 3.0에 언어적인 특징으로 포함되었다. 이와 더불어 람다 표현식(Lambda Expression), 이 두 가지는 C# 코드로 표현한 라인 수를 급격히 줄일 수 있었고, 더 섬세한 객체지향 프로그램에 집중할 수 있게 해준다.

@interface NSArray (ConvertableArray)
- (NSDictionary*)ConvertToDictionary;
@end

@implementation NSArray (ConvertableArray)
- (NSDictionary*)ConvertToDictionary
{
   // .. 실제 구현 생략 ..
   return nil;
}
@end

int main(int argc, const char * argv[])
{
   @autoreleasepool {

       NSArray* arr = [NSArray arrayWithObjects:@"A", @"B", nil];
       NSDictionary* dic = [arr ConvertToDictionary];

       // TODO
   }
   return 0;
}

같은 코드로 C# 으로 변환하면 다음 코드와 같다.

public static class ConvertableArray
{
    public static IDictionary ConvertToDictionary(this IList list)
    {
        // .. 구현 생략 ..
        return null;
    }
}

class MainClass
{
    public static void Main (string[] args)
    {
        var arr = new List<String> { "A", "B" };
        var dic = arr.ConvertToDictionary ();
    }
}

하지만, 내부적으로 처리되는 매커니즘은 완전히 틀리다. 무엇이 그렇게도 완전히 틀릴까?

  • C# 확장 메서드는 정적 클래스의 정적 메서드로만 표현할 수 있다.
  • 오브젝티브-C 카테고리는 인스턴스 메서드이다.

그러므로 오브젝티브-C의 카테고리(@category)는 C#의 확장 메서드와 달리 인스턴스화 된 카테고리 메서드가 호출될 때 마다 참조 카운터가 증가한다. NSArray 객체가 인스턴스화 되었기 때문에 카테고리 메서드를 호출할 수 있다는 이야기가 된다.

카테고리의 메서드는 디버거를 통해 다음과 같이 역어셈블리 된다. 역어셈블리 코드를 좀 더 보기 편하기 위해 로컬 변수를 선언하여 살펴 보았다.

먼저 48만큼 메모리 사이즈를 확보한 다음 넘어온 값과 로컬 변수를 초기화하거나 값을 대입한다. rbp-8( =rdi)self 가 들어간 것이고, rbp-16 (=rsi)는 메서드 정보가 들어간다. rbp-20 (=$10)은 INT32 정수 값이 할당된다. 마지막으로 +48로 원래 스택 포인터로 돌아와 빈 값을 리턴하게 된다. 스택이 8씩 자라는 것은 필자가 소스코드를 64비트 대상으로 컴파일 했기 때문이다.

0x100000d40:  pushq  %rbp
0x100000d41:  movq   %rsp, %rbp
0x100000d44:  subq   $48, %rsp
0x100000d48:  movq   %rdi, -8(%rbp)
0x100000d4c:  movq   %rsi, -16(%rbp)
0x100000d50:  movl   $10, -20(%rbp)
0x100000d57:  movq   -8(%rbp), %rsi
0x100000d5b:  movq   %rsi, %rdi
0x100000d5e:  callq  0x100000eac               ; symbol stub for: objc_retain
0x100000d63:  leaq   -32(%rbp), %rdi
0x100000d67:  movabsq$0, %rsi
0x100000d71:  movq   %rax, -32(%rbp)
0x100000d75:  movl   $1, -36(%rbp)
0x100000d7c:  callq  0x100000eb8               ; symbol stub for: objc_storeStrong
0x100000d81:  movabsq$0, %rax
0x100000d8b:  addq   $48, %rsp
0x100000d8f:  popq   %rbp
0x100000d90:  ret    



Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. porcokang 2015.01.09 10:50 Address Modify/Delete Reply

    글을 쓰다 만듯한 포스트 입니다. 하지만 잘 읽었습니다.

아름답고 자연스러운 오브젝티브-C

필자가 오브젝티브-C(Objective-C)를 접한 것은 올해 초, 갑갑한 문법적인 표현(Syntax)을 보니 코드를 보기가 싫어졌었다. 하지만 많은 iOS 개발자가 생겨나고 맥킨토시(Macintosh)를 쓰면서 자연스럽게 맥용 응용 프로그램에 관심이 생기기 시작했다. 처음에는 리눅스와 대부분의 운영체제를 지원하는 Qt(큐티) 프레임워크를 봐오다가, 코코아(Cocoa) 를 알게 되면서 맥킨토시에 가장 아름다운 UI 프레임워크인 것을 느끼게 되었다고 할까.

오브젝티브-C는 매우 깊은 역사가 있다. 이 역사에 대해서는 다음의 위키피디아(Wikipedia) 를 참고하기 바란다. 필자도 이 언어에 대한 깊은 역사를 이렇다 할 만큼 자신 있게 설명해 주기 힘들 것 같다.

.. 생략 .. [1]
오브젝티브-C는 스텝스톤(Stepstone)이라는 회사에서 일하고 있던 브래드 콕스(Brad Cox)와 톰 러브(Tom Love)라는 두 연구원이 만들었다. 역시 1980년대 초의 일이다. 이 두 사람은 1981년 ITT의 프로그래밍 기술 센터(Programming Technology Center)에서 일하던 시절 스몰토크를 처음 접했다. 콕스는 소프트웨어 설계와 프로그래밍에 있어서 재사용성의 문제에 흥미를 느끼게 되었고, 스몰토크같은 프로그래밍 언어가 ITT 시스템 개발자들이 개발을 진행할 강력한 환경을 만드는 데 필요불가결한 요소임을 깨닫게 되었다. 콕스는 C 컴파일러를 고쳐 스몰토크의 기능 일부를 추가하기 시작했고, 곧 그 스스로 OOPC라고 불렀던 C의 객체지향 버전을 내놓게 되었다. 한편 러브는 1982년에 Schlumberger Research에 채용되었고, Smalltalk-80의 최초 상업적 버전을 써 볼 기회를 가지게 되었다. Smalltalk-80은 이후 그들이 낳은 정신적 자식의 성장에 큰 영향을 끼쳤다.
.. 생략 ..

필자가 오브젝티브-C를 접하면서 ‘빙고!’를 외쳤다. 현대적인 언어의 대부분이 C언어, 그리고 바로 이 오브젝티브-C 언어의 영감을 받았다고 해도 무리는 아니다. (단, 현대적인 언어의 정의는 스스로 정의를 내리기 바란다.)

그렇다면 왜 오브젝티브-C 언어가 아름다운지 보자.

아름다움을 만들어 준 메시지 기반 언어

오브젝티브-C의 가장 기초적인 문법을 일반적인 객체 지향 언어의 문법과 비교해 보자.

// 일반적인 객체지향 언어들의 표현
void* obj = data->get_data(); // 또는
void* obj = data.get_data(); // 또는
Object obj = data.get_data();

// 오브젝티브-C 언어
NSObject* obj = [data get_data];

위의 일반적인 객체지향 언어와 오브젝티브-C 언어는 표현하는 방법에 있어 다른 점이 보인다. 자, 무엇이 다른지 한번 살펴보자.

  1. 문법 표현 방법 : 가장 차이가 나는 점은 식의 표현을 대괄호([ ])로 묶여 있다. (메서드 호출 시)
  2. 메서드 호출 방법 : 포인터(->) 또는 참조(.)를 통해 호출하지 않고 공백(a space)으로 메서드를 가리켜 호출한다.

위 코드가 컴파일 된다면 더욱 명확하게 차이점을 볼 수 있다.

일반적인 객체지향 언어의 경우 컴파일 된 어셈블리(기계어) 코드는 메서드가 메모리 상에 상주하고 있는 주소를 통해 직접 메모리를 엑세스하여 메서드를 실행한다.
오브젝티브-C의 경우 바로 이것이 오브젝티브-C 언어의 특징인 메시지를 통해 메서드를 호출하는 방법이다. data 객체는 get_data() 메서드를 직접 호출하지 않고 다른 대리자(위임)를 통해 메서드를 실행한다.

그렇다면 오브젝티브-C는 대리자를 통해 메서드의 실행을 위임함으로서 장점은 뭘까?

  1. NullPoint 예외(오브젝티브-C의 nil 또는 NULL)나 기타 치명적인 오류를 언어적인 레벨에서 차단한다.
  2. 관리언어(Managed Languages)인 자바, C# 등에서 즐겨 쓰는 Code Interception 등의 기법과 유사한 것들을 쉽게 확장할 수 있는 포인트를 제공한다.
  3. LLVM과 같은 가상 머신(Virtual Machine) 매커니즘을 손쉽게 적용할 수 있다. (clang)
딱히 바로 생각나는 것은 몇 안되지만, 더 많은 장점이 있음은 분명하다. 그리고 오브젝티브-C의 메시지 기반으로 작동하는 언어적인 특성을 분석해보자

오브젝티브-C 메시지 기반 메서드 호출

1. objc_msgSend 함수의 메커니즘

오브젝티브-C는 objc_msgSend() 함수를 이용하여 메시지를 보낸다. 이것은 함수만 해당되는 사항은 아니다. 위에서 살펴본 것과 같이 식의 표현을 대괄호([ ... ]) 안에 코드로 표현하는데 이 대괄호 안에 들어가는 모든 객체건 뭐건 간에 메시지를 통해 값을 가져오거나 메서드를 호출하게 된다.

아래 보이는 어셈블리 코드는 필자가 오브젝티브-C로 작성한 맥용 데스크탑 응용 프로그램 중 일부를 어셈블리 레벨에서 디버깅 하는 스크린샷이다. 다음에 사용된 코드의 일부는 다음과 같다.

[self.sidebar setTarget:self];

sidebar는 인스턴스화 된 객체(Object)이다. 오브젝티브-C는 메서드 호출에서만 메시지를 보내는 것이 아니라는 것이다. 그리고 objc_retainAutoreleasedReturnValue() 함수는 매우 긴 이름이지만, 맨 앞 글자의 retain만 주목해서 보면 된다. sidebar 인스턴스는 현재 컨텍스트(Context)에서 참조하므로 참조 카운터(References Count)를 1 증가 시킨다.


2. objc_msgSend 함수 내부에서 전달받은 메시지

아래의 스크린샷은 objc_msgSend() 함수의 내부에서 RIP 레지스터가 가리키는 메모리 주소의 HEX 이다. '73 69 64 65 62 61 72 00'(sidebar) 문자열은 objc_msgSend() 함수에 의해 RTTI(Run-time Type Information) 정보로 객체를 가져오기 위한 메시지라고 보면 된다. lldb의 're r' 명령을 통해 레지스터의 값들을 확인할 수 있다.

얼핏 보아도 아래의 스크린샷의 메모리 공간은 인스턴스 객체의 메시지와 메서드의 메시지들을 몰아서 외부에서 참조할 수 있도록 나열한 것임을 알 수 있다.


3. objc_msgSend() 메서드의 시그너처가 선언된 곳에서 objc_msgSend 호출

lldb 디버거를 통해 ni 명령으로 objc_msgSend() 함수에 진입하면 메시지 전달 함수가 메모리 상에 상주해 있는 곳으로 이동 시킨다.


4. 컨텍스트(Context)에서 전달된 메시지를 순회하여 검색/실행

전달되는 메시지를 통해 인스턴스의 메타데이터를 사용하여 실제로 객체를 가져오게 된다. 아래의 네모난 상자의 명령들이 바로 객체를 찾아오기 위한 루프(Loop)이다. 


5. 메시지에 의해 처리된 객체는 일부 캐싱하여 성능 향상을 꾀함

재미있는 점은 매번 메시지의 정보를 순회하면서 찾지 않고, 한번 찾은 정보는 별도로 캐싱 하고 있는 공간에서 검색하게 된다.


지금까지는 sidebar 인스턴스를 가져오기 위한 과정이었다. 이제 이 인스턴스 객체의 메서드를 호출하는 과정인데, objc_sendMsg()를 통해 메시지를 전달하여 찾은 메서드를 실행하게 된다.



Posted by 땡초 POWERUMC

댓글을 달아 주세요

불편한 매킨토시(Macintosh), 맥북에어를 사용하면서 좌충우돌

애플의 맥킨토시(Macintosh) 제품을 이용하면서 많은 사람들이 기존의 익숙함과 다른 인터페이스 환경 때문에 불편하다는 이야기를 한다. 필자도 카페베네 커피숍을 자주 가는데 대부분 그곳에 iMac 제품이 있는데, 한번씩 써보면 도대체 왜 이런 기계를 쓸까라는 생각을 할 만큼 불편했었다. 네이버 중고나라에서 맥북을 파는 사람들을 보면 이따금 '저랑 안맞는 것 같아서 팔아요' 라는 분들도 계실 정도다.


무엇이 맥킨토시 제품을 사용하는데 불편하게 만들까?

간단하게 필자의 생각을 요약해 보았다. 온전히 필자의 주관적인 기준이다. 불편한 점이 좀 유치하긴 하지만 처음 접해보는 맥킨토시 제품인지라 감각적인 디자인에 만족하면서도 막상 사소한 것에 불편함을 느꼈다.


  • 트랙패드
    필자의 맥북에어에 붙어있는 트랙패드가 상당히 불편했다. 마우스 좌/우 버튼 조작이 어색해서 브라우저에서 스크롤을 하는 것이 여건 귀찮은게 아니었다.
  • 화면 인터페이스
    왜 윈도우 창의 버튼이 좌측이 몰려있나. 우측으로 옮길 수 없을까? 윈도우에 익숙해진 탓에 창 버튼이 좌측에 몰린 것이 거슬린다.

  • 뭘 해야 할지 모르는 산만함
    OSX(오에스 텐)의 상단에 상태바에 메뉴가 있다. 그리고 하단에 커다란 아이콘이 있다. 보이지 않는 설치된 응용 프로그램들을 어디서 찾아야 하지?

맥킨토시(Macintosh) 초보 탈출

이 외에도 사소한 것들이 더 많았던 것 같았다. 그래서 약 이틀 정도 사용법에 익숙해지기 위해 검색하고 찾아보면서 '완전한 초보자를 위한 몇 가지 가이드'를 제시하고자 한다.


지금까지 약 2주정도 맥북에어를 사용해 보니, 오히려 원도우가 더 답답하게 느껴질 정도로 맥킨토시의 운영체제는 직관성있고 매우 편리하다. 맥킨토시의 매력은 아마 각자가 찾아야 하지 않을까 생각한다. 적어도 맥이 더이상 불편하다는 생각은 말끔히 사라질 것이다.



OSX 환경 설정

OSX 운영체제의 환경을 설정하는 것만으로 효과를 톡톡히 볼 수 있다. 마치 윈도우를 처음 설치하면 자기 입맛에 맞게 바탕화면이나 키보드 눌림 스피드나 마우스 포인터 속도를 자신에게 맞추는 작업이라고 생각하면 된다.

여기에 나열되는 설정은 좌측 상단의 '사과 아이콘->시스템 환경 설정'으로 들어가면 된다.
 


  1. 하단 Dock 아이콘 숨기기
    Dock 을 자동으로 숨기도록 하여 일반 윈도우를 더 크게 사용할 수 있다.

  2. 키보드 반응 속도 향상
    키보드 반응 속도는 아래의 슬라이드 바를 빠르게/짧게 상태인 우측으로 옮겨주면 된다.
    그리고 F1~F12키보드를 Fn(펑션키)와 함께 눌러서 특수 기능을 사용하도록 하는 것이 좋다. 이를 설정하려면 아래의 '모든 F1, F2 등의 키를 표준 기능 키로 사용' 항목을 체크한다.

  3. 트랙패드 제스처 활성화
    만약 휠 마우스를 사용한다면 아래의 '스크롤 및 확대/축소' 탭에서 '스크롤 방향: 자연스럽게' 항목은 체크 해제한다. 이를 해제하지 않으면 아래로 스크롤 하기 위해 비행 시뮬레이션 게임을 하듯 마우스 휠을 위로 올려야 한다.

필수 소프트웨어

  1. KeyRemap4MacBook
    맥킨토시에서 제공하지 않는 키보드 제어 기능을 사용할 수 있다. 한영 전환 키라든가, 키보드 기능을 바꾼다거나 할 경우 이 앱을 설치하면 된다.
     

    KeyRemap4MacBook 다운로드
    http://pqrs.org/macosx/keyremap4macbook/


  2. 우측 Command 키로 한영 전환
    아래에 보이는 항목을 찾아 체크해 준다.


  3. 키보드 누를 때 반복/속도 향상
    아래의 항목의 수치를 적당하게 조정하면 키보드 반응 속도를 더욱 높일 수 있다.



OSX 자주 사용하는 핫키

몇 가지의 자주 사용하는 핫키만 알면 맥킨토시를 사용하는 것이 한결 자연스러워진다. 

핫키를 사용하기 위해 아이콘이 어떻게 생겼는지 반드시 기억하기 바란다.
 





  1. Mission Control(미션 컨트롤)
    화면의 윈도우와 열려있는 스페이스를 한 화면에서 볼 수 있는 편리한 기능이지요.
    Control + ⇧

  2. 스페이스 이동
    Control + 오른쪽 방향키 or 왼쪽 방향키
     
  3. SpotLight (스포트라이트)
    Control + Space

    OSX에서 사용중인 리소스(응용 프로그램, 이메일, 문자 등)을 모두 검색해 준다.

트랙패드

트랙패드는 시스템 환경설정의 트랙패드 항목에서 매우 자세하게 볼 수 있다. 간단하게 자주 사용하는 제스처만 몇 개 꼭 알고 있으면 된다.

  • 두 손가락을 살짝 댓다가 때기 = 마우스 우클릭
  • 두 손가락 + 위 또는 아래 = 화면을 스크롤
  • 두 손가락 + 좌 또는 우 = 브라우저의 이전 페이지/앞 페이지 이동
  • 세 손가락으로 움직이기 = 아이콘이나 창을 이동
  • 네 손가락 + 좌 또는 우 = 스페이스 영역을 이동한다
  • 네 손가락 + 위 = Mission Control(미션 컨트롤) 실행



Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 양수영 2013.03.04 09:22 Address Modify/Delete Reply

    이미지들이 안보이는데요..?
    저만 그런가요? ㅎㅎㅎ

    • powerumc 2013.03.04 10:46 Address Modify/Delete

      지금 모바일로 보고 있는데
      이미지 잘 보이네여.

      이거 저만 보이는건가요? ㅡㅡㅎ

  2. 정환나라 2013.03.07 10:03 Address Modify/Delete Reply

    저는 pc에서 크롬으로 보고 있는데 만 아래 이미지 빼고는다 안나오는데요

  3. jamie 2013.03.15 14:20 Address Modify/Delete Reply

    크롬브라우저에서는 안보이나봅니다. 저도 크롬유저인데...ㅠㅜ