postscript 문법 정리

2018. 6. 7. 02:440x06 Malware

728x90

Adobe PostScript란 디지털 인쇄기술의 근간이라고 할 수 있는 프레임워크의 일종이다.

pdf와 같은 전자 문서 형식이며, 페이지를 기술할 수 있는 PDL의 일종.


텍스트는 줄을 가로질러 분할 되고 논리적 구조를 강조하기 위해 들여쓰기도 가능하다. 


주석은 %기호를 사용한다. 


현재 LanguageLevel은 3이다. 


PostScript가 파일을 출력하는 데 많이 쓰이기는 하지만, 편집이 불가능한 프레임워크는 아니다.


PostScript 역시 스택이 존재한다. 스택 관련 명령어는 다음과 같다.


1.  count 

스택의 깊이를 스택의 맨 위에 올려둔다. 


2.  clear

스택의 모든 데이터를 제거한다. 


3.  copy 

가이드 라인 오류인 것 같다. 가이드라인은 index와 동일한 기능을 적어두었다.

내가 생각하기에 copy라는 명령어는 [n] copy 일 경우는 올바르지 않은 명령이면서 [n]은 그대로 push되며 [n] [n1] copy [n2] 인 경우는 [n]과 [n2]만 push 된다.


4.  dup

스택의 가장 위의 객체를 복사하여 스택에 추가 시킨다.


5.  exch 

c언어의 swap, 어셈블리어의 xchg와 동일하다. 

하지만, post script에서 스택의 명령어로 쓰일 때는 단순하게 두 개의 데이터가 교환 되는 것이 아닌,

스택의 상위 2개의 요소의 위치가 교환 되는 것이다.


6. index 

스택의 n번째 객체 사본을 맨 위에 추가한다. (기준은 top이 [0] index가 된다


7. pop 

스택의 마지막 요소를 제거한다. 


8.  roll 

스택의 상위 n개 객체를 치환한다.


공부 하면서 알게 된 것 post script는 스택 기반 프레임 워크이다.


스택의 첫 요소는 인덱스가 [0]이다.  근거는 해당 그림에서 알 수 있다.




여느 언어에서 스택은 push가 있지만, postscript에는 push라는 command가 존재 하지 않는다.

데이터를 입력하고 개행하는 순간 push가 되기 때문이다.

실제로 스크립트에서 push라는 명령어를 입력해보았다.



다음은 count 명령어 예시다.

count 명령을 입력하기 전에 stack이라는 명령을 입력했다. 

stack은 현 스택의 상태를 출력 시켜준다. 

현 스택의 상태는

2

5

3

이다. 


이때 커서는 GS<4> 즉 스택의 5번째를 가리키고 있다.

나는 count라는 명령어를 입력하면 어떤 일이 발생하는지 알고 있다.


4

2

5

3

4

라고 스택이 출력되게 되는데, count 명령어를 한번 더 상기할 필요가 있다. 스택의 깊이를 스택의 맨 위에 올려둔다고 위에 표현해두었다. 좀 더 쉽게 풀어쓰면, top 위치 (커서가 위치하고 있는 곳)를 스택에 push하겠다는 것이다. 


pop을 하게 되면 스택의 top 요소가 하나 빠져나가게 된다. 



copy는 이해가 잘 되지 않아 여러번 테스트를 해보았다.


첫 번째 케이스로 스택에 5 4 3 2 1 순으로 push 하고 copy 3이라는 명령을 수행했다. 

스택의 결과는 

2

2

3

4

5

가 되었다. 해당 명령어에서는 [x] copy [n] 이기 때문에 [n]이 그대로 push 됨을 확인했다. 


두 번째 케이스이다.


[n] copy [x] 를 수행해 보았다. copy 명령어를 잘못 이행한 듯 한 Error가 출력 되었음에도 불구하고 stack에는 10이라는 값이 push 됨을 확인했다. 이로써 postscript의 명령어의 조합은 or연산으로 추정해본다. 


세 번째 케이스이다.


[n] [n2] copy [n3] 을 수행해보았다. 결과는 [n]은 push되고, [n2]는 무시되면서 [n3]이 push 되었다.

즉 x86 Assembly로 표현을 해보자면 

mov eax, [n]

push eax

mov eax, [n2]

mov eax, [n3]

push eax 가 되는 것이다. 


dup 명령어는 스택의 top 요소를 한번 더 push 하는 명령어이다.


index 명령어의 경우는 스택의 top을 기점으로 [n] 번째 요소를 push한다. 


현재 스택은 5 4 3 2 1 순으로 쌓였기 때문에

1

2

3

4

5

로 세팅 되어 있다. 

해당 명령을 수행하면, top을 [0]으로 잡게 되는데 [n]값이 1이기 때문에 스택의 요소 2가 push되게 된다.



익히기 위해 하나만 더 수행해보자. 이번에는 3 index를 할 것이다. 

top을 [0]으로 잡고 [n] index를 수행하면 요소 3이 push 될 것 이다. 확인해보자.


roll 명령은 [n] [n+1] roll이 라면 [n]번째를 기준점으로 삼고, [n+1]의 연산만큼 위로 올리는 것이다.


예를 들어 스택에 1 2 3 4 5 순으로 push를 하게 되면

5

4

3

2

1 로 세팅이 된다. 


이때 4 1 roll 을 하게 되면 top을 기점으로 4번째 줄을 기준으로 삼아 +1씩 위로 올린다.

이때 5번째 줄은 기준에 해당하지 않으므로 고정이 된다.

즉, 5번째 줄의 '1'은 움직이지 않는다.

[1] 5

[2] 4

[3] 3

[4] 2

[5] 1

이라면 [5]는 고정이 되고, [4]->[3] , [3]->[2] , [2] -> [1] , [1]은 [4] 기점으로 이동하게 된다.


4

3

2

5

1




또 다른 예를 들어보자. 이번엔 4 -1 roll이다. 

4번째 줄을 기준으로 삼고 -1 만큼 감소한다. 

이번에도 스택에 push 순서는 1 2 3 4 5 

4

3

2

1

이 세팅되게 되고,

4번째 줄인 "2"를 기준점으로 삼는다. 


마지막 줄 (5번째 줄)은 고정이 되게 되고, [0]~[4]까지 -1씩 감소하게 된다. 


[0] 2

[1] 5

[2] 4

[3] 3

[4] 1



여기까지가 stack을 관리하는 주요 명령어이다.


이번에는 실제 악성코드의 코드를 분석하면서 postscript의 예약어들과 변수를 어떻게 사용하는지 알아보고자 한다. 


우선 postscript는 스택 기반이기 때문에 모든 변수가 스택에 push된다. 


변수 명은 / 을 통해 가능하다. 만약 상수 값을 제외한 문자를 입력하면 이런 상황이 도래 된다.



16진수를 push할 때는 16#숫자 를 사용하면 된다. 


postscript는 이어서 명령을 기입해도 알아서 분별하여 스택에 정확히 push해준다. 

스택에 push되는 순서는 좌 -> 우 이다. 





'0x06 Malware' 카테고리의 다른 글

가이드라인이라 쓰고 삽질의 흔적이라 읽는다.  (0) 2018.04.02
XMR Virus  (0) 2018.02.14
CodeEngn Malware 08  (0) 2018.01.07
CodeEngn Malware 07  (0) 2018.01.07
CodeEngn Malware 06  (0) 2018.01.07