이번에도 환경변수를 사용하면 되는데, 이번엔 argv가 아닌 stdin으로 입력받는다.


전과 같은 방식으로 공격하되 파이프를 이용해 이렇게 넘겨주면 클리어된다.

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : wolfman > darkelf  (0) 2015.10.13
LOB Redhat : orc > wolfman  (0) 2015.10.13
LOB Redhat : goblin > orc  (0) 2015.10.13
LOB Redhat : gremlin > cobolt  (0) 2015.10.13
LOB Redhat : gate > gremlin  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,



버퍼의 크기가 상당히 작아졌다.

환경변수를 이용하여 공격하기로 했다.

환경변수의 주소를 출력해주는 파일을 만들고, export 명령을 사용해 환경변수에 NOP+SHELL을 올린 후

해당 주소를 찾아내어 RET을 덮어씌워주었다.


클리어.

'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : wolfman > darkelf  (0) 2015.10.13
LOB Redhat : orc > wolfman  (0) 2015.10.13
LOB Redhat : goblin > orc  (0) 2015.10.13
LOB Redhat : cobolt > goblin  (0) 2015.10.13
LOB Redhat : gate > gremlin  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

꽤나 전에 다 풀었던 문제들이지만 복습할 겸 다시 풀어보기로 했다.


그냥 간단한 BOF 문제.

버퍼의 크기는 0x100이며, 카나리도 없다.


원본 파일은 동적 디버깅이 불가능하도록 되어 있었으므로 파일을 복사하여 버퍼 스택 주소를 알아냈다.


거기에 쉘코드를 집어넣고 실행하면 클리어.


'Wargame > Lord of Buffer overflow' 카테고리의 다른 글

LOB Redhat : wolfman > darkelf  (0) 2015.10.13
LOB Redhat : orc > wolfman  (0) 2015.10.13
LOB Redhat : goblin > orc  (0) 2015.10.13
LOB Redhat : cobolt > goblin  (0) 2015.10.13
LOB Redhat : gremlin > cobolt  (0) 2015.10.13
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

main에서부터 명령어를 하나하나 보면서 스택과 레지스터에 들어있는 값이 어떻게 변환되고, 프로그램이 어떻게 작동하는지를 하나하나 파악해 보도록 하겠다. 하나하나라고는 하지만 정말 완전히 한 명령어씩만 하지는 않고, 연관성이 있는 명령어들은 묶어서 설명한다.


프로그램 소스는 매우 간단하다. 조금만 프로그래밍을 해본 사람이라면 한 번쯤은 짜봤을 법한 소스이다.

<소스>

#include <stdio.h>

int main()
{
	int i;
	int sum = 0;
	for(i=1; i<=100; i++) sum+=i;
	printf("sum : %d\n", sum);
	return 0;
}


필자는 컴파일과 분석을 우분투 14.04 64bit 버전에서 수행했다.

64비트 환경이므로 32비트로 컴파일하고 분석하기 위하여 컴파일시 뒤에 -m32 를 붙여주자.

또한 분석을 용이하게 하기 위해 뒤에 -mpreferred-stack-boundary=2 도 붙여주도록 하자.


여기까지 했으면 간단한 분석의 준비가 끝났다.

바로 GDB를 이용해 하나하나 분석해 보도록 하자.


gdb를 실행할 때 뒤에 붙인 -q 옵션은 gdb 실행 시 나타나는 긴 버전 및 도움말 등을 스킵하는 옵션이다.

disas main 명령어를 쳐서 메인을 보면 위와 같이 AT&T 문법으로 나타나는 메인의 어셈블리어들을 볼 수 있다.

혹시나 리버싱을 먼저 했거나, Intel의 문법이 더 익숙한 사람들은 ' set disassembly-flavor intel ' 명령을 이용하여 문법의 변경이 가능하다.

우선 ' b *main '으로 main의 첫 부분에 BreakPoint를 걸고 실행시켜 main에서 멈추게 한 뒤 ' info reg '로 레지스터들의 초기값들을 확인해보자.

eax, ecx, edx, ebx는 지금 당장 눈여겨 볼 필요는 없고, 현재 ebp 값이 0이라는 점을 보고 넘어가자.


