처음에는 정말 간단한 두수의 합을 출력하는 문제인줄 알고 while문을 이용하여 코드를 짰는데

이런 결과가 나왔다..

출력초과 결과는 처음 봤어서 좀 당황했었지만 문제를 다시 읽어보니......

 

A+B-4 문제는 일반적인 문제와 달리 입력의 마지막 조건이 제시해 있지 않음을 알았다..!

평소라면 입력한 n줄 만큼 입력받는다던가의 조건이 있는데 이 문제는 그렇지 않았던 것이다..

 

여기서 생각해낸 것은 EOF(End Of File) !!

 

#include <stdio.h>
int main() {
	int a, b;
	while (scanf("%d %d", &a, &b)!=EOF){
		printf("%d\n", a + b);
	}
}

코드를 설명하자면, 예제 입력처럼 두 수를 공백으로 구분하여 입력하면 그때 그때 바로 두수를 더한 결과를 출력하는 간단한 코딩이다.

 

여기서 주목해야할 부분은 while문의 조건이다.!

EOF는 말 그대로 파일 끝의 위치에 오면 EOF, 즉 -1을 반환될때 while문을 종료하게 만드는 것이다

 

저 코드로 다시 제출함으로써 문제를 풀어낼 수 있었다.!!!!!

 

 

'기억장소' 카테고리의 다른 글

sizeof 연산자  (0) 2019.04.23
continue문  (0) 2019.04.22
%.2f  (0) 2019.04.21

여러 게임핵 도전중에 고전게임인 똥피하기게임을 알게되었다..!

게임을 몇번 플레이해보니 쉽지 않아서 점수가 잘 안오르던 차에 이 게임의 점수값을 맘대로 바꿔보고 싶었다.!

 

쓴 프로그램은 TSearch!

예전엔 Cheat Engine을 사용했었는데 개인적으로는 TSearch가 보기 더 간편해서 적성에 맞았다...ㅎㅅㅎ

 

먼저 게임을 소개해보겠다잉

게임 화면

게임은 스페이스 바를 누르면 시작하고 바로 장애물인 똥이 내려온다 

방향키로 장애물을 피해 사람을 움직이면 되는 간단한 게임이다!

최고점수, 현재 스코어

위에 41이 최고점수이고 그 아래 15가 현재 점수를 말한다.

예상외로 한판에 고득점을 얻어서 나는 이 최고기록값인 41을 사용해 이 값의 주소를 찾아보았다

게임을 실행시켜 놓은 상태에서 TSearch를 실행시킨후 Open process에 들어가 실행시켜 놓은 게임을 연다.

그다음 맨왼쪽에 있는 돋보기를 클릭하면

이런창이 뜨는데 나는 41이라는 정확한 최고기록 값을 알고있기 때문에 Exact Value(정확한 값)을 선택한후 Value에 41을 입력하고 OK를 누른다

그러면 41의 값을 가진것들이 총 70개라고 알려주는 창이 뜨고 Ok를 누르면

이렇게 왼쪽에는 주소값이, 가운데에는 내가 찾았던 vlaue가 나온다

Value값들은 그 종류에 따라 실시간으로 계속해서 바뀔수도 있고 고정된 값일 수도 있다.

값이 41인 데이터들이 너무 많아서 간추리기 위해 게임을 다시 플레이해서 최고기록을 47로 바꾼후 다시 TSearch에서 값들을 확인해본 결과

41사이에서 Value가 47인 데이터를 딱 하나 찾을수 있었다..! 이걸 더블클릭하면

오른쪽에 똑같이 뜨게 되는데, 맨왼쪽칸은 데이터의 이름을 설정할수 있는 칸이다.

이 데이터가 확실히 맞는지 다시한번 확인하기 위해 게임을 다시다시 플레이하여 새 최고기록을 찍은후 아까 그 값을 확인해보니!

게임에 나타나는 바뀐 최고점수처럼 TSearch에 나타나는 Value도 함께 75로 바뀐걸 볼수있다!

이로써 저 데이터는 최고기록값임을 확신할 수 있었다

그래서 이 값의 이름을 최고기록으로 바꿔주고 내 목표인 최고기록 값을 900으로 수정해보니

이렇게 최고기록이 완전히 바뀌게 되었다!!!!!

 

최고기록 데이터를 찾는 다른 방법으로는...!

아까 했듯이 처음 최고기록이었던 41을 검색하고 최고기록을 47로 새로 갱신한 후에

돋보기...(Next Search) 를 클릭하면

첫 검색보단 여러 Search종류들이 나오는데

