SSA 1주차
Hacking/SSA 포너블 스터디

SSA 1주차

범용 레지스터는 계산, 메모리 어드레스 지정, 임시저장공간 등의 목적으로 사용한다

x86-64 프로세서의 범용 레지스터

AX :  산술 연산을 수행할때 누산기로 사용한다

BX :  데이터의 어드레스를 지정할때 데이터 포인터로 사용

CX :  루프 또는 문자열의 카운터로 사용

DX:  I/O 관련 어드레스를 지정할때 사용, 산술연산을 수행할때 보조 레지스터로 사용

SI :  문자열에 관련된 작업을 수행할때 원본 문자열의 인덱스로 사용

DI :  문자열에 관련된 작업을 수핼할때 목적지 문자열의 인덱스로 사용

SP:  스택의 포인터로 사용

BP:  스택의 데이터에 접근할때 데이터의 포인터로 사용

R8 ~ R15:   x86-64 프로세서에서 추가된 범용 레지스터로 다양한 용도로 사용가능 

//  16비트일때 접두사 X   32비트일때 E  64비트일때 R이 붙음


syscall 함수 

 인자로 시스콜 넘버를 사용

   함수 호출가능 

시스콜 넘버는 

asm-arm/unistd.h  에 있음

사용할때는 

#include <sys/syscall.h>
#include <unistd.h> 

로 헤더파일을 써주면됨

호출은 인터럽터를 사용하며 리눅스는 IDT의 128번째인(int $0x80) 인터럽터를 사용한다. 

※ 어셈으로 함수를 만들때 레지스터 사용방법

eax : syscall number
ebx : 첫번째 인자
ecx:  두번째 인자
edx:  세번째 인자
esi:   네번째 인자
edi:   다섯번째 인자
ebp:   여섯번째 인자

write 함수 구현

   int fd   // 파일 디스크립터
   void buf // 파일에 쓰기를 할 내용을 담은 버퍼
   size_t n 쓰기할 바이트 개수

AT&T 문법


상수 앞에는 $가붙고 레지스터 앞에는 %가 붙음 (AT&T기준)

.globl main

main:

        push %ebp 

        mov %esp, %ebp    //  함수 프롤로그 

        mov $1, %ebx        //   파일디스크립터 인자로 1을 넣음

        mov $helloworld, %ecx       // 문자열 내용을 담은 버퍼를 helloworld 로 정의 

        mov $12, %edx         //  쓰기할 바이트 개수 12

        mov $4, %eax          // 시스템콜 넘버

        int $0x80               //   syscall  호출 인터럽터 

        leave   

        ret                     // 함수 에필로그  


helloworld: .string "HelloWorld\n"       //  helloworld 의 내용을 정의 


 

strlen 함수 구현

 

※  인자로 string을 받아 null 이 나올때까지 카운트하여 문자열의 길이를 구한다.



strlen:
        push %ebp
        mov %esp, %ebp

        mov 0x8(%ebp), %eax         // ebp + 0x8은 첫번째 인자값  첫번째 인자값을 eax에 넣음
        mov $0x0, %ecx                //    ecx에 0x0을 넣음

        .loop:  
                movb (%eax), %bl              //  eax를 한글자씩 bl에 넣음
                cmpb $0x0, %bl                //   0x0과 bl을 한글자씩 비교함
                je .gogo                          //  값이 같으면 .gogo로 점프함
                inc %ecx                         //   ecx를 1 증가시킴
                inc %eax                         //   eax를 1 증가시킴
                jmp .loop                        //  .loop 로 점프함

        .gogo:
                mov %ecx, %eax              //  ecx를 eax에 넣음  eax는 보통 함수의 리턴값 

        leave
        ret



puts 함수 구현
※ 문자열을 앞에서 구현한 strlen 함수로 길이를 구해온다음 write함수로 출력한다 (strlen + write)



  Eax는 보통 함수의 리턴값이 담겨있다.

  Puts 함수를 쓸때 buf_size 부분에 Eax를 넣어주면 전 함수의 리턴값이 들어가게된다.


strchr 함수 구현

첫번째 인자를 한글자씩 잘라서 두번째 인자와 같을때까지 반복하고 같으면 검색한 글자의 주소를 리턴 

만약에 없으면 -1 을 리턴한다 


gets 함수 구현

 read 로 임시버퍼에 입력받은후 strchr 으로 \n을 NULL 처리한후 strcpy로 원래 입력할곳에 복사한다.