카테고리

asm (27) bootloader_x86_grub (1) C (92) compile (11) config (76) CPP (13) CSS (1) debugging (7) gimp (1) Go (1) html (1) Java (1) JavaScript (1) kernel (19) LibreOffice (3) Linux system progamming (21) MFC (1) opencv (4) OpenGL (1) PHP (1) Python (4) qemu (29) shell (3) socket (7) troubleshooting (2) ubuntu18.04 (2) windows (1)

2018/12/06

asm 64bit 키보드 입력 처리

global      _start         
section     .text
_start:
  mov         rax, 0          ; SYS_READ를 SYS_CALL 값으로 설정
  sub         rsp, 8          ; 읽기 버퍼로 스택에 8 바이트 공간을 할당
  mov         rdi, 0          ; rdi를 0으로 설정 STDIN, 키보드 입력
  lea         rsi, [rsp]      ; const char * buf를 스택의 8 바이트 공간에 설정
  mov         rdx, 1          ; char에 대해 size_t count를 1로 설정
  syscall

    mov         rax,1
    mov         rdi,1
    mov         rsi,message
    mov         rdx,13
    syscall
    mov         rax,60
    xor         rdi,rdi
    syscall

section     .data
    message:    db          "Hello, World", 10

compile:
nasm -felf64 hello.asm && ld hello.o && ./a.out

asm 시스템 콜 함수 표 검색

리눅스 커널 소스로 이동후 아래 명령어 실행
/usr/src/linux-source-3.19$ grep -rA3 'SYSCALL_DEFINE.\?(read,' *

asm32 키보드 입력 처리

;키보드 입력 시스템 콜
;systeam call tables 검색

SECTION .data

msg: db "Please enter a str: ", 0
msgLen: db 21

; msg:다른 코드 참조 레이블
; db:바이트 정의
; 0은 null 바이트

SECTION .bss

SECTION .text
global main ;외부 사용 가능

main:
push ebp
mov ebp, esp

;코드 작성 영역
 push DWORD [mesLen]
 push msg
 call write

 ;콘솔 읽기
 mov eax, 3
 mov ebx, 0 ; 표준 입력 키보드
 mov ecx, msg
 mov edx, 15
 int 0x80

 push 15
 push msg
 call write

;스택 해재
mov esp, ebp
pop ebp
ret

write:
push ebp
mov ebp, esp

;함수 코드 작성 영역
; 시스템 호출 작성
; 정의: write(fileDescriptor, char* msgAddr, bytes)

 mov ebx, 4
 mov ebx, 1 ;0=stdin 1=stdout 2=stderror
 mov ecx, [ebp + 8]
 mov edx, [ebp + 12]

 ;인터럽트 생성
 int 0x80


;compile
;nasm -f elf32 -o asm.o systemCalls.asm
;gcc -m32 -o program asm.o

asm 64bit 문자열

64 bit
global    _start

          section   .text
_start:   mov       rax, 1                  ; 쓰기 위한 시스템 호출
          mov       rdi, 1                  ; 파일 핸들 1은 stdout입니다.
          mov       rsi, message            ; 출력 할 문자열의 주소
          mov       rdx, 13                 ; 바이트 수
          syscall                           ; 쓰기 운여체제 호출
          mov       rax, 60                 ; 빠져나가기 시스템 호출
          xor       rdi, rdi                ; 종료 코드 0
          syscall                           ; 운영체제 종료 호출

          section   .data
message:  db        "Hello, World", 10      ; 개형 문자 \n

compile:
nasm -felf64 hello.asm && ld hello.o && ./a.out

asm 32bit write 함수 정의 후 호출

;시스템 인터럽트 write
;systeam call tables 검색

SECTION .data

msg: db "Asembly is freakin cool",10,0
msgLen: db 26

; msg:다른 코드 참조 레이블
; db:바이트 정의
; 10은 개형 문자 \n
: 0은 null 바이트

SECTION .bss

SECTION .text
global main ;외부 사용 가능

main:
push ebp
mov ebp, esp

;코드 작성 영역
; 시스템 호출 작성
; 정의: write(fileDescriptor, char* msgAddr, bytes)

 push DWORD [mesgLen]
 push msg
 call write

;스택 해재
mov esp, ebp
pop ebp
ret

write:
push ebp
mov ebp, esp

;코드 작성 영역
; 시스템 호출 작성
; 정의: write(fileDescriptor, char* msgAddr, bytes)

 mov ebx, 4
 mov ebx, 1 ;0=stdin 1=stdout 2=stderror
 mov ecx, [ebp + 8]
 mov edx, [ebp + 12]

 ;인터럽트 생성
 int 0x80