이제 한줄씩 실행해 가며 분석을 시작할 텐데, 한 번 할때마다 계속 값을 확인하기는 귀찮으므로 display 명령을 이용하여 자동으로 값이 출력되도록 설정하도록 하겠다. 봐야 하는 것은 다음에 실행할 명령어들 일부와 main에서 사용되는 레지스터들의 값이다.

main에서 실질적으로 사용하는 범용 레지스터는 eax밖에 없으므로 esp, ebp, eax 및 esp을 기준으로 스택에서 0x20바이트, eip를 기준으로 명령어 5개를 display하겠다.

이제 si나 ni 등으로 한 명령어씩 수행할 때마다, 혹은 BP에 걸릴 때마다 display된 값들을 자동으로 출력해 준다.


ni를 이용하여 명령을 수행하자.

우선 push %ebp와 mov %esp, %ebp이다.

mov    %ebp와 mov    %esp, %ebp라는 명령이었다.

이 명령을 통해 esp에 +4를 한 후 ebp값이 esp에 저장되고, esp의 값이 ebp에 들어갔으므로, 둘은 0xffffd128이라는 같은 주소를 가리키게 되었다.


다음 명령이다.

sub    $0x10, %esp 이라는 명령이었다.

esp에서 0x10만큼 뺀다는 것인데, 스택은 주소상 위에서 아래로 자라므로 스택에 0x10 bytes만큼을 할당했다고 볼 수 있다. 0xffffd128을 가리키던 esp가 0xffffd118을 가리키게 되었다.

다음 명령이다.

movl    $0x0, -0x4(%ebp) 라는 명령이었다.

ebp-0x4가 가리키는 위치에 0을 넣는다는 뜻인데, 

변한 게 없는 것 같지만 이미 0x00000000이라는 값을 가진 위치가 0x0으로 바뀐 것이기 때문에 변화가 없는 게 당연하다. 지역변수에 0을 할당하였다.

다음 명령이다.

mov    $0x01, -0x8(%ebp) 였다.

지역변수2에 1이라는 값을 할당하였다.

메모리상 ebp-0x8 위치가 1로 바뀐 것을 확인할 수 있다.

다음 명령이다.

jmp    0x804843d 라는 명령.

아래로 점프하였다.

eip의 값이 0x804843d로 변경되었다.

다음 명령이다.


이번에는 연관이 있는 명령이라 한번에 두 개의 명령을 동시에 수행했다.

cmpl $0x64, -0x8(%ebp) 였는데, 이후 jle 0x8048433 명령이 수행되었다.

이는 $0x64라는 값과 ebp-0x8에 들어 있는 값을 비교하여 *(ebp-0x8)이 같거나 작을 경우 지정한 주소로 점프하는 명령어이다.

반복문의 시작점이라고 볼 수 있겠다.

연재 ebp-0x8에는 1이 들어 있고, 이는 아마도 반복문의 카운터가 되는 값이다.

계속하자.


두 개의 명령을 한번에 실행했다.

mov    -0x8(%ebp), %eax  와  add    %eax, -0x4(%ebp) 이었다.

eax에 -0x8(%ebp)를 집어넣는데, 이는 아까 가져온 카운터 값이다. 그리고 처음에 0으로 초기화한 -0x4(%ebp)에 집어넣는다. 아마 이 부분이 sum 변수일 것으로 생각된다.

다음 명령이다.


addl $0x1, -0x8(%ebp) 이었다.

카운터라고 추측했던 -0x8(%ebp)에 상수 1을 더한다.

그리고 cmpl과 jle 문을 지나면서 반복문을 계속한다.

-0x8(%ebp)가 0x64보다 작거나 같을 때까지 반복하는 반복문이므로 C언어로 표현하면

for(i=1; i<=100; i++) sum += i;

이런 구문이라고 볼 수 있겠다.

반복문 다음의 mov, 즉 main+38에 BP를 걸고 c로 계속 진행시키자.


-0x8(%ebp)의 위치에는 0x65가 들어가 반복문을 빠져나온 직후이며, 결과인 sum은 0x13ba라는 값인 것을 알 수 있다.

