MIPS 명령어

공부 2014. 11. 21. 02:03
반응형

 MIPS 명령어의 필드

 

[   op   ][   rs   ][   rt   ][   rd   ][ shamt ][ funct ]
6bits      5bits     5bits     5bits     5bits      6bits

op : 명령어가 실행할 연산의 종류 opcode로 불리운다.
rs : 첫 번째 근원지(source) 피연산자 레지스터
rt : 두 번째 근원지 피연산자 레지스터
rd : 목적지(destination) 레지스터, 연산 결과가 기억된다.
shamt : 자리이동(shift) 양

funct : 기능(function). op 필드에서 연산의 종류를 표시하고 funct 필드에서는 그 중의 한 연산을 구체적으로 지정한다. 기능 코드(function code)라고 부르기도 한다.

MIPS 명령어

 

산술연산자

add                            : $s1 = $s2 + $s3
sub (subtract)             : $s1 = $s2 - $s3
addi (add immediate)   : $s1 = $s2 + 100
addu (add unsigned)    : $s1 = $s2 + $s3
subu (subtract unsigned) : $s1 = $s2 - $s3
addiu (add immediate unsigned) : $s1 = $s2 + 100
mfc0 (move from coprocessor register) : $s1 = $epc :: EPC와 다른 특별한 레지스트를 복사하기 위해 사용
mult (multiply)             : Hi, Lo = $s2 x $s3  :: 64비트 부호 있는 곱셈; Hi, Lo
multu (multiply unsigned) : Hi, Lo = $s2 x $s3  :: 64비트 부호 있는 곱셈; Hi, Lo
div (divide)                   : Lo = $s2 / $s3, Hi = $s2 mod $s3 :: Lo = 몫, Hi = 나머지
divu (divide unsigned)   : Lo = $s2 / $s3, Hi = $s2 mod $s3 :: 부호없는 몫과 나머지
mfhi (move from Hi)      : $s1 = Hi :: Hi의 복사본을 얻는데 사용
mflo (move from Lo)     : $s1 = Lo :: Lo의 복사본을 얻는데 사용


논리연산자

and                            : $s1 = $s2 & $s3
or                               : $s1 = $s2 | $s3
nor                             : $s1 = ~($s2 | $s3)
andi (and immediate)   : $s1 = $s2 & 100
ori (or immediate)        : $s1 = $s2 | 100
sll (shift left logical)      : $s1 = $s2 << 10
srl (shift right logical)   : $s1 = $s2 >> 10


데이터전송 (메모리 <-> 레지스터)

lw (load word)            : $s1 = Memory[$s2 + 100]
sw (store word)          : Memory[$2 + 100] = $s1
lhu (load half unsigned): $s1 = Memory[$s2 + 100]
lbu (load byte unsigned): $s1 = Memory[$s2 + 100]


조건부 분기

beq (branch on equal) : if ($s1 == $s2) go to L
bne (branch on not equal) : if ($s1 != $s2) go to L
slt (set on less than)   : if ($s2 < $s3) $s1 = 1; else $s1 = 0
sltu (set less than unsigned): if ($s2 < $s3) $s1 = 1; else $s1 = 0
sltiu (set less than immediate unsigned): if ($s2 < 100) $s1 = 1; else $s1 = 0


무조건 점프

j (jump)                      : go to L
jr (jump register)          : go to $ra
jal (jump and link)       : $ra = PC + 4; go to L 


기본 블럭(basic block)

분기 명령을 포함하지 않으며(맨 끝에는 있을 수 있다.) 분기 목적지나 분기 레이블도 없는(맨 앞에 있는 것은 허용된다.) 명령어 시퀀스. 오랫동안 쓰여질 메모리 블럭인지의 구분 기준이기도 하며 컴파일러가 초기 단계에 하는 작업중의 하나이다.


 jal(jump-and-link)

지정된 주소로 점프하면서 동시에 다음 명령어의 주소를 레지스터(MIPS에서는 $ra)에 저장하는 명령어.


 복귀주소(return address)

프로시저 종료 후 제자리로 돌아갈 수 있게 하는 호출위치에 대한 링크. MIPS에서는 $ra 레지스터에 저장된다.


 프로그램 카운터(program counter, PC)
