<보안 study>/웹

WASM(Web Assembly) 정리

gosoeungduk 2021. 8. 31. 19:12
반응형

#WASM #Web Assembly #웹어셈블리


웹 브라우저에서 js 가 아닌 코드가 컴파일 되어 실행되는 컨셉이다.

img0

wasm 은 브라우저에서 text format 으로 나타내어 보여준다.

개인 공부용으로 해당 text format 의 명령어나 문법을 간략히 정리해본다.

(module
 ...
 )

(module ... ) 안에는 해당 웹어셈 프로그램에 쓰인 요소들이 들어간다.

안에 들어가는 요소는 func, global, memory, table, 등등이 있다.

img1

(;0;) (;1;)

그리고 위와 같이 각 요소들은 순서에 따라 서수(ordinal)를 갖게된다. (0번 요소, 1번 요소 , ...)

(func $함수변수이름 (;0;) (export "사용할 함수이름") (param $인자로 쓰이는변수 i32) (result i32)
    (local $함수내 지역변수들) (local $함수내 지역변수들) ... 
    // 함수 구문 시작
)

함수 정의 부분이다. 처음엔 낯설어도 꽤 친절한 구조이다.

일단 괄호를 통해 함수 하나를 묶어 준다. 그리고 func 로 선언을 해주는데 해당 함수 이름은 $ 표시 뒤에 써주면 된다. export 할 시에는 export 뒤에도 export 할 이름을 써주면 된다.

그리고 param 구문으로 인자를 정의할 수 있는데, 인자가 여러개라면 (param ~~) 구문을 개수만큼 써주면 된다. 대신 $ 뒤에 오는 변수이름은 각각 다르게 해야한다. 또한, 인자와 더불어 return 구문으로 반환 값에 대한 형식 i32, i16,... 을 지정해줄 수 있다.

바로 다음에는 해당함수에서 쓰이는 지역변수를 local 구문을 통해 정의해준다. 그 뒤에는 함수 내용이 시작된다.

WASMC/C++ 등을 웹에서 읽도록 효율적으로 변환한 결과라지만, 여전히 stack 을 이용하는 언어이다.

이는 개발자도구에서도 살펴볼 수 있는 기능을 갖고있는데, 예를들어

i32.const 255
local.set $var2

해당 구문이 있다고 하면, 첫 번째 줄 실행 시 스택에는 255 값이 들어간다.

img2

그리고 local.set 을 통해 var2 에 스택의 255 값을 pop 하여 넣어준다.

img3

아무튼 이런 원리.

변수와 스택에 값 왔다갔다 시키기 (set, get)

set 은 변수에 값을 넣는 대입연산자의 느낌이다. 보통 위에 코드처럼 상수 값 뒤에 연달아 나오는 것이 특징.

상수 값을 스택에 넣고, 스택 맨 위에 있는 해당 값을 pop 하여 변수에 집어 넣는다.

get 은 변수에 있는 값을 얻어와서 스택 맨 위에 push 하는 명령어다.

예를 들어, local.get $var1 이라는 구문이 있으면, 현재 $var1 에 있는 값을 스택에 push 하는 것.

메모리와 스택에 값 왔다갔다 시키기(store, load)

store 명령어는 메모리 상에 값을 저장시키는 명령어이다. 스택에 맨 위 부터 차례로 1000, 1 값이 있다면, store 명령어는 $memory + 1 의 위치에 1000 이라는 value 를 저장한다. 비트범위를 고정할 수 있는 store8, store16 등 종류도 다양하다.

load 명령어는 메모리로부터 스택에 값을 가져오는 명령어이다. 스택 맨 위에 1 이란 값이 있다면, load 명령어는 1을 pop 시키고 $memory + 1 위치에서 value 를 가져와서 스택에 push 한다.

조건문 (ne, eq, eqz)

일반 AT&T 나 INTEL 어셈블리의 jne , je 처럼 웹어셈블리도 동일한 역할을 하는 어셈명령어를 갖고있다.

일단 ne 는 스택 맨 위 두 값을 비교하여 두 값이 같지않으면, 두 값을 pop 시킨 후 1을 다시 push 한다. 만약 ne 명령어 직후 스택 맨 위 값이 1이면 같지 않다는 뜻으로 간주한다.

그러면 eq 는 ? 반대로 생각하면 되겠다. 같으면, 1을 push 하고 다르면 0을 push 한다.

그냥 두 값의 boolean 값을 리턴하는데 ne 만 반대로 간다고 생각하면 된다.

eqz 는 위 두 개랑 달리 하나의 스택 값(one operand) 을 갖고 비교한다. 만약 스택 맨 위 값이 0 이랑 같으면 1을 스택에 push 하고 다르다면 0을 push 한다.

이 정도만 정리하고, 분기 명령어는 하나이다.

분기문 (br_if)

br_if 는 스택 맨 위의 값이 1 이면, 분기하고 아니면 그대로 진행한다.


이 밖에도 add, sub 등 여러 명령어가 있지만 디버깅 해보면 다 이해 가능하다.

참고

WebAssembly: How and why

WASM Manual

WASM Windows2000

반응형

'<보안 study> > ' 카테고리의 다른 글

CSP(Content-Security-Policy) 정리  (0) 2021.08.23
DreamHack CTF 문제에서 배우는 NOSQL Injection  (0) 2020.09.30
동적 폼(form) 만들기  (0) 2018.07.24