최고기록이 41에서 47로 바꼈으니 Has Changed검색을 선택하여 범위를 좁히거나,

41에서 47로 Value값이 증가하였으니 Has Increased를 선택하여서도 범위를 줄여나가며 원하는 데이터를 찾아낼수있다!!

 

매우매우 간단한 첫 게임핵이었지만 정말많은 몇백만개의 데이터들중에 내가 원하는 딱한가지의 값을 찾아내가는것이 정말 새로웠고 신기했고 재밌었다..!!!

이 문제를 풀어보니 , 문제가 보여주고 있는 패턴만 금방 알아낸다면 이 문제는 매우 간단한 문제인 것을 깨달았습니다.

먼저 이 문제의 메인 화면 부터 봐보겠습니다.

"5번 파일에 플래그가 있다!" 라는 문구와 1 2 3 4 라 쓰여있는 버튼이 있습니다.

 

그런데 여기서 제가 느낀 특이점은 파일이 있다는 5번부터 버튼이 없는 것이었는데요.

일단 1 2 3 4 이 버튼들을 눌러보았습니다.

눌러보니 바로 Nop이라는 문구가 떴는데요 2 3 4 도 마찬가지였습니다.

 

그런데 여기서 눈여겨봐야할 점이있는데요. 바로 주소창에 추가된 ?id=1 이라는 문구입니다.

2를 눌렀을땐 ?id=2가 나왔고, 3 4 또한 저런 형식으로 나왔습니다.

 

저는 이를 통해 그럼 5라는 버튼이 있었다면, 5를 눌렀을 때도 1 2 3 4와 같이 ?id=5라는 문구가 쳐졌겠구나 생각하였습니다.

그래서 주소창에 직접 ?id=5를 쳐본결과

이렇게 플래그를 얻을 수 있었습니다!

'webhacking' 카테고리의 다른 글

webhacking challenge 26  (0) 2019.12.20

26번의 문제 메인 화면입니다. view-source를 눌러주면

 

이런 코드를 볼 수 있는데요. 이 코드를 

 

if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); }

"GET으로 입력 받은 변수 id 값이 "/admin/"이라면, "no!"를 외치고 종료"

$_GET['id'] = urldecode($_GET['id']);

"GET으로 입력 받은 id 값에 그 id값을 urldecode하여 넣어준다"

if($_GET['id'] == "admin"){
    solve(26);
  }

"만약 GET으로 입력 받은 id가 "admin"과 일치하면 문제 해결"

 

이라고 저는 개인적으로 해석해 보았습니다.

 

 

분석 후 제가 첫번째로 해본 것은 주소창에 no가 나오도록 id=/admin/을 해보았습니다.

예상대로 no! 라는 문구가 나왔습니다.

이번엔 제대로, id에 admin을 인코딩하여 넣어주기로 하였습니다.

 

인코딩 표를 보며 한 결과,

%61%64%6D%69%6E  이렇게 나왔습니다.

 

 

이제 이걸 주소창에 치기만 하면 된다는 생각으로 해보았는데

?id=%61%64%6D%69%6E 를 치고 엔터를 누르는 동시에 

 

이와 같이 자동으로 %61%64%6D%69%6E 이 admin으로 바뀌었습니다...

 

 

이 원인을 찾기 위해 열심히 구글링 해본 결과,

 

브라우저는 입력 받은 데이터를 자동으로 인코딩하여 php로 보내면, php는 그 데이터를 자동으로 디코딩한다.

 

라는 것을 깨달았습니다.

즉, 제가 방금 %61%64%6D%69%6E 이렇게 보낸 데이터가 자동으로 인코딩이 되며 자동으로 admin이 된 것이었죠.

 

 

 

그렇다면 결론적으로 이 %61%64%6D%69%6E 이 데이터를 한 번 더 인코딩 시키면 되겠구나 생각하여 다시 인코딩해보았습니다.

 

그렇게 한번 더 인코딩하여,

%2561%2564%256D%2569%256E

라는 값이 나왔고 이를 주소창에 ?id=%2561%2564%256D%2569%256E 라고 친 결과.!

문제를 풀 수 있었습니다!

'webhacking' 카테고리의 다른 글

HackCTF - Web Hidden  (0) 2019.12.20

첫 C 프로젝트로 짰었던 행맨 (hangman) 게임이다. 

간단하게 게임을 설명하자면 A가 B몰래 영어 단어를 하나 입력하면 

그 단어의 알파벳 수 만큼 빈칸이 나오는데 

B는 그것을 참고하여 알파벳을 막 던져보며 무슨 단어인지 추론해나가는 게임이다.

 

