본문 바로가기

해킹/리버싱

[reversing.kr] position

우선 readme를 읽어보자.

name을 통해 serial을 gen하는 그런 문제인것 같다. 그러면 우리는 serial generation 루틴을 찾아서 분석해야 할 것이다. 

우선 패킹은 되어있지 않은 것으로 확인하였다.

문자열 참조를 통해 다음의 루틴을 찾아보자. 그러면 위의 call position.8D1740에서 eax값이 세팅되고 이 값이 0이면 Correct를 띄우는 것을 확인할 수 있다. 그러므로, 위 함수 안에 key gen과 비교 루틴이 있을 것이다.

그전에, 이 프로그램은 event handling 방식이기에, 위의 루틴이 실행되는 event를 알아보면, serial이나 name칸에 어느것이든 적힐 때마다, 위의 루틴을 반복한다. 그러므로, 우선 serial 칸에 readme에 제공되어있는 시리얼 값을 넣어준 후에, name을 적으면 keygen routine을 검사할 수 있을 것이다.

우선 위와 같이 적어주고, 본격적으로 분석해보자.

함수에 진입하면 초기에 어떤 반복문들이 얽히고 섥혀있어서, 이 녀석들을 탈출할때까지 블포 걸고 달려주자.

그러면 위와 같은 상황이 되는데 ebp - 14 에 어떤 시리얼 값과 ebp - 18에 내가 적은 abcd가 있는 것을 확인할 수 있다. 

그 밑에 이런 알수없는 함수가 있는데 32bit 시스템이므로, push 0를 인자로 전달하는 함수임을 알 수 있다. 이 함수를 실행하면, 실행 전후로, al 값이 변경되는데, 그 값은 인자로 받은 값을 num이라고 할때, 우리가 입력한 ecx가 가리키는 string의 1byte 값을 num을 idx로 하여 받아온다. (ebp - 18은 우리가 입력한 name string이다.)

그 밑에 루틴을 보면, 입력된 시리얼을 '-'를 기준으로 한 두단계 정도에 걸쳐서, name을 통한 시리얼값과 비교를 하고, 어느부분에서 다른 경우 이 함수를 탈출하게 된다. 그러므로, 값을 분석하면서 name에 따라 어떤 시리얼이 생성되는지를 분석하고 그 name을 찾아야 하는데,

그 루틴이..

종종 몇 번째 idx의 데이터를 가져오는 문구가 있고, 나머지는 깡 어셈 계산이어서, 이거 안되겠다. 싶어서, C로 코드를 짜줬다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define KEY_SERIAL "76876-77776"

char it(int idx, char* buf) {
    return buf[idx];
}

void makeSerial(char name[], char * buf) {
    char serial[11] = KEY_SERIAL;
    char al, cl, bl, dl;
    char e20, e1f, e1e, e1d, e1c;
    char e28, e27, e25, e24;
    //printf("%02X", al);
    al = it(0, name);
    cl = al;
    cl &= 1;
    e20 = cl + 5;
    cl = al;
    cl = cl >> 1;
    dl = al;
    bl = al;
    cl &= 1;
    dl = dl >> 2;
    bl = bl >> 3;
    al = al >> 4;
    cl += 5;
    dl &= 1;
    al &= 1;
    bl &= 1;
    e1c = al + 5;
    e1f = cl;
    e1e = dl + 5;
    e1d = bl + 5;
    al = it(1, name);
    cl = al;
    cl &= 1;
    e28 = cl + 1;
    cl = al;
    cl = cl >> 1;
    dl = al;
    bl = al;
    cl &= 1;
    dl = dl >> 3;
    al = al >> 4;
    cl++;
    bl = bl >> 2;
    dl &= 1;
    al &= 1;
    e24 = al + 1;
    e27 = cl;
    dl++;
    bl &= 1;
    bl++;
    e25 = dl;
    buf[0] = '0' + bl + e20;
    buf[1] = '0' + e25 + e1d;
    buf[2] = '0' + e24 + e1f;
    buf[3] = '0' + e1e + e28;
    buf[4] = '0' + e1c + e27;
    buf[5] = '-';
    al = it(2, name);
    cl = al;
    cl &= 1;
    e20 = cl + 5;
    cl = al;
    cl = cl >> 1;
    dl = al;
    bl = al;
    cl &= 1;
    dl = dl >> 2;
    bl = bl >> 3;
    al = al >> 4;
    cl += 5;
    dl &= 1;
    al &= 1;
    bl &= 1;
    e1c = al + 5;
    e1f = cl;
    e1e = dl + 5;
    e1d = bl + 5;
    al = it(3, name);
    cl = al;
    cl &= 1;
    e28 = cl + 1;
    cl = al;
    cl = cl >> 1;
    dl = al;
    bl = al;
    cl &= 1;
    dl = dl >> 3;
    al = al >> 4;
    cl++;
    bl = bl >> 2;
    dl &= 1;
    al &= 1;
    e24 = al + 1;
    e27 = cl;
    dl++;
    bl &= 1;
    bl++;
    e25 = dl;
    buf[6] = '0' + bl + e20;
    buf[7] = '0' + e1d + e25;
    buf[8] = '0' + e1f + e24;
    buf[9] = '0' + e1e + e28;
    buf[10] = '0' + e1c + e27;
    buf[11] = 0;
}

int main(void) {
    char name[5];
    char buf[11];
    int i, j = 0;
    for (i = 0; i < 26 * 26 * 26 * 26; i++) {
        strcpy(name, "aaaa");
        name[3] += (char)(i % 26);
        name[2] += (char)((i / 26) % 26);
        name[1] += (char)((i / (26 * 26)) % 26);
        name[0] += (char)((i / (26 * 26 * 26) % 26));
        makeSerial(name, buf);
        if (!strcmp(buf, KEY_SERIAL)) {
            j++;
            if (name[3] == 'p') {
                printf("*");
            }
            printf("%s ", name);
            if (!(j % 5))
                puts("");
        }
    }
}

위와 같은 C코드를 짜줘서, 시리얼을 generation하도록 한 후, aaaa부터 zzzz까지 모든 경우의 수를 따져서, 해당 시리얼을 gen하는 name을 출력한다.

실행해주면 위와 같은 결과가 나온다. 

'해킹 > 리버싱' 카테고리의 다른 글

[reversing.kr] Direct3D FPS  (1) 2021.05.07
[reversing.kr] easyELF  (0) 2021.04.09