다음은 함수의 인자를 지정해 주는 단계이다. 계속하자.


-0x4(%ebp)에 들어 있는 결과값을 eax에 집어넣고, 이를 또 0x4(%esp)에 넣는다.

마지막으로 문자열의 주소가 저장되어 있을 것으로 예상되는 0x80484f0이라는 주소를 (esp)에 넣는다.

보통 함수의 인자를 넣을 때 인자를 거꾸로 넣으며 push를 이용해 스택에 넣어준다고 알고 있는 사람이 많은데,

이렇게 esp를 미리 함수 인자만큼 할당 후 (esp)에 첫번째 인자, (esp+4)에 두번째 인자 등으로 넣어 주어도 관계는 없다.

어차피 push reg 라는 명령이 { sub    $0x04, %esp  /   mov    reg, (%esp) } 와 같은 의미이기 때문이다.

이제 call 명령을 수행한다.


명령을 수행하자마자 " sum : 5050 " 이라는 문자열이 커맨드라인에 출력되었다.

첫 번째 인자로 들어갔던 0x80484f0의 주소에 들어 있는 값을 확인하니 "sum : %d\n"라는 문자열임을 확인할 수 있다.

다음으로 return 0을 수행하기 위해 %eax에 0을 넣는다.


이제 마지막으로 남은 것은 함수를 끝내는 함수 에필로그 뿐이다.

이 부분은 조금 자세히 보자.


leave 명령을 수행한 직후의 모습이다.

leave는 저장해 두었던 main 이전 함수의 %ebp, 즉 SFP(Saved Frame Pointer)를 원래대로 되돌리는 명령이다.

이 명령은 { mov %ebp, %esp  /  pop %ebp } 로 이루어져 있다.

%ebp의 값을 %esp에 넣게 되므로 %esp와 %ebp는 같은 위치를 가리키게 되고, %ebp는 main 함수의 프롤로그에서 { push %ebp  /  mov %esp, %ebp } 를 한 후 고정되어 있었으므로 당연히 SFP를 가리키고 있다.

pop 명령은 %esp를 기준으로 진행되는 명령이므로 pop %ebp를 하게 되면 SFP가 ebp로 들어가고, 이렇게 원래의 ebp가 복원되었다.

위 이미지에서 가장 처음에 ebp가 갖고 있던 초기값인 0x0이 복원된 것을 볼 수 있다.

다음으로 ret 명령이다.


leave 명령이 %ebp를 복원하는 명령이었다고 한다면, ret 명령은 %eip를 원래 있어야 할 장소로 돌려보내는 명령이다.

call로 함수를 수행하게 되면 자동으로 RET을 스택에 push 하는데, 이는 이 함수 이후 수행할 명령어가 저장된 주소이다.

예를 들어 이 프로그램에서라고 하면 call printf로 함수를 수행한 뒤에도 eip는 return 0을 수행하기 위해 그 다음의 주소로 정상적으로 돌아왔다.

실제 함수의 주소는 main이 아닌 libc에 있기 때문에 %eip가 달라져 다른 주소로 점프하게 되는데, 점프하기 전에 다시 돌아오기 위해 스택에 값을 저장해 두는 것이다.

ret 명령은 { pop %eip  /  jmp %eip } 이다. 원래 %eip는 mov나 pop 같은 명령어로는 변조가 불가능한 매우 중요한 레지스터이기 때문에 뒤에 jmp %eip를 통해 정당성을 확보해 준 것이다.

esp는 leave 명령을 수행한 이후 pop 때문에 SFP+4의 위치를 가리키고 있는데, 여기에서 pop을 하게 되면 SFP 직전에 저장된 RET가 eip에 들어가게 되어 eip가 정상적으로 복구되는 것이다.

RET가 스택에 저장된다는 취약점을 이용하여 버퍼 오버플로우 등을 이용해 이 부분을 원하는 값으로 덮어씌우면 원하는 주소의 명령을 수행하게 할 수 있다.





블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,





Write-up은 아니지만 여기에 올리도록 하겠습니다.

이번 대회에는 포렌식을 기본으로 한 10문제가 나왔는데,  그중 두 문제를 풀고 전체 21위를 하였습니다.