;compile
;nasm -f elf32 -o asm.o systemCalls.asm
;gcc -m32 -o program asm.o

asm 32bit 시스템 인터럽트 0x80

;시스템 인터럽트 0x80
;systeam call tables 검색

SECTION .data

msg: db "Asembly is freakin cool",10,0
msgLen: db 26

; msg:다른 코드 참조 레이블
; db:바이트 정의
; 10은 개형 문자 \n
; 0은 null 바이트

SECTION .bss

SECTION .text
global main ;외부 사용 가능

main:
;주 라벨을 만들고 스택 생성
push ebp
mov ebp, esp

;코드 작성 영역
; 시스템 호출 작성
; 정의: write(fileDescriptor, char* msgAddr, bytes)

 mov ebx, 4
 mov ebx, 1 ;0=stdin 1=stdout 2=stderror
 mov ecx, msg
 mov edx, [msgLen]

 ;인터럽트 생성
 int 0x80

;스택 해재
mov esp, ebp
pop ebp
ret

;compile
;nasm -f elf32 -o asm.o systemCalls.asm
;gcc -m32 -o program asm.o

asm 32bit 문법 기본 구조

;어셈블러 문법 구조
;컴파일 방법
;nasm -f elf32 -o asm.o systemCalls.asm
;gcc -m32 -o program asm.o

SECTION .data

SECTION .bss

SECTION .text
global main ;외부 사용 가능

main:
;주 라벨을 만들고 스택 생성
push ebp
mov ebp, esp

;코드 작성 영역

;스택 해재
mov esp, ebp
pop ebp
ret

asm 인수 전달 값 확인

; 어셈블리와 동등한 프로그램
SECTION .data
msg: db "Arg = %s ",10,0
msg2: db "Arg Count = %d ", 10,0

SECTION .text
;출력에 대한 접근 허용
extern printf
;main 외부적 사용 가능하게 만듬
global main

main: ;int main(int numArguments, char* arg[])
 push ebp
 mov ebp, esp

 mov eax, DWORD[ebp +8] ; 매개변수 위치
 mov ebx, DWORD[ebp +12]; arg 위치
 mov ecx, 0

beginLooping:
 ; 외부 함수는 레지스터에서 사용중인 값을 수정할 수 있기 때문에 항상 외부 함수를 호출하기 전에 값을 유지해야한다.
 push ebx ;ebx 영역: 인수 주소 보유
 push eax ;eax 영역: 인수의 수를 갖음
 push ecx ;eax 영역: 카운터 보유

 ;printf 호출
 push DWORD [ebx]
 push msg
 call printf
 add esp, 8 ;스택 정리

 ;항상 역순으로 복원
 pop ecx ;카운터 복원
 pop eax ;인수의 수를 되 돌림.
 pop ebx ;주소 복원

 inc ecx    ; 카운트 하나씩 증가
 add ebx, 4 ; 배열 다음 인수로 이동

 ; 루프
 cmp ecx, eax ;eax 같지 않으면
 jne beginLooping ; jmp 실행 else, exit

 mov esp , ebp
 pop ebp
 ret

compile.sh 변경

#!/bin/bash

numArg=$#
arch32=32
arch64=64

clear
if [ $numArg != 2 ] ; then 
echo "You enter too many or too little arguments to script when expected 2, asm file"
echo "you supplied only $numArg"
echo "Usage: compile <input.asm> <program_name>"
exit
else
echo "Compiling asm using NASM"
input=$1
output=$2
inter=asm000.o
nasm -f elf$arch32 -o $inter $input
ret=$?
if [ $ret != 0 ] ; then 
echo "Nasm compilation failed"
    exit
else
echo "compilation using GCC for final output"
gcc -m$arch32 -o $output $inter
ret=$?
if [ $ret != 0 ] ; then 
echo "There was a problem with gcc compilation"
exit
else
rm $inter
echo "Compilation successfull"
echo "Starting apllication ------------------------"
./$output arg1 arg2 arg3 arg4 
echo "Application ended --------------------------"
fi
fi
fi

asm esp Extended Stack Pointer, ebp Extended base Pointer

High Memory
Arg2
Arg1
ret
  <-----------------ebp
ebp
local1
local2
      <-------------esp
Low memory

example code
; 어셈블리와 동등한 프로그램
SECTION .data

msg1: db "The variable contains %d",10,0

SECTION .text
;출력에 대한 접근 허용
extern printf
;main 외부적 사용 가능하게 만듬
global main

