sweetchip's blog


안녕하세요 pgnsc 입니다.


리버싱을 계속 공부하고 있는데 역시나 너무나도 어렵지만 풀고나면 너무 쉽게 느껴지네요 ㅋㅋ


문제를 다풀고 나면 이런거에 내가 삽질 하다니.. 라는 생각이 들기도 합니다 -_-


[물론 문제가 이상한게 아닌 이런방법을 왜 몰랐나 라는 뜻입니다 ㅋㅋ ]


오늘의 크랙미!


Coolsoft 의 게시물중 하나인 크랙미입니다. [문제시 삭제]



crackme.exe


좋습니다.. 시작해봅시다


오늘은 그림위주의 설명을 하겠습니다.



what is the key? 라는 것이 나오고 글자를 비교하고 맞으면 good 이라고 나오는 프로그램입니다.


이제 살짝 살펴볼까요



일단은 제가 주석을 달아두긴 했습니다.


입력을 받은후 3개의 루틴을 거쳐서 키값을 비교합니다.


첫번째는 입력받은 값을 뒤집고 [ex abc -> cba]


두번째는 알파벳인경우[제가 확인한것은 알파벳^^] 0x0D 만큼 더해줍니다.


세번째는 한글자씩 비교들어갑니다.


말로는 쉽지만 꽤나 삽질을 했습니다 ㅠ-ㅠ




그러면 첫번째 루틴은 생략하고 두번째 부터 시작하겠습니다.


sweetchip 을 입력하고 다음과정을 거칩니다.


현재 문자열을 pihcteews 입니다.



꽤나 긴 루틴이 입니다..


처음보고 입이 떡 벌어졌으나 별건 아니더군요 :D


입력한 글자를 하나씩 가져오고 그 글자가 알파벳인경우 13을 하는 루틴입니다. [모두 분석한것이 아니라 추가로 더 있을지도.. ^^]


또한 하지만 그 만큼 더해도 알파벳은 벗어나지 않습니다[ex : z => ^ 으로 되지 않고 z => q 로 됩니다.]


위에 브레이크 포인트를 걸어둔곳을 글자로 확인하면..


0040C1E0 |. 8B55 08 |MOV EDX,DWORD PTR SS:[EBP 8]

0040C1E3 |. 0355 FC |ADD EDX,DWORD PTR SS:[EBP-4]

0040C1E6 |. 8A02 |MOV AL,BYTE PTR DS:[EDX] // AL에 글자삽입

0040C1E8 |. 04 0D |ADD AL,0D // AL에 0x0D만큼 더함

0040C1EA |. 8B4D 08 |MOV ECX,DWORD PTR SS:[EBP 8]

0040C1ED |. 034D FC |ADD ECX,DWORD PTR SS:[EBP-4]

0040C1F0 |. 8801 |MOV BYTE PTR DS:[ECX],AL // 원래 글자를 0x0D만큼 더한 AL로 변경함


그리고 글자를 모두다 검사하고 변경한뒤 루틴이 종료됩니다.



레지스터 창의 eax, ecx에 저장된값은 위 루틴을 거쳐서 나온 값이고


edx의 값은 다음 루틴에 사용될 비교할 값입니다.


최종 답이 EDX과 같아야 합니다.




현재: sweetchip -> pihcteews -> cvupgrrjf 입니다.


자 이제 대충 루틴을 파악했습니다.


글자 입력 -> 뒤집기 -> 알파벳인경우 13


이제 마지막 루틴을 확인할 차례입니다.




네 위가 바로 마지막 확인 루틴입니다.


아래의 반복문을 돌면서 한글자씩 체크합니다.


한글자씩 비교해서 글자가 맞다면 다음으로 넘어갑니다. 아니라면 함수를 빠져나옵니다.


이부분은 한글자씩 아무 글자를 대입하면 점프문에서 다음으로 넘어가는지, 루틴을 종료하는 부분으로 넘어가는지 확인해서


한글자씩 끼워맞추다보면 게싱이 가능합니다.


이런식으로 한글자씩 알아냅니다. [위사진 말고 한번더 위의 레지스터창 사진에서 설명했듯이, 그 사진에서 edx부분에 저장된 값과 같아야 합니다.]


한글자씩 알아내다 보면..



i'm reverser 이 정답이 되게 됩니다 ^^




:D


아래는 위 어셈블리를 토대로 c언어로 변경해서 만든 소스코드입니다.


C언어 초보라서 소스가 약간 난잡할수 있습니다.


Key gen :

unknown_crackme_Cracked_by_sweetchip.exe

#include

#include


void reverseString(char* s) {

size_t size = strlen(s);

char temp;


for (size_t i = 0; i < size / 2; i ) {

temp = s[i];

s[i] = s[(size - 1) - i];

s[(size - 1) - i] = temp;

}

}


int main()

{

printf("/////////////////////////////////////////\n");

printf("///// unknown Crackme ///////\n");

printf("///// Key-Gen ///////\n");

printf("///// By sweetchip ///////\n");

printf("/////////////////////////////////////////\n");


char encrypted[] = "erferire z'v";

int length = strlen(encrypted);


reverseString(encrypted);


for(int i = 0; i

{

char nowalpha = encrypted[i];

if(isalpha(nowalpha))

{

if(nowalpha >= 0x41 && nowalpha <= 0x4D)

{

nowalpha= nowalpha 0x0D;

}

else if(nowalpha >= 0x4E && nowalpha <= 0x5A)

{

nowalpha = nowalpha - 0x0D;

}

else if(nowalpha >= 0x61 && nowalpha <= 0x6D)

{

nowalpha = nowalpha 0x0D;

}

else if(nowalpha >= 0x6E && nowalpha <= 0x7A)

{

nowalpha = nowalpha - 0x0D;

}

encrypted[i] = nowalpha;

}

}


printf("\nKey is : %s\n\n",encrypted);

system("pause");

}




신고

댓글 0