획득 점수 40%, 보고서 60% 로 합산하여 본선 진출이 결정되지만 어차피 2000점대로는 아무리 보고서를 잘 써도

(솔직히 보고서 잘 쓰려면 분석도, 즉 문제도 잘 풀어야 하기 때문에)

본선은 나갈 수 없을 것 같아 보고서는 따로 작성하지 않았습니다.


나중에 가능하다면 푼 문제의 Write-up을 작성하여 올리도록 하겠습니다.

여전히 내 실력은 바닥을 기고 있다는 것을 알려 주는 결과였습니다.

더 공부해야지...

'CTF > Write-up' 카테고리의 다른 글

Codegate 2016 Junior Prequal Write-up  (0) 2016.03.19
제 13회 해킹캠프 CTF Write-up  (0) 2016.02.28
2015 Dimicon Prequal/Qual Write-up  (0) 2015.11.15
제 12회 해킹캠프 CTF Write-up  (0) 2015.09.20
2015 inc0gnito CTF Write-up  (0) 2015.09.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

레지스터 (Register)

Knowledge 2015. 10. 12. 10:34

레지스터(Register)

 

레지스터란 CPU에서 사용하는 일시적인 소형 저장메모리이다. CPU에서 사용하는 메모리 중 가장 작고 빠른 메모리라고 볼 수 있다. 사실 레지스터의 종류는 수백가지가 있지만 시스템 해킹이나 간단한 어셈블리 코딩을 하기 위해서는 그 중에서 가장 중요하고 대표적인 9가지의 레지스터만을 알아도 상관없다.

 

우선 레지스터는 32비트 기준으로 EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP, EIP가 존재한다.

원래 이들은 16비트 기준으로 AX, BX, CX, DX… 등이었으나 사용하는 메모리의 크기가 커지면서 레지스터의 크기도 커져 앞에 Extended 라는 접두어가 붙으면서 크기가 16비트에서 32비트로 확장되었다. 이름이 마치 A, B, C ,D 순서대로 붙여진 것 같지만 사실 그렇지 않고, 모두 그 의미를 가지고 있다. 다음이 그 내용이다.


범용 레지스터

- EAX (Extended Accumulator Register) : 함수의 리턴 값이나 연산 결과가 담긴다.

- EBX (Extended Base Register) : 배열의 주소가 저장되고 이를 참조하는 데 사용한다.

- ECX (Extended Count Register) : 루프문에서 카운트를 세는 데 사용한다.

- EDX (Extended Data Register) : EAX의 보조 레지스터로 특수한 경우에 EDX-EAX 순서로 붙여서 임시 8바이트 레지스터로 사용한다.


인덱스 레지스터

- ESI (Extended Source Index) : 데이터 이동 시 원본 데이터의 주소를 담당한다.

- EDI (Extended Destination Index) : 데이터 이동 시 저장될 주소를 담당한다.


포인터 레지스터

- ESP (Extended Stack Pointer) : 현재 스택 프레임의 끝 주소를 담는다.

- EBP (Extended Base Pointer) : 현재 스택 프레임의 기준이 되는 주소를 담는다.

- EIP (Extended Instruction Pointer) : 수행할 명령어의 주소를 담는다.

 

이렇게 역할을 구분해놓긴 했지만 사실 EIP를 제외한(가급적 ESP, EBP 또한) 레지스터들은 범용적으로 사용해도 상관이 없다. 함수 리턴 값을 EAX가 아니라 EBX에 담아도 상관은 없다는 뜻이다. 하지만 나중에 이미 만들어진 코드를 읽고 이해하기 편하게 하기 위해서는 만들어진 목적 그대로 사용하는 편이 좋다. 

또한, 레지스터는 32비트 CPU를 기준으로 32비트 크기를 갖고 있다. 그런데 이는 16비트나 8비트 단위로 데이터를 다루기 힘들기 때문에 또 레지스터를 나눠 둔 단위들이 있다. 이는 다음 그림을 보면 이해할 수 있다.



보다시피 EAX의 크기는 0~31까지 총 32비트이다.