main:
 push ebp
 mov ebp , esp
 sub esp, 10

 mov DWORD [ebp - 4] , 0xff ; variable 1
 mov DWORD [ebp - 8] , 0x10 ; variable 2

 push DWORD [ebp - 4]
 push DWORD msg1
 call printf

 push DWORD [ebp -8]
 push DWORD msg1
 call printf

 mov esp , ebp
 pop ebp
 ret

asm 조건문 비교 연산자

SECTION .data

x: dd 32
y: dd 56
msg1: db "X is greater thean Y",10,0
msg2: db "Y is greater thean X",10,0

SECTION .bss

SECTION .text

extern printf ;from c standard libray
global main   ; 


main:
 ;create stack frame
 push ebp
 mov ebp, esp

;if( x > y) {
 ; msg1
 ;} else{
 ; msg2
 ;}

 mov eax, DWORD [x]
 mov ebx, DWORD [y]

 cmp eax, ebx ; cmp x, y
 jg .xGreatThany
 push DWORD msg2
 call printf
 jmp .done
.xGreatThany:
 push DWORD msg1
 call printf
 jmp .done

.done:

 ;destory the stack frame
 mov esp, ebp
 pop ebp
 ret

asm integer 자료형

apt-get install gcc-multilib

자료형
db 8bit                                     8bit
dw 8bit,8bit                                16bit
dd 8bit,8bit 8bit,bit                       32bit
dd 8bit,8bit,8bit,8bit 8bit,8bit,8bit,8bit  64bit

example asm2.asm
SECTION .data

msg: db "Hello world, this is assembly",10,0
msgLen: equ $-msg
fmt: db "Msg length = %d",10,0

i: dd 120
fmt2: db "Value of myInteger is %d",10,0

SECTION .text

extern printf
global main

main:
 push ebp
 mov ebp, esp

 push msg
 call printf

 ;printf(format,msgLen)
 push DWORD msgLen
 push fmt
 call printf

 ;printf(format,balue)
 push DWORD i
 push fmt2
 call printf

 mov esp, ebp
 pop ebp
 ret

compile :
compile.sh

#!/bin/bash

numArg=$#
clear
if [ $numArg != 2 ] ; then
echo "You enter too many or too little arguments to script when expected 2, asm file"
echo "you supplied only $numArg"
echo "Usage: compile <input.asm> <program_name>"
exit
else
echo "Compiling asm using NASM"
input=$1
output=$2
inter=asm000.o
nasm -f elf32 -o $inter $input
ret=$?
if [ $ret != 0 ] ; then
echo "Nasm compilation failed"
    exit
else
echo "compilation using GCC for final output"
gcc -m32 -o $output $inter
ret=$?
if [ $ret != 0 ] ; then
echo "There was a problem with gcc compilation"
exit
else
rm $inter
echo "Compilation successfull"
fi
fi
fi

./compile.sh asm2.asm asm2

asm 스택(함수 내부 구조)

스택 (함수 내부)
스택 이해 - 스택 구조
스택 관계 레지스트
EBP: 스택 베이스 주소를 가리키는 레지스터
DSP: 스택 최상단 주소를 가리키는 레지스터
EIP: 다음 실행할 명령어를 가리키는 레지스터(함수 종료시 RET Address 추가)

100 <--- High Memory(100)
...
...
...
...
050 Ret Address
051 EBP <---EBP
...
...
...
000 <--- Low Memory(0) == ESP

Add(4,8) 동작.
100 <--- High Memory(100)
...
...
... 8 int b == mov eax,DWORD PTR[ebp+0xc]
... 4 int a == mov eax,DWORD PTR[ebp+0x8]
050 Ret Address
051 EBP <---EBP 함수호출 Add(4,8)
... 값 대입 0xc = int c; == mov eax,DWORD PTR[ebp-0x4]
...
...
000 <--- Low Memory(0) == ESP

Add(4,8) // 함수 호출 시 스택 메모리 위치에 변수 값 대입
int add(int a, int b){
    int c;
    c=a+b;
    return c
}

In Assembly
push ebp
mov ebp, esp
sub esp 0x10

mov eax, DWORD PTR [ebp+oxC];12
mov edx, DWORD PTR [ebp+0x8];8
lea eax,[ebx+eax*1]
mov DWORD PTR[ebp-0x4),eax
mov eax, DWORD PTR [ebp-0x-4]

leave
ret

asm
vi asm1.c
#include <stdio.h>
int main(){
    return oxff;
}

Compile:
gcc -o asm1 asm1.c