알파벳을 틀리게 추론 할 때 마다 행맨의 몸이 머리부터 그려지고,

모든 몸이 다 그려지면 게임 실패이다.

 

행맨은   ⓞ

         ┌☆┐

         ┌┴┐

 이렇게 생겼으며 행맨이 보이는 바와 같이 생명도 7개이다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //exit함수
#include <windows.h> //system("cls"), 글자색 변경 함수
#include <string.h> //문자열세는 함수
#include <conio.h>  //getch 함수

사용 헤더파일

#define XMIDDLE 56 
#define YMIDDLE 15 //정가운데 좌표 정의
int hangman(void); //행맨 게임
void drawhang(int life); //hangman 그림 
int updown(void); //updown 게임
void CursorView(char show); //커서 숨기기위한 함수 
void gotoxy(int x, int y); //좌표
void Frame(void); //겉 프레임 

사용 함수, 변수

void drawhang(int life) {
	switch (life) {
	case 0:gotoxy(22, 9); printf("┐");
	case 1:gotoxy(18, 9); printf("┌");
	case 2:gotoxy(20, 9); printf("┴");
	case 3:gotoxy(22, 8); printf("┐");
	case 4:gotoxy(18, 8); printf("┌");
	case 5:gotoxy(20, 8); printf("☆");
	case 6:gotoxy(20, 7); printf("ⓞ");
	default:
		gotoxy(2, 2); printf("남은 생명 : %d", life);
	}
}

행맨을 그리는 함수

int hangman(void) {
	while (1) {
		char answer[100];  //답배열 
		char wrong[25] = "\0";  //오답배열
		char input; //입력
		char write[100] = { 0, }; //입력 배열
		int life = 7; //행맨 몸 부분부분 7개
		int find = 0;  //정답에 포함되는 알파벳인지 아닌지 확인
		int checked = 0;  //이미 입력했던 알파벳인지 아닌지 확인하는 변수
		int flag = 0; //check
		system("cls");
		system("title hangman game!");
		gotoxy(46, 17);
		printf("몰래 단어 입력 ! => ");
		scanf("%s", answer);
		int len = strlen(answer);  // 정답 단어의 길이

		for (int i = 0; i < len; i++) {
			write[i] = '_';  //입력배열을 '_'로 초기화
		}

		while (life > 0) {
			if (flag == 1) {
				break;
			}
			flag = 0;
			fflush(stdin);
			system("cls");
			drawhang(life);
			find = 0; // 실행할때마다 찾았는지 초기화
			gotoxy(47, 8);
			printf("정답 : ");
			for (int i = 0; i < len; i++) {
				printf("%c ", write[i]);
			}
			gotoxy(47, 10);
			printf("오답 => ");
			for (int i = 0; i < 7 - life; i++) {
				printf("%c , ", wrong[i]);
			}
			gotoxy(47, 14);
			printf("알파벳 입력 => ");
			scanf(" %c", &input);

			for (int i = 0; i < len; i++) {
				if (write[i] == input) {   // 입력한 알파벳이 이미 입력되어있으면
					printf("\n\n\n\n\t\t\t\t\t   [이미 말한 알파벳 입니다!]");
					checked = 1;		// 1 :  이미 입력한 알파벳이라는 뜻.  // 0 : 처음 입력.
					Sleep(700);
					break;
				}
				else if (answer[i] == input) { // 입력배열에 포함되지 않고(중복x), 정답배열엔 포함되었을 경우(정답)
					find = 1;  //알파벳 맞췄을때. 찾았다. find=1;
					write[i] = answer[i];  //빈칸을 알맞은 알파벳으로 바꾸기
				}
			}

			if (find == 1) { // 정답배열에 포함을 확인함.
				printf("\n\n\n\t\t\t\t\t        [딩동댕 ☆★]");
				Sleep(700);
			}
			else if (find == 0 && checked == 0) {   // 정답도 아니고, 입력배열도 아니다(중복x). // 오답배열과는 비교 해야함.
				for (int i = 0; i <= 7 - life; i++) {  // 오답배열의 내용과 입력 알파벳을 비교. 중복 확인. 
					if (wrong[i] == input) {  //오답배열에 같은 알파벳이 이미 있으면 => 이미 틀렸던 경우
						printf("\n\n\n\n\t\t\t\t\t   [이미 말한 알파벳 입니다!]");
						Sleep(700);
						find = 1;
						break;
					}
				}
				if (find == 0) {  //정답이 아니면서, 오답배열에도 기록되어있지 않은 경우. => 처음 틀린 경우
					printf("\n\n\n\n\t\t\t\t\t     [다시 생각해보세요!]");
					Sleep(700); // sleep
					wrong[7 - life] = input; //오답 배열에 잘못 입력한 알파벳 나열
					life--;
				}//오답
			}

			if (!strcmp(write, answer)) {  //모든 알파벳을 맞추면
				system("cls");
				gotoxy(46, 7);
				printf("  ㅇ     |     ㅇ");
				gotoxy(46, 8);
				printf(" ㅇ   -------   ㅇ ");
				gotoxy(46, 9);
				printf("ㅇ      /\      ㅇ");
				gotoxy(46, 10);
				printf("     _________");
				gotoxy(46, 11);
				printf("         |");
				gotoxy(46, 12);
				printf("       _____");
				gotoxy(46, 13);
				printf("           |");
				gotoxy(36, 15);
				printf("행맨이 완성되기 전에 답을 맞추셨습니다!");
				gotoxy(41, 17);
				printf("☆★ 축 하 드 립 니 다 ★☆");
				gotoxy(40, 20);
				puts("  다시하려면 y 종료하려면 n");
				while (1) {
					fflush(stdin);
					if (GetAsyncKeyState(0x59) & 0x0001) {
						getch();
						system("cls");
						flag = 1;
						break;
					}
					if (GetAsyncKeyState(0x4e) & 0x0001) {
						getch();
						return 0;
					}
					Sleep(500);
					if (GetAsyncKeyState(0x59) & 0x0001) {
						getch();
						system("cls");
						flag = 1;
						break;
					}
					if (GetAsyncKeyState(0x4e) & 0x0001) {
						getch();
						return 0;
					}
				}
			}

			if (life == 0) {     //결국 못알아내고 행맨이 다 그려지면
				system("cls");
				gotoxy(43, 10);
				printf("_______     _____   |___");
				gotoxy(43, 11);
				printf("|______     |____   |");
				gotoxy(43, 12);
				printf("|______       _______");
				gotoxy(43, 13);
				printf("   |                 |");
				gotoxy(43, 14);
				printf("___|____             |    ㅇ    ㅇ");
				gotoxy(40, 18);
				printf("    정답은 %s였습니다...", answer);
				gotoxy(38, 20);
				printf("    다시하려면 y 종료하려면 n");
				Sleep(1000);
				while (1) {
					fflush(stdin);
					if (GetAsyncKeyState(0x59) & 0x0001) {
						getch();
						system("cls");
						flag = 1;
						break;
					}
					if (GetAsyncKeyState(0x4e) & 0x0001) {
						getch();
						return 0;
					}
					Sleep(500);
					if (GetAsyncKeyState(0x59) & 0x0001) {
						getch();
						system("cls");
						flag = 1;
						break;
					}
					if (GetAsyncKeyState(0x4e) & 0x0001) {
						getch();
						return 0;
					}
				}
			}  //답을 맞추기 전에 생명 7개가 다 끝났을때
			find = 0;
			checked = 0;
		}  //생명 있는 동안 반복	
	} //게임 다시하고 싶을때를 대비하여 반복문 안에 둔다
}

