GCC가 경로 문자열을 16바이트 조각으로 쪼개 바이너리 검사를 무력화한다
Paths in Pieces
Linux 배포판과 패키지 관리자는 빌드된 바이너리에 절대 경로가 남았는지 grep이나 strings로 검사한다. 하지만 GCC는 std::string에 복사되는 문자열 상수를 16바이트 조각으로 나눠 xmm 레지스터로 옮기기 때문에, 원래 경로가 바이너리에 그대로 존재하지 않는다. 심지어 /home/linuxbrew/.linuxbrew가 /home/linuxbrew/xbrew/.linuxbrew처럼 전혀 다른 경로로 보이기도 한다. 반복되는 _placehold 패딩은 중복 제거로 256바이트가 176바이트로 줄어든다. Clang은 같은 명령을 생성하면서도 문자열을 쪼개지 않는다. 저자는 -mstore-max=128 외에는 끌 방법이 없다며, 바이너리 해석 가능성을 위해 문자열을 온전히 두는 편이 낫다고 주장한다.
바이너리에서 strings ./binary를 돌리는 것은 불투명한 바이너리 덩어리를 들여다보는 너무나 간단하고 편리한 방법이라, 쪼개기와 중복 제거가 주는 미미한 절약보다 그 가치가 크다.