snack.exe


!!!rc4的加解密算法相同!!!


查壳无壳,用ida查看string发现有字符

snack01

说明是用python写完打包的程序

使用pyinstxtractor和uncompyle6进行解包和反编译

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
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8

import pygame
import random
import key

def initialize(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i] = S[j]
S[j] = S[i]
return S


def generate_key_stream(S, length):
i = 0
j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i] = S[j]
S[j] = S[i]
key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream


def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
decrypted_data = None((lambda .0 = None: [ i ^ data[i] ^ key_stream[i] for i in .0 ])(range(len(data))))
return decrypted_data

pygame.init()
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SNAKE_SIZE = 20
SNAKE_SPEED = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('贪吃蛇')
font = pygame.font.Font(None, 36)
snake = [
(200, 200),
(210, 200),
(220, 200)]
snake_direction = (SNAKE_SPEED, 0)
food = ((random.randint(0, WINDOW_WIDTH - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE, (random.randint(0, WINDOW_HEIGHT - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE)
key_bytes = bytes((lambda .0: [ ord(char) for char in .0 ])(key.xor_key))
data = [
101,97,39,125,218,
172,205,3,235,195,
72,125,89, 130,103,
213,120,227,193,67,
174,71,162,248,244,
12,238,92,160,203,185,155]
decrypted_data = decrypt(bytes(data), key_bytes)
running = True
if running:
window.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN or event.key == pygame.K_UP:
snake_direction = (0, -SNAKE_SPEED)
elif event.key == pygame.K_DOWN:
snake_direction = (0, SNAKE_SPEED)
elif event.key == pygame.K_LEFT:
snake_direction = (-SNAKE_SPEED, 0)
elif event.key == pygame.K_RIGHT:
snake_direction = (SNAKE_SPEED, 0)
continue
snake_head = (snake[0][0] + snake_direction[0], snake[0][1] + snake_direction[1])
snake.insert(0, snake_head)
snake.pop()
if snake[0] == food:
food = ((random.randint(0, WINDOW_WIDTH - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE, (random.randint(0, WINDOW_HEIGHT - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE)
snake.append(snake[-1])
if snake[0][0] < 0 and snake[0][0] >= WINDOW_WIDTH and snake[0][1] < 0 and snake[0][1] >= WINDOW_HEIGHT or snake[0] in snake[1:]:
running = False
for segment in snake:
pygame.draw.rect(window, WHITE, (segment[0], segment[1], SNAKE_SIZE, SNAKE_SIZE))
pygame.draw.rect(window, RED, (food[0], food[1], SNAKE_SIZE, SNAKE_SIZE))
score_text = font.render(f'''Score: {len(snake)}''', True, WHITE)
speed_text = font.render(f'''Speed: {SNAKE_SPEED}''', True, WHITE)
window.blit(score_text, (10, 10))
window.blit(speed_text, (10, 40))
score = len(snake)
if score >= 9999:
flag_text = font.render('Flag: ' + decrypted_data.decode(), True, WHITE)
window.blit(flag_text, (10, 70))
pygame.display.upate()
pygame.time.Clock().tick(10)
continue
pygame.quit()

print(decrypted_data.decode())

前三个函数体是rc4加密

将贪吃蛇相关的代码删掉和将key.pyc逆向

后为下列代码

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
xor_key = 'V3rY_v3Ry_Ez'  #这是key的内容
def initialize(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i] = S[j]
S[j] = S[i]

return S

def generate_key_stream(S, length):
i = 0
j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i] = S[j]
S[j] = S[i]


key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream

def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
decrypted_data = bytes([ i ^ data[i] ^ key_stream[i] for i in range(len(data))])
return decrypted_data

key_bytes = bytes(ord(char) for char in (xor_key))
print(key_bytes)
data = [
101,97,39,125,218,
172,205,3,235,195,
72,125,89, 130,103,
213,120,227,193,67,
174,71,162,248,244,
12,238,92,160,203,185,155]

decrypted_data = decrypt(bytes(data), key_bytes)
# flag_text = ('Flag: ' + chr(decrypted_data))

print(decrypted_data)

但是这段反编译代码有问题

rc4的初始化是将 s[i]与j[i]交换位置

而反编译出来的代码**S[i] = S[j] S[j] = S[i]**是单纯的赋值并没有交换顺序

所以正确脚本是

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
xor_key = 'V3rY_v3Ry_Ez'
def initialize(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
# S[i] = S[j]
# S[j] = S[i]
S[i],S[j] = S[j],S[i]
return S

def generate_key_stream(S, length):
i = 0
j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
# S[i] = S[j]
# S[j] = S[i]
S[i], S[j] = S[j], S[i]

key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream

def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
decrypted_data = bytes([ i ^ data[i] ^ key_stream[i] for i in range(len(data))])
return decrypted_data

key_bytes = bytes(ord(char) for char in (xor_key))
# key_bytes = [86,51,114,89,95,118,51,82,121,95,69,122]
print(key_bytes)
data = [
101,97,39,125,218,
172,205,3,235,195,
72,125,89, 130,103,
213,120,227,193,67,
174,71,162,248,244,
12,238,92,160,203,185,155]
decrypted_data = decrypt(bytes(data), key_bytes)
# flag_text = ('Flag: ' + chr(decrypted_data))

print(decrypted_data)