objdump -d -o -M intel asm1
검색 main
메모리 구조 확인.

asm printf 메세지 출력

SECTION .data ;초기화된 자료형
SECTION .text ;asm 소스 코드
SECTION .bss  ; 초기화 하지 않은 자료형, 단 0으로 초기화된 변수는 이 위치에 지정됨.

msg; db "Hello world, this is assembly", 10, 0 ;사용할 메세지

;printf
SECTION .text  ;asm 소스 코드

global main
main:
    push ebp
    mov ebp, esp

    push msg
    call prinf

    mov esp, ebp
    pop ebp
    ret

; 사용자 언어 사용 가능 void main(){ }


example 
SECTION .data

msg: db "Hello world, this is assembly", 10, 0 ;출력 메세지

SECTION .text    ; asm code

extern printf
global main

main:
 push ebp
 mov ebp, esp

 push msg
 call printf

 mov esp, ebp
 pop ebp
 ret

compile
nasm -f elf -o asm1.o asm1.asm

CPP Floating_type 실수 연산

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
// 실수 연산는 컴퓨터 연산시 오차를 가진다.
// 오차를 최소화 하기 위해 실수 연산을 사용한다.

float fValue = 76.4;

cout << fValue << endl;

cout << "size of fValue " << sizeof(float) << endl;
cout << scientific << fValue << endl; // 지수 표현
cout << fixed << fValue << endl; // 부동 소수점 기본 6자리수 표시
cout << setprecision(20) << fixed << fValue << endl; // 부동 소수점 20 자리 지정

// 실수 연산는 컴퓨터 연산시 오차를 가진다. 검증
double dValue = 76.4;
cout << setprecision(20) << fixed << dValue << endl; // 부동 소수점 20 자리 지정

// 실수 연산는 컴퓨터 연산시 오차를 가진다. 검증
long double lValue = 123.456789876543210;
cout << setprecision(20) << fixed << lValue << endl;
cout << "size of long double " << sizeof(lValue) << endl;

return 0;
}

CPP Integer 정수 표현

#include <iostream>
#include <limits>
using namespace std;

int main() {
int value = 55555;
cout << value << endl;

// 구글 검색 limits.h 표현 가능한 표 확인 가능cout << "Max int value "<< INT8_MAX << endl;
cout << "8bit  Max int value "<< INT8_MAX << endl;
cout << "8bit  Min int value "<< INT8_MIN << endl;
cout << "16bit Max int value "<< INT16_MAX << endl;
cout << "16bit Min int value "<< INT16_MIN << endl;
cout << "32bit Max int value "<< INT32_MAX << endl;
cout << "32bit Min int value "<< INT32_MIN << endl;
cout << "64bit Max int value "<< INT64_MAX << endl;
cout << "64bit Min int value "<< INT64_MIN << endl;

long int lValue = 9223372036854775807;
cout << lValue << " Max range" << endl;

    short int sValue = 32767;
    cout << sValue << " Max range" << endl;

    cout << "Size of int: " << sizeof(int) << "Byte" << endl;
    cout << "Size of shot: " << sizeof(short) << "Byte" << endl;
    cout << "Size of shot: " << sizeof(short int) << "Byte" << endl;

    unsigned int uValue = 2147483649;
    cout << uValue << endl;

return 0;
}

CPP Input 기본 입력

#include <iostream>
using namespace std;

int main() {
cout << "Enter your name: " << flush;
string input;
cin >> input;
cout << "You entered: " << input << endl;

cout << "Enter a number:" << flush;
int value;
cin >> value;
cout << "You entered: " << value << endl;
return 0;
}

CPP 문자열

#include <iostream>
using namespace std;

int main() {
string text1 = "Hello this is a string ";
string text2 = "fred";

string text3 = text1 + text2;

cout << text1 << endl;
cout << text2 << endl;

cout << text1 << text2 << endl;

cout << text3 << endl;

return 0;
}

CPP Variables 변수...

#include <iostream>
using namespace std;

int main() {
int numberCats = 5;
int numberDogs = 7;
int numberAnimails = numberCats + numberDogs;

cout << "Hello" << endl;
cout << "Number of cats: " << numberCats << endl;
cout << "Number of dogs: " << numberDogs << endl;

cout << "Total number of animals: " << numberCats + numberDogs << endl;
cout << "Total number of animals_1: " << numberAnimails << endl;

cout << "New dog acquired!" << endl;

numberDogs = numberDogs + 1;
cout << "New number of dogs: " << numberDogs << endl;

return 0;
}