실행 중인 명령어의 주소를 가지고 있는 레지스터.


 스택 포인터(stack pointer)
가장 최근에 스택에 할당된 주소를 가리키는 값. 레지스터가 스필될 장소 또는 레지스터의 옛날 값을 찾을 수 있는 장소를 표시한다.

 

 

* 레지스터는 데이터를 저장하는 중 속도가 가장 빠른 장소이므로 가능한 많이 사용하는 것이 바람직 하지만, 레지스터가 제한되어 있으므로 프로시져 호출 시에는 다음과 같은 제약조건이 부여되고 그 이외에는 stack 을 활용한다.

$a0 - $a3 : 전달할 인수를 가지고 있는 인수 레지스터 4개
$v0 - $v1 : 처리 결과를 되돌려 주는 결과 값 레지스터 2개
$ra : 호출한 곳으로 되돌아 갈 때 사용하는 복귀주소 레지스터 1개
$t0 - $t9 : 프로시져 호출 시, 피호출 프로그램이 원상 복구해 주지 않는 임시 레지스터 10개
$s0 - $s7 : 프로시져 호출 전과 후의 값이 같게 유지되어야 하는 저장 레지스터 8개 
        (피호출 프로그램이 이 레지스터를 사용하면 원래 값을 저장했다가 원상 복구 해야 함.)


 전역 포인터(global pointer, $gp)
정적 데이터를 가리키는데 사용하도록 예약된 레지스터.


 프로시져 프레임(procedure frame)
레지스터에 들어가지 못할만큼 큰 배열이나 구조체같은 지역 변수를 저장하는데에도 스택을 사용하게 되는데. 이 떄에 프로시져의 $s 레지스터들과 지역 변수를 저장하는 스택(stack) 부분을 말하며 액티베이션 레코드라고도 한다.


 프레임 포인터($fp)
프로시져의 저장된 레지스터와 지역 변수의 위치를 표시하는 값.

* 메모리의 사용 시에 스택은 최상위 주소에서부터 시작해서 아래쪽으로 자라며 아래와 같은 모양이다.
$sp -> 7fff fffc     ────────
                                            stack
                                             ↓
 
                                             ↑
                                    dynamic data (heap)
$gp -> 1000 8000 ────────
                                        static data
$gp -> 1000 0000 ────────
                                             text
pc  -> 0040 0000 ────────
                                           사용유보
                            0 ────────

 텍스트 세그먼트(text segment)

Unix 목적 파일에서 원시 파일 루틴의 기계어가 수록된 부분.


 PC-상대주소지정방식(PC-relative addressing)

PC와 명령어 내 상수의 합이 실제 주소가 되는 주소 지정방식으로 32bit 명령어를 만드는 방식이기도 하다.

 

 MIPS 주소지정방식

1. 수치(immediate) 주소지정 ... 피연산자는 명령어 내에 있는 상수이다.           [ op ][ rs ][ rt ][    수   치   값    ]

2. 레지스터 주소지정 ... 피연산자는 레지스터이다.
   [ op ][ rs ][ rt ][ rd ][ ... ][ funct ]
               └────────→ [      레지스터     ]

3. 베이스(base) 또는 변위(displacement) 주소시정 ... 메모리 내용이 피연산자이다. 
  메모리 주소는 레지스터와 명령어 내의 상수값을 더해서 구한다.
   [ op ][ rs ][ rt ][    Address    ]
               └───────┐                                  메모리
                                               (+) ──→ [ 바이트 | 하프워드|     워드       ]
             [      레지스터     ]──┘


4. PC-상대주소지정 ... PC값과 명령어 내 상수의 합을 더해서 주소를 구한다.
   [ op ][ rs ][ rt ][    Address    ]
               └───────┐                                  메모리
                                               (+) ──→[                 워드                 ]
             [      레지스터     ]──┘

5. 의사직접(pseudodirect) 주소지정 ... 명령어 내의 26비트를 PC의 상위 비트들과 연접하여 점프주소를 구한다.
   [ op ][              Address            ]
               └───────┐                                  메모리
                                               (:) ──→ [ 바이트 | 하프워드|     워드       ]
             [           PC        ]──┘