16비트 CPU 환경에서 사용하던 AX는 전과 마찬가지로 EAX의 절반인 하위 16비트이며, 여기서 또 절반을 나누어 상위 8비트를 AH, 하위 8바이트를 AL로 설정해 두었다. EAX의 상위 16바이트는 딱히 이름을 지정해두지 않았으므로 이 부분만을 바로 참조하는 것은 불가능하다.

이는 다른 레지스터에도 똑같이 적용된다.

EBXBX, BH, BL이며 ECXCX, CH, CL인 것 처럼.

하지만 ESIEDI는 조금 다른데, 이 둘은 8비트짜리 레지스터로 참조할 때 SIH, SIL, DIH, DIL로 사용한다.

이와 같은 하위 비트들을 어셈블리어에서 사용할 때에는, 특히 하위 비트가 Source일 때 주의해야 하는데,

MOV %EAX, %AL 의 형식으로 사용할 경우 4바이트의 데이터를 1바이트짜리에 집어넣는 상황이 되어버리기 때문에 컴파일이 되지 않는다. AT&T 기준으로 MOVB 명령을 사용하거나 intel 기준으로 BYTE PTR 등으로 크기를 정확히 명시해주어야 한다.

'Knowledge' 카테고리의 다른 글

libcapstone-dev 설치 방법  (0) 2016.03.12
PE 파일과 Memory-Mapped File  (0) 2015.12.24
Wireshark로 인증서 추출하기  (0) 2015.11.02
제한적 ASLR 해제 방법  (0) 2015.10.22
RTL Chaining의 원리  (0) 2015.10.18
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

오늘 짠 어셈블리의 끝판왕.

생각보다 atoi를 어셈블리로 짜려고 하니까 여간 힘든게 아니다.

프로그래밍을 하면서 알고리즘이나 자료구조 등을 제대로 공부하지 않아서인지는 모르지만 더 좋은 길도 잘 떠오르지 않았고...

결국 엄청 더러우면서도 작동은 하는 소스가 만들어졌다.

해당 프로그램은 stdin으로 숫자를 입력받아 해당 수만큼 반복하여 "Hello World"를 puts해주는 기능을 가졌다.

만약 숫자가 아닌 값을 입력하면 "It is Not Number!"를 출력하고 종료된다.

많이 조잡하지만 만들고 나니 뿌듯하긴 하다.


.globl main
main:
	push %ebp
	mov %esp, %ebp
	sub $0x04, %esp
	lea -0x04(%ebp), %ecx
	push %ecx
	call gets
	lea -0x04(%ebp), %eax
	push %eax
	call atoi
	mov %eax, %esi
	xor %edi, %edi
	.main_loop:
		cmp %edi, %esi
		jle .main_finish
		push $helloworld
		call puts
		inc %edi
		jmp .main_loop
	.main_finish:
		leave
		ret

atoi:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %esi
	push %esi
	call isNumberStr
	cmp $0x00, %eax
	jle .atoi_notNumber
	mov 0x08(%ebp), %esi
	push %esi
	call strlen
	mov %eax, %edi
	xor %eax, %eax
	mov 0x08(%ebp), %esi
	xor %ecx, %ecx
	xor %edx, %edx
	.atoi_loop:
		xor %ebx, %ebx
		movb (%esi), %bl
		cmpb $0x00, %bl
		je .atoi_finish
		cmp $0x00, %edi
		je .atoi_finish
		sub $0x30, %bl
		mov %edi, %ecx
		.atoi_loop2:
			cmp $0x01, %ecx
			je .atoi_add
			imul $0x0a, %ebx
			dec %ecx
			jmp .atoi_loop2
			.atoi_add:
				add %ebx, %eax
				inc %esi
				dec %edi
				jmp .atoi_loop
	.atoi_notNumber:
		push $notNumber
		call puts
		mov $-0x01, %eax
		jmp .atoi_finish
	.atoi_finish:
		leave
		ret


gets:
	push %ebp
	mov %esp, %ebp
	sub $0x1000, %esp
	mov $0x03, %eax
	mov $0x00, %ebx
	lea -0x1000(%ebp), %ecx
	mov $0x1000, %edx
	int $0x80
	lea -0x1000(%ebp), %eax
	push $0x0a
	push %eax
	call strchr
	movb $0x00, (%eax)
	lea -0x1000(%ebp), %eax
	push %eax
	mov 0x08(%ebp), %eax
	push %eax
	call strcpy
	leave
	ret

