메뉴 닫기

Power Of XX (AHK Master 문제 풀이)

인텐드 솔루션으로 푸신분이 아무도 없네요..ㅜㅜ

전부 치트엔진+게싱 했어요..ㅜㅜ

 

1. static analysis

아래는 정적 분석을 통해 작성한 코드 이고 이걸 돌리면 디컴파일이 샤샤샥 됩니다.

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

 

#include <stdio.h>
#include <stdint.h>
#include <windows.h>
 
struct MT {
    uint32_t *next;
    uint32_t items;
    uint32_t mt[624];
};
 
static uint8_t MT_getnext(struct MT *MT) {
    uint32_t r;
 
    if (!MT>items) {
        uint32_t *mt = MT>mt;
        unsigned int i;
 
        MT>items = 624;
        MT>next = mt;
 
        for (i=0; i<227; i++)
            mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0(mt[i+1]&1))&0x9908b0df)^mt[i+397];
        for (; i<623; i++)
            mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0(mt[i+1]&1))&0x9908b0df)^mt[i227];
        mt[623= ((((mt[623] ^ mt[0])&0x7ffffffe)^mt[623])>>1)^((0(mt[0]&1))&0x9908b0df)^mt[i227];
    }
 
    r = *(MT>next++);
    r ^= (r >> 11);
    r ^= ((r & 0xff3a58ad<< 7);
    r ^= ((r & 0xffffdf8c<< 15);
    r ^= (r >> 18);
    return (uint8_t)(r >> 1);
}
 
static void MT_decrypt(uint8_t *buf, unsigned int size, uint32_t seed) {
    struct MT MT;
    unsigned int i;
    uint32_t *mt = MT.mt;
 
    *mt=seed;
    for(i=1; i<624; i++)
        mt[i] = i+0x6c078965*((mt[i1]>>30)^mt[i1]);
    MT.items = 1;
    MT.next = MT.mt;
 
    while(size)
        *buf++ ^= MT_getnext(&MT);
}
int main(void) {
    FILE *fp=fopen("AHK_MASTER.exe","rb");
    fseek(fp , 0x54A00, SEEK_SET ); //00 4A 05 00 F4 29 07 93 <– file end / AHK~START(4) + CRC(4)
    unsigned char rawData[0x200= {0,};
    fread(rawData,1,0x200,fp);
 
 
    BYTE *pData = rawData;
 
    DWORD PWSum = 0;
 
    pData += 16//Skip 16bytes header
    pData +=1//must 3;
 
    //pw
    DWORD PWLen = *(DWORD *)pData ^ 0xFAC1;
    pData += 4;
    MT_decrypt(pData,PWLen,PWLen+0xC3D2);
    printf("password : ");
    for(int i=0; i<PWLen; i++) {
        PWSum += pData[i];
        printf("%c",pData[i]);
    }
 
    printf("\n");
    pData += PWLen;
 
    //const str
    MT_decrypt(pData,4,0x16FA);
    for(int i=0; i<4; i++)
        printf("%c",pData[i]); //must FILE
    printf("\n");
    pData += 4;
 
 
    //Type
    DWORD Len2 = *(DWORD *)pData ^ 0x29BC;
    pData +=4;
    MT_decrypt(pData,Len2,Len2+0xA25E);
    printf("Type : ");
    for(int i=0; i<Len2; i++)
        printf("%c",pData[i]);
    printf("\n");
    pData += Len2;
 
    //Org Exe
    DWORD Len3 = *(DWORD *)pData ^ 0x29AC;
    pData +=4;
    MT_decrypt(pData,Len3,Len3+0xF25E);
    printf("Org EXE : ");
    for(int i=0; i<Len3; i++)
        printf("%c",pData[i]);
    printf("\n");
    pData += Len3;
 
    //JB01 Packed?!
    bool is_packed = pData[0];
    pData += 1;
 
    //SizeGet
    DWORD CompressedSize = *(DWORD *)pData ^ 0x45AA;
    pData +=4;
    DWORD UnCompressedSize = *(DWORD *)pData ^ 0x45AA;
    pData +=4;
 
    pData += 16;
 
 
    BYTE *Output = (BYTE *)calloc(1,CompressedSize + 1);
    BYTE *OutputUnCompressed = (BYTE *)calloc(1,UnCompressedSize + 1);
 
    MT_decrypt(pData,CompressedSize,PWSum+0x22AF);
    memcpy(Output,pData,CompressedSize);
 
    printf("%d %d : %d\n\n\n",CompressedSize,UnCompressedSize,Len2);
    if(is_packed == 0) {
        srand(0x1000);
        for(int i=0; i<CompressedSize; i++)
            Output[i] ^= rand()&0xff;
        printf("%s",Output);
    }
 
 
 
}

 

cs

2. dynamic analysis

"스크립트 복호화가 끝난 직후"에 메모리에 Break Point를 걸어주면 볼 수 있다.

(그냥 실행하고 cheat engine으로 스캔해봤자 안보임 ㅅㄱ)

 

 

댓글 남기기

이메일은 공개되지 않습니다.