참조 :  http://cluster1.cafe.daum.net/_c21_/bbs_search_read?grpid=1Iply&fldid=Hsaf&datanum=238&openArticle=true&q=%BA%B9%B1%CD%20%B8%ED%B7%C9%BE%EE&re=1

'공부' 카테고리의 다른 글

VA & RVA (절대주소, 상대주소)  (0) 2015.01.02
[리버싱 핵심원리]PE File Format #1 -- 미완성  (0) 2014.12.24
새로 알게 된것  (0) 2014.11.02
RTL(Return To Libc)  (0) 2014.11.02
스택 구조와 sfp 그리고 ret  (0) 2014.11.01
블로그 이미지

KuroNeko_

KuroNeko

,

API Hooking - Debugging

API/공부 2014. 11. 13. 23:07
반응형

디버깅을 하고 데이터를 얻기 위해서는 프로세스의 PID가 필요하고 그 프로세스의 핸들이 필요한데, 간단히 프로세스 스냅샷을 찍어 해당 PID를 구하고 OpenProcess로 프로세스의 핸들을 받아온다.그리고 또 디버깅 이벤트를 발생시켜야하는데 INT_3를 WriteProcessMemory를 사용하여 한바이트만큼 넣어주고 다시 함수를 호출할 때 예외 이벤트를 걸리게 해준다. 이벤트가 걸려있는 동안 우리는 파라미터나 데이터를 가져올 수 있는데, 데이터를 얻은 다음 INT_3을 함수의 원래 주소(1바이트)값으로 변경시키고 다시 호출시킨다.


'API > 공부' 카테고리의 다른 글

DLL Injection  (0) 2015.05.27
API 자료형(추가 예정)  (0) 2014.10.31
HANDLE and etc  (0) 2014.10.31
블로그 이미지

KuroNeko_

KuroNeko

,

API Hooking - Debugging

API/자료 2014. 11. 13. 23:01
반응형

디버깅을 이용한 API후킹입니다.


이 예제는 간단히 안티디버깅기법으로 막힙니다.



API Hooking(Debug).zip


블로그 이미지

KuroNeko_

KuroNeko

,

새로 알게 된것

공부 2014. 11. 2. 14:54
반응형

ln

-s : 소프트 링크(바로가기 역할)

-sf : 강제 링크걸기

default(옵션X) : 하드 링크(이게 변경 되면 원래 데이터까지 바뀐다)


vi 편집기

- vi편집기에서 :!명령어 를 사용하면 !뒤에 명령어를 실행가능

'공부' 카테고리의 다른 글

[리버싱 핵심원리]PE File Format #1 -- 미완성  (0) 2014.12.24
MIPS 명령어  (0) 2014.11.21
RTL(Return To Libc)  (0) 2014.11.02
스택 구조와 sfp 그리고 ret  (0) 2014.11.01
클래스와 네임스페이스  (0) 2014.10.30
블로그 이미지

KuroNeko_

KuroNeko

,

RTL(Return To Libc)

공부 2014. 11. 2. 00:56
반응형

RTL

- 개념 : ret를 시스템명령을 내릴 수 있는 함수의 주소를 덮어씌우고 해당 인자값을 넣어 exploit 하는 것(?)

- 보통 system함수를 사용한다.


Libc라는 건 윈도우 환경에서 프로그래밍을 해봤다면 헤더라는 말을 들어봤을 것이고, 그 헤더는 함수들의 집합체라고 할 수 있겠다. RTL ,말 그대로 헤더안의 함수들의 주소로 이동해 메모리 안에 있는 인자값을 이용해 실행하는 것.


예를 들어 LOB에 darkknight문제를 보면


Buf[40byte]+SFP[4byte]+ret[4byte]+---


이런 식으로 기본적인 틀이 잡아지는데, buf의 48번째 값이 bf(스택안의 값) 이 되면 안되기 때문에 RTL을 사용해서 풀어야한다.

가장 많이 사용하는 system함수는 뒤에 4byte 짜리 두개의 인자 값을 가지며,

첫번째에 해당하는 인자값은 실행할 명령어

