DongDD's IT

Register 및 어셈블리어, Calling Convention, Endian 본문

IT 보안/Reversing

Register 및 어셈블리어, Calling Convention, Endian

DongDD 2017. 12. 29. 16:53

Register 및 어셈블리어 정리


레지스터


IA-32 레지스터

- Intel에서 만든 32bit 크기의 레지스터

- 32bit(4bytes) 데이터를 한번에 처리 가능

- 32bit 크기로 메모리 주소 접근 가능


범용 레지스터 : 연산에 사용되는 레지스터

1) EAX : 산술, 논리 연산에 사용되는 레지스터, 함수 리턴 값 전달용도로도 사용된다.

2) EBX : 간접 주소 지정 시 사용되는 레지스터

3) ECX : 루프문에서 반복 명령 수행 시 반복 횟수를 저장하기 위해 사용하는 레지스터

4) EDX : 간접 주소 지정에서 사용되는 레지스터이고 곱셈, 나눗셈 시 보조 연산 레지스터로 사용된다.


포인터 레지스터 : 주소를 가리키는 포인터 용도로 사용되는 레지스터

1) ESP(Stack Pointer) : 가장 최근에 스택에 들어온 Data를 가리키는 레지스터

2) EBP(Base Pointer) : 스택 프레임 사용 시 현재 실행 중인 함수 스택 프레임의 시작 주소를 가리키는 레지스터


인덱스 레지스터 : 연산과 간접 주소 지정에 사용되는 레지스터

1) ESI(Source Index) : 복사, 비교에 사용되는 Source string을 가리킴

2) EDI(Destination Index) : 복사, 비교에 사용되는 Destnation string을 가리킴


인스트럭션 레지스터(인스트럭션 포인터)

1) EIP(Instruction Pointer) : 다음에 실행될 명령어의 주소를 가리키는 레지스터(CS 레지스터와 함께 실행 주소를 참조)


세그먼트 레지스터

1) CS(Code Segment) : Code Segment의 시작 주소를 가리키고 EIP 레지스터가 가지고 있는 offset과 더해져 실행을 위한 명령어 주소 참조

2) DS(Data Segment) : Data Segment의 시작 주소를 가리키고 범용 레지스터가 가지고 있는 offset과 더해져 데이터 영역 주소 참조

3) SS(Stack Segment) : Stack Segment의 시작 주소를 가리키고 포인터 레지스터가 가지고 있는 offset과 더해져 스택 영역 주소 참소


Flags : 산술, 논리 연산을 통한 결과 값으로 Flag값이 변화한다.


1) CF(Carry Flag) : 부호 없는 값의 연산 결과가 피연산자의 범위를 벗어났을 때 설정된다.

2) ZF(Zero Flag) : 연산 결과가 0일 때 1로 설정된다.

3) SF(Sign Flag) : 연산 결과의 최상위 비트가 음수이면 1로 설정되고 양수이면 0으로 설정된다.

4) OF(Overflow Flag) : 부호 있는 숫자의 연산 결과가 피연산자의 범위를 벗어났을 때 설정된다.


Assembly Language


- 기계어와 1:1로 매칭되는 언어

- 기계어와 고급 언어의 중간 단계의 언어

- 2진수로 표현된 기계어를 사람이 알아볼 수 있게 번역한 언어


어셈블러(Assembler) : 어셈블리어를 기계어로 바꿔주는 프로그램


디스어셈블러(Disassembler) : 기계어를 어셈블리어로 번역해 보여주는 프로그램(Ollydbg, IDA, GDB)


Intel vs AT&T

1) Intel

- Operand의 순서가 역방향(mov dst, src)

- mov eax, ecx(ecx -> eax)

2) AT&T

- Operand의 순서가 정방향(mov src, dst)

- mov %ecx, %eax(ecx -> eax)


명령어

1) 복사 Instruction

① MOV : source data를 destination data에 복사, Operand의 사이즈가 같아야한다.(레지스터를 통해서 수행)

② MOVZX : MOV와 같은 동작을 하지만 부호를 가지지 않는다.(남는 공간을 0으로 채움)

③ MOVSZ : MOV와 같은 동작을 하지만 부호를 가진다.(남는 공간을 부호에 맞는 비트로 채움)

④ MOVS : ESI에 존재하는 String을 EDI가 가리키는 주소로 복사한다.