isAlpha:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	movb %al, %bl
	cmpb $0x41, %al
	jl .isAlpha_notalpha
	cmpb $0x5a, %al
	jng .isAlpha_alpha
	cmpb $0x61, %al
	jl .isAlpha_notalpha
	cmpb $0x7a, %al
	jng .isAlpha_alpha
	jmp .isAlpha_notalpha
	.isAlpha_alpha:
		mov $0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_notalpha:
		mov $-0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_finish:
		leave
		ret

isNumber:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	cmpb $0x30, %al
	jl .isNumber_notnumber
	cmpb $0x39, %al
	jng .isNumber_number
	jmp .isNumber_notnumber
	.isNumber_number:
		mov $0x01, %eax
		jmp .isNumber_finish
	.isNumber_notnumber:
		mov $-0x01, %eax
		jmp .isNumber_finish
	.isNumber_finish:
		leave
		ret

isAlphaStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
	mov 0x08(%ebp), %esi
	.isAlphaStr_loop:
		movb (%esi), %bl
		and $0xff, %ebx
		cmpb $0x00, %bl
		je .isAlphaStr_Alpha
		push %ebx
		call isAlpha
		cmpb $0x00, %al
		jl .isAlphaStr_notAlpha
		inc %esi
		jmp .isAlphaStr_loop
	.isAlphaStr_Alpha:
		mov $0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_notAlpha:
		mov $-0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_finish:
		leave
		ret

isNumberStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
        mov 0x08(%ebp), %esi
        .isNumberStr_loop:
                movb (%esi), %bl
                and $0xff, %ebx
                cmpb $0x00, %bl
                je .isNumberStr_Number
                push %ebx
                call isNumber
                cmpb $0x00, %al
                jl .isNumberStr_notNumber
                inc %esi
                jmp .isNumberStr_loop
        .isNumberStr_Number:
                mov $0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_notNumber:
                mov $-0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_finish:
                leave
                ret
	leave
	ret

puts:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	push %eax
	call strlen
	mov %eax, %edx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov 0x08(%ebp), %ecx
	int $0x80
	push $0x0a
	lea (%esp), %ecx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov $0x01, %edx
	int $0x80
	add $0x04, %esp
	leave
	ret

strcpy:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	mov 0x08(%ebp), %edi
	mov 0x0c(%ebp), %esi
	.strcpy_loop:
		movb (%esi), %al
		movb %al, (%edi)
		cmpb $0x00, %al
		je .strcpy_finish
		inc %esi
                inc %edi
		jmp .strcpy_loop
	.strcpy_finish:
		leave
		ret


strlen:
	push %ebp
	mov %esp, %ebp
	xor %ecx, %ecx
	mov 0x08(%ebp), %eax
	.strlen_loop:
		movb (%eax), %bl
		cmpb $0x00, %bl
		je .strlen_finish
		inc %eax
		inc %ecx
		jmp .strlen_loop
	.strlen_finish:
		mov %ecx, %eax
		leave
		ret

notNumber : .string "It is Not Number!"
helloworld : .string "Hello, World"


'Programming' 카테고리의 다른 글

파이썬 웹 이미지 크롤러 (GUI)  (0) 2016.02.03
[C++] 가상함수(Virtual Function)  (0) 2016.01.20
Assembly Programming - isAlpha, isNumber  (0) 2015.10.11
Assembly Programming - gets  (0) 2015.10.10
Assembly Programming - strchr  (0) 2015.10.10
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

요즘 어셈블리로 코딩하는 것에 재미가 들려서 그런지 계속 이런걸 만들고 있다.

어셈블리어로 printf 만드는게 그렇게 어렵다고 하길래 한번 짜보기 위해 그 기반이 될 모듈들을 만들고 있다.

아마도 포맷스트링을 처리해야 하므로 atoi는 기본으로 필요할 것 같다.

그를 위한 isAlpha와 isNumber이다.

전에 짰던 함수들도 좀 포함되어있지만 무시하도록 하자.