두번쨰에 해당하는 인자값은 함수를 실행하고 다음으로 진행할 주소값

을 가진다. 그럼 스택에서는 이 값들을 리틀 엔디안 방식으로 넣어야하기 때문에 반대로 들어간다.(진행될 주소값, 명령어 순)


그럼 결과적으로 payload는 이렇다


Buf[40byte]+SFP[4byte]+system+exit+&/bin/sh


여기서는 깔끔하게 쉘을 따기 위해서 exit함수를 사용했다.

/bin/sh의 주소값은 간단하게 memcmp로 확인하자.

'공부' 카테고리의 다른 글

MIPS 명령어  (0) 2014.11.21
새로 알게 된것  (0) 2014.11.02
스택 구조와 sfp 그리고 ret  (0) 2014.11.01
클래스와 네임스페이스  (0) 2014.10.30
FD(File Descriptor) 정리  (0) 2014.10.05
블로그 이미지

KuroNeko_

KuroNeko

,
반응형

스택 : 지역변수나 매개변수들이 쌓이는 메모리공간,


특징

 - 리틀 엔디안 방식으로 저장된다. == 하위 바이트부터 먼저 들어간다.


스택의 기본 구조

- Buffer + sfp[4byte] + ret[4byte]


Buffer : 데이터가 저장되는 공간.

SFP

- leave 시켜 ret로 돌아갈 주소를 ebp에 불러온다.(pop ebp로 4바이트를 뛴다.)

mov esp, ebp

pop ebp

ret : 리턴

'공부' 카테고리의 다른 글

MIPS 명령어  (0) 2014.11.21
새로 알게 된것  (0) 2014.11.02
RTL(Return To Libc)  (0) 2014.11.02
클래스와 네임스페이스  (0) 2014.10.30
FD(File Descriptor) 정리  (0) 2014.10.05
블로그 이미지

KuroNeko_

KuroNeko

,
반응형

1. DWORD

- 32비트(4바이트) 정수형

- unsigned int


2. WORD

- 16비트(2바이트) 정수형

- unsigned short


3. BYTE

- 8비트(1바이트) 정수형

- unsigned char


4. LPSTR

- Long Pointer String 의 약자 == char *


5. LPCSTR

- Long Pointer Constant String 의 약자 == const char *


//프로그램 환경에 따라서 형태가 바뀌는 매크로역할

6. LPTSTR

- Long Pointer t_string == tchar *

7. LPCTSTR

- Long Pointer Constant t_string == const tchar *


//Unicode

8. LPWSTR

- Long Pointer Wide String == w_char *

9. LPCWSTR 

- Long Pointer Constant Wid String == const w_char *

'API > 공부' 카테고리의 다른 글

DLL Injection  (0) 2015.05.27
API Hooking - Debugging  (0) 2014.11.13
HANDLE and etc  (0) 2014.10.31
블로그 이미지

KuroNeko_

KuroNeko

,

HANDLE and etc

API/공부 2014. 10. 31. 21:17
반응형

핸들(HANDLE)

- 운영체제는 자신을 보호하는 기능이 있어야한다. 왜냐면프로그램이 운영체제의 자원을 필요로 해서 바로 접근을 한다고 하면 운영체제의 권한을 탈취 당할 수 있기 때문인데, 이를 방지하기 위해서 프로그램에게 알려주는 값.

- 프로그램은 운영체제의 자원을 사용하기 위해 운영체제에게 핸들을 제시해줘야 한다.


HWND

- HandleWindow의 약자로 창의 핸들을 말한다.


HINTERNET

- HandleInternet의 약자로 네트워크(?)를 사용하기 위한 핸들이다.


HINSTANCE

- Handleinstance의 약자로 프로그램 코드를 담고 있는 모듈에 대한 핸들

- 자원읽기에 주로 사용된다.


Etc...


Ps. Handle은 사용된 후에 반드시 닫아줘야한다.( CloseHandle() )

'API > 공부' 카테고리의 다른 글

DLL Injection  (0) 2015.05.27
API Hooking - Debugging  (0) 2014.11.13
API 자료형(추가 예정)  (0) 2014.10.31
블로그 이미지

KuroNeko_

KuroNeko

,