행맨 게임 돌아가는 함수

void CursorView(char show) {
	HANDLE hConsole;
	CONSOLE_CURSOR_INFO ConsoleCursor;
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	ConsoleCursor.bVisible = show;
	ConsoleCursor.dwSize = 1;
	SetConsoleCursorInfo(hConsole, &ConsoleCursor);  //커서숨기기
}

콘솔창 내에서 커서 숨기는 함수

void gotoxy(int x, int y)
{
	COORD Cur;
	Cur.X = x;
	Cur.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);  //좌표
}

좌표 함수

void Frame(void) {
	printf(" +");
	for (int i = 0; i <= 108; i++)
		printf("-");
	puts("+");
	for (int i = 0; i < 29; i++) {
		printf(" |");
		gotoxy(111, i + 1);
		puts("|");
	}
	printf(" +");
	for (int i = 0; i <= 108; i++)
		printf("-");
	printf("+");
}  //프레임

게임 테두리 찍는 함수

int main() {
	while (1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
		CursorView(0); //커서 숨기기 
		system("mode con cols=113 lines=31");
		system("title Menu");
		system("title Menu");
		Frame();
		gotoxy(47, 7);
		printf("★☆ GAME WORLD ☆★");
		gotoxy(47, 9);
		printf("+-----------------+"); Sleep(400);
		gotoxy(47, 10);
		printf("|  SELECT A GAME  |");  Sleep(400);
		gotoxy(47, 11);
		printf("|                 |"); Sleep(400);
		gotoxy(47, 12);
		printf("| 1 --> Hangman   |");  Sleep(400);
		gotoxy(47, 13);
		printf("+-----------------+"); Sleep(400);
		gotoxy(XMIDDLE - 8, 18);
		printf("  ESC --> EXIT");

		while (1)
		{
			if (GetAsyncKeyState(0x31) & 0x0001)
			{
				getch(); //엔터 필요없이 바로 값을 가져감
				system("cls");
				hangman();
				break;
			}
			if (GetAsyncKeyState(VK_ESCAPE) & 0x0001)
			{
				fflush(stdin);
				getch();
				system("cls");
				Frame();
				gotoxy(XMIDDLE - 8, YMIDDLE - 1);
				printf("진짜 종료할까요??");
				gotoxy(XMIDDLE - 1, YMIDDLE);
				printf("Y/N");
				while (1)
				{
					if (GetAsyncKeyState(0x59) & 0x0001) {  //'y'입력
						getch();
						system("cls");
						gotoxy(XMIDDLE - 8, YMIDDLE - 1);
						printf("bye bye ~ ☆ ★\n\n\n\n\n\n\n");
						exit(0);

					}
					if (GetAsyncKeyState(0x4E) & 0x0001) {  //'n'입력
						getch();
						main();
					}
				}
			}
		}
	}
}

