[macOS] CodeSign이 안 될때

해당 글을 쓰다가 이 FinderInfo에 대해 끝장을 봐야겠다는 생각이 들었다.

끝장을 보자.

00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

man xattr 에 따르면 FinderInfo는 32바이트 길이라고 한다. 저 띄어쓰기로 구분된 00 하나가 한 바이트를 나타낼 것이다.

그렇다면 바로 저 9번째 비트에 20이라고 되어있는 부분이 패키지라는 것을 알리는 부분임에 틀림없다.

한참을 인터넷을 돌아다닌 결과 FinderInfo에 대한 Carbon API 소스 코드를 찾을 수 있었다.


struct FileInfo {
  OSType              fileType;               /* The type of the file */
  OSType              fileCreator;            /* The file's creator */
  UInt16              finderFlags;            /* ex: kHasBundle, kIsInvisible... */
  Point               location;               /* File's location in the folder */
                                              /* If set to {0, 0}, the Finder will place the item automatically */
  UInt16              reservedField;          /* (set to 0) */
};

OSTypeFourCharCode 의 typedef, FourCharCode는 unsigned int 이다. 64비트 컴퓨터이므로 int는 16바이트이다.

맨 앞에 있는 0 4개는 fileType, 그 다음 0 4개는 fileCreator, 그 다음 0 4개가 바로 finderFlags 이고, finderFlags에 바로 우리가 찾던 정보가 들어있다.

/* Finder flags (finderFlags, fdFlags and frFlags) */
/* Any flag reserved or not specified should be set to 0. */
/* If a flag applies to a file, but not to a folder, make sure to check */
/* that the item is not a folder by checking ((ParamBlockRec.ioFlAttrib & ioDirMask) == 0) */
enum {
  kIsOnDesk                     = 0x0001, /* Files and folders (System 6) */
  kColor                        = 0x000E, /* Files and folders */
                                        /* bit 0x0020 was kRequireSwitchLaunch, but is now reserved for future use*/
  kIsShared                     = 0x0040, /* Files only (Applications only) */
                                        /* If clear, the application needs to write to */
                                        /* its resource fork, and therefore cannot be */
                                        /* shared on a server */
  kHasNoINITs                   = 0x0080, /* Files only (Extensions/Control Panels only) */
                                        /* This file contains no INIT resource */
  kHasBeenInited                = 0x0100, /* Files only */
                                        /* Clear if the file contains desktop database */
                                        /* resources ('BNDL', 'FREF', 'open', 'kind'...) */
                                        /* that have not been added yet. Set only by the Finder */
                                        /* Reserved for folders - make sure this bit is cleared for folders */
                                        /* bit 0x0200 was the letter bit for AOCE, but is now reserved for future use */
  kHasCustomIcon                = 0x0400, /* Files and folders */
  kIsStationery                 = 0x0800, /* Files only */
  kNameLocked                   = 0x1000, /* Files and folders */
  **kHasBundle                    = 0x2000, /* Files only */**
  kIsInvisible                  = 0x4000, /* Files and folders */
  kIsAlias                      = 0x8000 /* Files only */
};

바로 kHasBundle이 0x2000으로 되어있는것을 볼 수 있다. 결론적으로 이 부분에 kHasBundle 비트가 설정되어있다고 할 수 있겠다.

정말로 이게 맞는지 검증해 보자. kIsAlias0x8000 으로 되어있다. 그렇다면 alias를 만들어 xattr를 확인해 보자. alias-test로 해당 alias의 이름을 바꾸었다. xattr -px com.apple.FinderInfo alias-test 의 결과이다:

66 70 6B 61 4D 41 43 53 80 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

실제로 3번째 int 자리에 8000으로 플래그가 세팅되어있음을 확인할 수 있었다.

놀랍게도 그 앞에 있는 비트들도 해석이 가능하다. xattr -lx com.apple.FinderInfo alias-test 를 사용하면 hex 뿐만 아니라 ascii 텍스트도 볼 수 있다.

00000000  66 70 6B 61 4D 41 43 53 80 00 00 00 00 00 00 00  |fpkaMACS........|
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000020

맨 앞의 4자리는 fileType이고, 66 70 6B 61이 fpka로, 이 Finder.h 파일에 정의되어 있다.