.globl main
main:
	push %ebp
	mov %esp, %ebp
	push $alpha
	call isNumberStr
	leave
	ret


isAlpha:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	movb %al, %bl
	cmpb $0x41, %al
	jl .isAlpha_notalpha
	cmpb $0x5a, %al
	jng .isAlpha_alpha
	cmpb $0x61, %al
	jl .isAlpha_notalpha
	cmpb $0x7a, %al
	jng .isAlpha_alpha
	jmp .isAlpha_notalpha
	.isAlpha_alpha:
		mov $0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_notalpha:
		mov $-0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_finish:
		leave
		ret

isNumber:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	cmpb $0x30, %al
	jl .isNumber_notnumber
	cmpb $0x39, %al
	jng .isNumber_number
	jmp .isNumber_notnumber
	.isNumber_number:
		mov $0x01, %eax
		jmp .isNumber_finish
	.isNumber_notnumber:
		mov $-0x01, %eax
		jmp .isNumber_finish
	.isNumber_finish:
		leave
		ret

isAlphaStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
	mov 0x08(%ebp), %esi
	.isAlphaStr_loop:
		movb (%esi), %bl
		and $0xff, %ebx
		cmpb $0x00, %bl
		je .isAlphaStr_Alpha
		push %ebx
		call isAlpha
		cmpb $0x00, %al
		jl .isAlphaStr_notAlpha
		inc %esi
		jmp .isAlphaStr_loop
	.isAlphaStr_Alpha:
		mov $0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_notAlpha:
		mov $-0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_finish:
		leave
		ret

isNumberStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
        mov 0x08(%ebp), %esi
        .isNumberStr_loop:
                movb (%esi), %bl
                and $0xff, %ebx
                cmpb $0x00, %bl
                je .isNumberStr_Number
                push %ebx
                call isNumber
                cmpb $0x00, %al
                jl .isNumberStr_notNumber
                inc %esi
                jmp .isNumberStr_loop
        .isNumberStr_Number:
                mov $0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_notNumber:
                mov $-0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_finish:
                leave
                ret
	leave
	ret

puts:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	push %eax
	call strlen
	mov %eax, %edx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov 0x08(%ebp), %ecx
	int $0x80
	push $0x0a
	lea (%esp), %ecx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov $0x01, %edx
	int $0x80
	add $0x04, %esp
	leave
	ret

strcpy:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	mov 0x08(%ebp), %edi
	mov 0x0c(%ebp), %esi
	.strcpy_loop:
		movb (%esi), %al
		movb %al, (%edi)
		cmpb $0x00, %al
		je .strcpy_finish
		inc %esi
                inc %edi
		jmp .strcpy_loop
	.strcpy_finish:
		leave
		ret


strlen:
	push %ebp
	mov %esp, %ebp
	xor %ecx, %ecx
	mov 0x08(%ebp), %eax
	.strlen_loop:
		movb (%eax), %bl
		cmpb $0x00, %bl
		je .strlen_finish
		inc %eax
		inc %ecx
		jmp .strlen_loop
	.strlen_finish:
		mov %ecx, %eax
		leave
		ret

alpha : .string "12345678a0"
helloworld : .string "Hello, World"


'Programming' 카테고리의 다른 글

[C++] 가상함수(Virtual Function)  (0) 2016.01.20
Assembly Programming - atoi  (0) 2015.10.11
Assembly Programming - gets  (0) 2015.10.10
Assembly Programming - strchr  (0) 2015.10.10
Assembly Programming - puts  (0) 2015.10.10
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

이번주 구현 목표였던 gets.

만들면 날려먹고 만들면 또 날려먹어서 고생좀 했다.



.globl main
main:
	push %ebp
	mov %esp, %ebp
	sub $0x1000, %esp
	lea -0x1000(%ebp), %eax
	push %eax
	call gets
	lea -0x1000(%ebp), %eax
	push %eax
	call puts
	leave
	ret