메인 함수

○ for문 구조 => for 변수 in [리스트] or (튜플) or "문자열":

                           수행할 문장...

   ☆ 리스트, 튜플, 문자열에서 차례대로 변수에 대입된다

○ continue : for문 실행 중 continue 만나면 for문의 처음으로 돌아가,

                 그 아래 명령을 실행하지 않음

range함수  => (시작 값, 마지막 값)

   ☆ 마지막값은 포함 X

   for문에서 함께 많이 쓰임

 

○ 리스트 내포 => [변수 for 항목 in 반복되는객체 if 조건문]

   ☆ 조건문은 있어도 되고 없어도 됨

   ☆ 더 간결하게 작성 가능

'python' 카테고리의 다른 글

10차시 - while문  (0) 2019.08.27
9차시 - if문  (0) 2019.08.26
8차시 - 자료형 값 저장  (0) 2019.08.21
7차시 - 불 자료형  (0) 2019.08.19
6차시 - 집합 자료형  (0) 2019.08.19

○ while문 : 어떤 명령어를 반복하여 실행할 때 사용됨

기본구조 => while 조건문:

실행 문장1

while문 빠져나오기 : break

명령문 처음으로 가기 : continue => 아래의 명령문을 실행 하지 않고

반복문의 처음으로 감.

무한 루프 : 반복문이 끝나지 않고 명령문을 계속 실행하는 것

ex) while True: => 조건이 계속 참이므로 명령문 계속 실행 / 끝날 조건도 X

☆ Ctrl+c 로 무한루프 빠져나올 수 O

 

 

'python' 카테고리의 다른 글

11차시 - for문  (0) 2019.08.27
9차시 - if문  (0) 2019.08.26
8차시 - 자료형 값 저장  (0) 2019.08.21
7차시 - 불 자료형  (0) 2019.08.19
6차시 - 집합 자료형  (0) 2019.08.19

○ if문 : 한 조건을 판단하여 판단 결과에 따라 명령어를 출력

if문 만들기 : if (조건):

실행문장

실행문장

...

elif(조건) : = C언어에선 else if와 동일

☆ 파이썬에서의 if문은 { } 괄호가 아닌 : 콜론을 붙여야함

☆ 조건부 표현식 : 조건문이 참일경우 if 조건문 else 조건문이 거짓일경우

=> 가독성 더 좋음

 

조건문 ? "참과 거짓을 판단하는 문장"

○ 비교연산자 : a > b | a < b | a == b | a != b | a <= b | a >= b |

다른연산자 : a and b-둘다 참이어야 참 | a or b-둘 중 하나만 참이어도 참 | a not-a가 거짓이어야 참

☆ 조건 참일 시 아무실행 하지 않기 : pass => 아무 동작 하지 않고 넘어간다

 

다양한 조건문

1. x in [리스트] : 리스트안에 x가 있는가?

2. x in (튜플) : 튜플안에 x가 있는가?

3. 'x' in '문자열' : 문자열안에 x가 있는가?

 

 

 

 

 

 

 

'python' 카테고리의 다른 글

11차시 - for문  (0) 2019.08.27
10차시 - while문  (0) 2019.08.27
8차시 - 자료형 값 저장  (0) 2019.08.21
7차시 - 불 자료형  (0) 2019.08.19
6차시 - 집합 자료형  (0) 2019.08.19

+ Recent posts