winmain을 어셈블리어에서 구별하는법
GetModuleHandle 밑에 CALL이 winmain이다.
1. 소스
2. 어셈블리어
퀴즈3.exe 파일의 코드 찾아내기
정답:
퀴즈4.exe 파일의 코드 찾아내기
MOV DWORD PTR SS:[EBP-A],EDX //EDX의값 즉 공간을 다쓰고 6바이트가 남아서 6바이트를 0으로채움
MOV WORD PTR SS:[EBP-6],DX // char str[24] = "AegisOne Security";
LEA EAX,DWORD PTR SS:[EBP-1C] // EBP-1C는 배열의 첫주소이므로 배열명이 된다 따라서 str
MOV DWORD PTR SS:[EBP-4],EAX // char * p = str;
MOVSX EDX,BYTE PTR DS:[ECX+6] // 현재 ECX는 p이므로 p+6의 값을 저장 =*(p+6);
MOV DWORD PTR SS:[EBP-20],EDX // int n = *(p+6);
정답 :
퀴즈5
함수 파라미터들이 고정인 함수들이다.
strcpy(1,2);
memcpy(1,2,3);
strcmp(1,2);
strlen(1);
malloc(1);
free(1);
PUSH가 3개인 것으로 보아, 값이 3개임을 알 수 있다.
func(&x, "%d", n); 이 형태를 보아 sprintf임이 유추가된다.
sprintf의 기본 양식은
sprintf(string, "%d", n ); 이다.
MOV DWORD PTR SS:[EBP-18],5 // int n = 5;
LEA EDX,DWORD PTR SS:[EBP-14] //배열의 시작주소를 나타낸다.
정답
퀴즈06
값 변경하기
Selection 1개만 수정했을 시 사용
All modifications 여러개 수정했을 시 사용
수정한 후 copy all -> seve로 exe파일을 저장하면 완전히 수정이 된다.
소스분석
PUSH
PUSH
PUSH
CALL 구조를 보아 sprint임을 유추
따라서 00401006의 값을 변경하면 값이 변한다.
조건문
조건문(if)
CMP 피연산자1 에서 피연산자2를 빼고 양수면 피연산자1이 크고 음수면 피연산자2, 0이면 같다.
JE 같으면 JMP 가실행
JNZ 서로 다르면 JMP가실행
JGE 왼쪽이 크거나 같으면 JMP가 실행
JLE 왼쪽이 작거나 같으면 JMP가 실행
if(n<= 10)
JG 왼쪽이 크면 실행
if(n <= 10)
JL 왼쪽이 작으면 실행
and 연산자
or연산자
and와 다르게 jge가 참이면 push0 부분 즉 , 종속문장을 실행한다.
문제 02-1
아래 어셈블리어의 맞는 코드 작성
정답:
퀴즈 02-2
분석
MOV EAX,DWORD PTR SS:[EBP+10] //arg 3 == lpCmdLine
EBP + 8 //arg 1
EBP + C //arg 2
EBP + 10 //arg 3
따라서 lpCmdLine을 불러오면 된다.
TEST 참거짓을 비교하는 비교 연산자.
위의 문장을 통해 IDIV ECX의 값이 ch /13이 됨을 알 수 있다.
JE 조건식 점프로 뛰는 범위 안에 JNZ가 겹쳐있으므로 or임을 유추한다.
JNZ는 앞에 문장이 참일 시 건너뛰는 용도로 사용되기 때문에 반대로 생각해야된다.
위의 어셈블에 대한 소스 정답.
0x49 - 0x34 + 0x41 = 0x56 0x56 == 'V' 즉 , 3번째 문자열에 V가 오는 값을 아규먼트로 등록해주면 success가 뜬다.
Switch case 문 유형 1.
위의 소스 어셈블리어
소스분석
같은주소 == switch문의 끝
Switch case 문 유형 2.
Switch문이 4개 이상일 경우
어셈블리어 소스
소스 분석
즉 상수가 0일 경우 0*4 + 401097 //16진수계산
case 0 : 401097
case 1 : 40109B
case 2 : 40109F
case 3 : 4010A3
위의 주소에 위치하는 데이터값의 번호에 관련된 곳에 case 시작부분이 있다.
퀴즈 2-3
소스분석
EBP+10 이므로 아규먼트 3번째값 lpCmdLine임을 알 수 있고, JNZ이므로 0이 아니면 점프한다는 의미이기에 if(*lpCmdLine==0)이 된다.
if의 참인 부분 JNZ의 주소가 00401029를 가르키므로 그 전에 주소는 if문의 값이 된다.
OR EAX,FFFFFFFF // MOV EAX , -1 을 의미
JMP의 주소가 함수 마지막을 가르키므로 return이 된다.
lpCmdLine[0] - 0x30은 값이 정수로 나올수 밖에 없으므로 int형이다.
n과 5를 XOR연산
CMP JE CMP JE 순을보아 Switch문임을 유추
case2 와 case4의 내용 JMP는 break;
default의 내용
소스로 변환한 정답
소스를 수정해서 success를 띄우는법
n^5 -> 4가 되는 값은 n == 1이다.
문자 '0'은 16진수로 0x30 10진수로 48이다. 따라서, lpCmdLine[0]의 값이 1이면 success가 출력된다.
2-4 퀴즈
어셈블리어
분석
MOV DWORD PTR SS:[EBP-4],EAX 문장을 통해 x라는 변수에 func(lpCmdLine)을 넣는다.
밑에 문장을 보아 switch(x)을 의미
case3개를 가진 switch문
40109F주소의 헥사값을 보면 저기에 적힌 주소들이 case문의 내용이다.
이제 여기서 추리를 한다. lpCmdLine이니까 arument에 값을 하나한씩 넣어보면서 규칙을 찾아낸다.
위의 규칙을 통해 문자열의 길이를 파악한다는 것을 알 수있다. 따라서 strlen()함수이다.
소스 정답
따라서 success를 띄우기 위해서는 x의 값이 4이상 이면 된다.
for문
벗어나는 키 F4
위의 소스에 관련된 어셈블리어
분석
초기식 -> JMP하는 내용이 증감식이다. for(i=1; ; i++)
JMP로 도착한 부분부터 다음 JMP까지가 조건식이다. for(i=1; i <11(0B); i++)
다음 JMP하는 내용이 종속문장이다. sum = sum + i;
분석해보면 아래와 같은 for문이 나온다.
for(i=1; i<11; i++)
sum+=i;
for 2번째 유형
어셈블리어
분석
for문의 형태이다.
MOV
ADD
MOV 를통해 len++임을 알고
*(str+len) == str[len]
MOVSX 에서 EBP-8 + ECX인데, MOV연산자이기 때문에 안에 값을 가져온다 따라서 *(str+len)이된다.
JE기 때문에 *(str+len) 그대로 연산식이 된다.
JE와 JMP 사이에 값이 없으므로 안에 종속문장은 없다.
while문
continue는 종속문장 안에서 나온다.
break 둘다 jmp로 나오니 혼동x
분석
2-5 퀴즈
소스정답
2-6 퀴즈
정답:
2-7
어셈코드
분석.
정답
success 띄우기
즉 , 이 소스는 리버싱을 어렵게하기위해 0x30을 -> 0x2F로 변환해서 나타냈다.
따라서 마지막 if문을 보면 300-84=216 b의 값이 216이나오면된다.
0x30 -> 0x2F 는 1을 뺀 값이다.
216 -> 자릿수에 1씩 빼면 105가나온다.
105 -> 0x31 0x30 0x35
따라서 argument 값에 105를 입력하면 정답이다.