C300_056
C300_소스코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> #include <string.h> void main(void) { char string1[100]; char string2[100]; printf("첫 번째 단어를 입력하세요 !\n"); gets(string1); printf("두 번째 단어를 입력하세요 !\n"); gets(string2); strcat(string1, string2); puts(string1); } | cs |
IDA - Layout Graph
IDA - Text View
pseudo code - 의사코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include <stdio.h> void main(void) { char var_1; char var_2; char var_8[6]; int var_C; int var_10; int var_14; int var_18; char string1[100]; char string2[100]; printf(_Format); eax = string1; gets(eax); printf(byte_403020); ecx = string2; gets(ecx); edx = string2; var_8 = edx; eax = var_8; var_10 = eax; do{ ecx = var_8 dl = [ecx]; var_1 = dl; var_8 = var_8 + 1; }while(var_1 != NULL) eax = var_8; eax = eax - var_10; // eax에 string2의 길이 저장 ecx = var_10; var_14 = ecx; var_18 = eax; edx = string1; edx = edx + 0xFFFFFFFFh; var_C = edx; do{ eax = var_C; cl = [eax+1]; var_2 = cl; var_C = var_C + 1; }while(var_2 != NULL) edi = var_C; esi = var_14; edx = var_18; ecx = edx; ecx = ecx >> 2; rep movsb; ecx = edx; ecx = ecx && 3; rep movsb; eax = string1; puts(eax); eax = 0; } | cs |
shr(shift right): 오른쪽으로 비트를 민다.
rep movsd(move data from String to String): ecx에 저장된 수 만큼 esi에서 edi로 4바이씩 복사한다.
rep movsb(move data from String to String): ecx에 저장된 수 만큼 esi에서 edi로 1바이씩 복사한다.
23줄 var_18 = string2 - var_8을 해석해보자.
while문에 의해 string2는 문자열의 끝인 NULL을 가리키고 있다.
var_8은 원래 while문 전의 string2 문자열의 시작 주소를 가지고 있다.
C문법에서는 주소값끼리의 연산이 불가능하다.
하지만 어셈블리에서는 가능하기 때문에 주소값의 차를 이용해 string2의 문자열의 길이를 구했다.
32줄 ecx = ecx >> 2를 해석해보자.
ecx는 우리가 얼마만큼 반복해서 데이터를 옮겨야하는지에 대한 수가 저장되어 있다.
우선 4바이트씩 복사하기 때문에, 4로 나누어 진행하는 모습이다.
36줄 ecx = ecx && 3을 해석해보자.
4바이트씩 복사한 후 4의 나머지로 인해 복사되지 않은 부분이 있을 수 있다.
예를 들어 7바이트 문자열이면 4바이트씩 복사하기 때문에 3바이트가 복사되지 않았다.
효율성을 위해 4바이트씩 복사한 후 나머지를 1바이트씩 복사할 것이다.
따라서 우리는 4로 나눈 나머지를 구해야한다. 이것을 and 연산을 이용해 구할 수 있다.
7 && 3 = 3이다. 따라서 and 3을 통해 항상 4로 나눈 나머지를 구할 수 있다.
어떤 수의 나머지를 구할 때 %, &를 이용하여 구할수 있다.
m % n = x
m & (n-1) = x
pseudo code - 의사코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <stdio.h> void main(void) { char var_1; char var_2; char var_8[6]; int var_C; int var_10; int var_14; int var_18; char string1[100]; char string2[100]; printf(_Format); gets(string1); printf(byte_403020); gets(string2); var_8 = var_10 = string2; while(*string2++ != NULL) var_18 = string2 - var_8; // string2 의 길이 저장 var_14 = var_8; var_C = string1 + 0xFFFFFFFFh; while(*string1++ != NULL) edi = var_C; // var_C는 string1에 저장된 문자열의 끝을 가리킨다. esi = var_14; // var_14는 string2가 저장된 문자열의 처음을 가리킨다. edx = var_18; // var_18은 stsring2의 문자열 길이가 저장되어있다. ecx = edx; ecx = ecx >> 2; rep movsd // ecx에 저장된 수 만큼 4바이트씩 esi에서 edi로복사한다. ecx = edx; // edx는 stsring2의 문자열 길이가 저장되어있다. ecx = ecx && 3; // ecx && 3을 하면, ecx를 4로 나눈 나머지가 저장된다. rep movsb // ecx에 저장된 수 만큼 1바이트씩 esi에서 edi로복사한다. puts(string1); return 0; } | cs |
'Reversing > ASM to C' 카테고리의 다른 글
ASM to C with IDA - 058 (strstr) (0) | 2018.07.16 |
---|---|
ASM to C with IDA - 057 (strlen) (0) | 2018.07.16 |
ASM to C with IDA - 055 (strncmp) (0) | 2018.07.12 |
ASM to C with IDA - 054 (strcmp) (0) | 2018.07.12 |
ASM to C with IDA - 053 (0) | 2018.07.12 |