gets:
	push %ebp
	mov %esp, %ebp
	sub $0x1000, %esp
	mov $0x03, %eax
	mov $0x00, %ebx
	lea -0x1000(%ebp), %ecx
	mov $0x1000, %edx
	int $0x80
	lea -0x1000(%ebp), %eax
	push $0x0a
	push %eax
	call strchr
	movb $0x00, (%eax)
	lea -0x1000(%ebp), %eax
	push %eax
	mov 0x08(%ebp), %eax
	push %eax
	call strcpy
	leave
	ret

strchr:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	movb 0x0c(%ebp), %bl
	.strchr_loop:
		cmpb (%eax), %bl
		je .strchr_finish
		cmpb $0x00, (%eax)
		je .strchr_notfound
		inc %eax
		jmp .strchr_loop
	.strchr_notfound:
		mov $0x01, %eax
	.strchr_finish:
		leave
		ret


puts:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	push %eax
	call strlen
	mov %eax, %edx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov 0x08(%ebp), %ecx
	int $0x80
	push $0x0a
	lea (%esp), %ecx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov $0x01, %edx
	int $0x80
	add $0x04, %esp
	leave
	ret

strcpy:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	mov 0x08(%ebp), %edi
	mov 0x0c(%ebp), %esi
	.strcpy_loop:
		movb (%esi), %al
		movb %al, (%edi)
		cmpb $0x00, %al
		je .strcpy_finish
		inc %esi
                inc %edi
		jmp .strcpy_loop
	.strcpy_finish:
		leave
		ret


strlen:
	push %ebp
	mov %esp, %ebp
	xor %ecx, %ecx
	mov 0x08(%ebp), %eax
	.strlen_loop:
		movb (%eax), %bl
		cmpb $0x00, %bl
		je .strlen_finish
		inc %eax
		inc %ecx
		jmp .strlen_loop
	.strlen_finish:
		mov %ecx, %eax
		leave
		ret

'Programming' 카테고리의 다른 글

Assembly Programming - atoi  (0) 2015.10.11
Assembly Programming - isAlpha, isNumber  (0) 2015.10.11
Assembly Programming - strchr  (0) 2015.10.10
Assembly Programming - puts  (0) 2015.10.10
Assembly Programming - strcpy  (0) 2015.10.10
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

gets 함수를 만들기 전 '\n'의 위치 등을 찾아주는 strchr 함수를 구현하는 것이 편할 것 같아 구현하였다.


.globl main
main:
	push %ebp
	mov %esp, %ebp
	push $0x65
	push $helloworld
	call strchr
	push %eax
	call puts
	leave
	ret

strchr:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	movb 0x0c(%ebp), %bl
	.strchr_loop:
		cmpb (%eax), %bl
		je .strchr_finish
		cmpb $0x00, (%eax)
		je .strchr_notfound
		inc %eax
		jmp .strchr_loop
	.strchr_notfound:
		mov $0x01, %eax
	.strchr_finish:
		leave
		ret


puts:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	push %eax
	call strlen
	mov %eax, %edx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov 0x08(%ebp), %ecx
	int $0x80
	push $0x0a
	lea (%esp), %ecx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov $0x01, %edx
	int $0x80
	add $0x04, %esp
	leave
	ret

strcpy:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	mov 0x08(%ebp), %edi
	mov 0x0c(%ebp), %esi
	.strcpy_loop:
		movb (%esi), %al
		movb %al, (%edi)
		cmpb $0x00, %al
		je .strcpy_finish
		inc %esi
                inc %edi
		jmp .strcpy_loop
	.strcpy_finish:
		leave
		ret


strlen:
	push %ebp
	mov %esp, %ebp
	xor %ecx, %ecx
	mov 0x08(%ebp), %eax
	.strlen_loop:
		movb (%eax), %bl
		cmpb $0x00, %bl
		je .strlen_finish
		inc %eax
		inc %ecx
		jmp .strlen_loop
	.strlen_finish:
		mov %ecx, %eax
		leave
		ret


helloworld : .string "Hello, World"


'Programming' 카테고리의 다른 글

Assembly Programming - isAlpha, isNumber  (0) 2015.10.11
Assembly Programming - gets  (0) 2015.10.10
Assembly Programming - puts  (0) 2015.10.10
Assembly Programming - strcpy  (0) 2015.10.10
Assembly Programming - strlen  (0) 2015.10.10
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,