2) 산술 Instruction

① ADD : 덧셈

② SUB : 뺄셈

③ MUL : 부호를 가지지 않는 곱셈(MUL ECX -> EAX*ECX, EAX Register를 기준으로 곰셈을 함)

④ IMUL : 부호를 가지는 곱셈(IMUL ECX -> EAX*ECX, EAX Register를 기준으로 곰셈을 함)

⑤ DIV : 부호를 가지지 않는 나눗셈(DIV ECX -> EAX/ECX, 목 : EAX, 나머지 : EDX)

⑥ IDIV : 부호를 가지는 나눗셈(DIV ECX -> EAX/ECX, 목 : EAX, 나머지 : EDX)

⑦ SHL : destination의 값을 source의 값만큼 왼쪽으로 이동시킴(SHL EAX, 0x1) 

  EAX: 0010 -> EAX : 0100

⑧ SHR : destination의 값을 source의 값만큼 오른쪽으로 이동시킴(SHL EAX, 0x1)

  EAX: 0010 -> EAX : 0001

⑨ LEA : []안의 자체 값을 복사한다. (LEA ESI, [EBP +8] -> EBP+8의 값이 ESI에 들어간다)

⑩ XOR : 초기화와 암호화, 복호화에 주로 사용된다.(XOR EAX, EAX -> EAX : 0)

3) 비교 Instruction

① REP : ECX 레지스터에 저장된 값만큼 명령어를 반복해서 실행한다.

② CMP : 두개의 피연산자를 비교한다.(Destination-Source를 통해 비교), 두 값이 같다면 ZF가 1로 설정되고 다르다면 ZF는 0으로 설정된다.

③ TEST : 두개의 피연산자를 AND연산하여 플래그 레지스터에만 영향을 준다. 즉, 결과 값의 상태 정보만 저장된다.

4) 분기 Instruction

① JMP : 해당 주소 값으로 이동(jump)한다.

② JZ : 0(ZF : 1)이면 이동(jump)한다.

③ JE : CMP의 결과가 0(ZF : 1)이면 이동(jump)한다.

④ JB : CMP의 결과가 음수이면 이동(jump)한다. (desnation < source)

⑤ JA : CMP의 결과가 양수이면 이동(jump)한다. (destination > source)

⑥ JNE : CMP의 결과가 같지 않으면 이동(jump)한다.

⑦ JNZ : CMP의 결과가 0이 아니면(ZF : 0) 이동(jump)한다.

⑧ CALL : 함수 호출 시 사용된다. 함수 호출 시 복귀 주소를 저장하고 호출한다

⑨ RET : 함수 종료 시 복귀하기 위해 사용된다. ESP값에 RET의 Operand값을 더한다.(RET 4 -> ESP+4로 이동)


콜링 컨벤션(Calling Convention)


- 함수를 호출하는 규약으로 스택을 이용하여 파라미터를 전달할 때 인자 전달 방법, 인자 전달 순서, 전달된 파라미터가 해제되는 곳, 리턴 값 전달 등을 명시한다.


1) _cdecl

- 매개 변수 전달 방식 : 우측 -> 좌측

- C, C++에서의 default

- 함수를 호출한 곳에서 파라미터 해제를 담당한다.

2) _stdcall

- 매개 변수 전달 방식 : 우측 -> 좌측

- 함수 내부에서 파라미터 해제를 담당한다.(프로시저 복귀 전 파라미터 해제)

3) _fastcall

- 매개 변수 전달 방식 : ecx, edx, 우측 -> 좌측(처음 두 개의 파라미터는 ecx, edx에 저장)

- 함수 내부에서 파라미터 해제를 담당한다.(프로시저 복귀 전 파라미터 해제)

4) thiscall

- 매개 변수 전달 방식 : ecx, 우측 -> 좌측(처음 한 개의 파라미터는 ecx에 저장)

- 함수 내부에서 파라미터 해제를 담당한다.(프로시저 복귀 전 파라미터 해제)


Big Endian vs Little Endian


Endian(Byte Ordering) : 데이터를 저장할 때 메모리에 저장되는 순서


1) Big Endian

- 낮은 주소에 상위 바이트 부터 저장

- Sparc/RISC 계열에서 사용

2) Little Endian

- 낮은 주소에 하위 바이트 부터 저장

- Intel 계열에서 사용



Comments