1. snake
py打包,pyc反编译
# 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.update()
pygame.time.Clock().tick(10)
continue
pygame.quit()
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8
xor_key = 'V3rY_v3Ry_Ez'
(要用python3.8运行脚本)
魔改RC4,照抄一下就行
#snake_wp
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] # Corrected the swap operation
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] # Corrected the swap operation
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 = [i ^ data[i] ^ key_stream[i] for i in range(len(data))] # Corrected decryption logic
return decrypted_data
key = 'V3rY_v3Ry_Ez'
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]
key_bytes = bytes([ord(char) for char in key])
dd = decrypt(bytes(data), key_bytes)
flag = ''
for i in range(len(dd)):
flag += chr(dd[i])
print(flag)
#flag{KMLTz3lT_MePUDa7A_P5LpzCBT}
2. HardSignIn
修改文件头的UPX
进去看不到啥主逻辑,看到一个回调函数,查看一下引用
去个花
tls0有个SMC
#SMC
addr=0x401890
size=0xAA
for i in range(size):
tmp=(get_wide_byte(addr+i))^0x66
patch_byte(addr+i,tmp)
跑一下得到main
然后是后面几个去花看一下逻辑
tls1删掉这一坨花就行
内容是反调试,11行直接绕过
tls2把这一坨删掉
13行反调试直接绕
tls3看起来比较奇怪,实际上还是反调试。
第九行直接绕
然后继续分析main,有个主要的加密和校验部分
进去看一下大致能看出来三个加密,依次为换表base64、rc4、魔改XTEA
然后就是取参数,要动调,绕过前面的反调试之后会有奇怪的异常,原程序的SMC不知有什么问题。这里建议手动解SMC之后,把tls0里的异或改为0
然后动调就正常了,各个参数都取出来
#HardSingin_wp
import base64
import string
#第三个加密 魔改XTEA,轮数改为100
from ctypes import *
def xtea_decrypt(v,k,r):
v0=c_uint32(v[0])
v1=c_uint32(v[1])
delta=0x9e3779b9
sum1=c_uint32(delta*r)
for i in range(r):
v1.value-=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])
sum1.value-=delta
v0.value-=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])
return v0.value,v1.value
#端序转换的函数,方便处理数据
def byte2uint32(d):
l=[]
for i in range(len(d)//4):
tmp=d[i*4:i*4+4]
l.append(tmp[3]*256**3+tmp[2]*256**2+tmp[1]*256+tmp[0])
return l
def uint322byte(uint32_list):
byte_array = []
for number in uint32_list:
byte_array.append(number & 0xFF)
byte_array.append((number >> 8) & 0xFF)
byte_array.append((number >> 16) & 0xFF)
byte_array.append((number >> 24) & 0xFF)
return byte_array
#第二个加密 RC4
def rc4(data, key):
S = list(range(256))
j = 0
out = []
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
i = j = 0
for char in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
out.append(char ^ S[(S[i] + S[j]) % 256])
return bytes(out)
#第一个加密 换表base64
def base64_kai_decode(str1, new_table):
original_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
return(base64.b64decode(str1.translate(str.maketrans(new_table,original_table))))
if __name__=='__main__':
#XTEA
enc = [ 0x59, 0x1B, 0xFD, 0xB4, 0x6B, 0xB8, 0xBE, 0xD9, 0xB3, 0xD3, 0x77, 0xD6, 0xF0, 0x65, 0x5F, 0x18,
0xA0, 0x9D, 0x3A, 0x53, 0x6D, 0x4A, 0x7B, 0x26, 0x74, 0x3A, 0x9C, 0x4E, 0x20, 0x43, 0x19, 0xD8,
0x72, 0xED, 0x95, 0xB5, 0x9C, 0x05, 0x22, 0x56, 0xCB, 0x7A, 0x11, 0x91, 0x9F, 0x7A, 0xBC, 0x0C,
0x4A, 0x69, 0x6D, 0xCE, 0x3D, 0xB4, 0xAB, 0x29, 0x61, 0xFA, 0x62, 0x32, 0xB4, 0xEC, 0x4C, 0xB6 ]
enc_uint32 = byte2uint32(enc)
# 0xb4fd1b59, 0xd9beb86b, 0xd677d3b3, 0x185f65f0, 0x533a9da0, 0x267b4a6d, 0x4e9c3a74, 0xd8194320,
# 0xb595ed72, 0x5622059c, 0x91117acb, 0xcbc7a9f, 0xce6d694a, 0x29abb43d, 0x3262fa61, 0xb64cecb4
'''
for byte in enc_uint32:
print(hex(byte), end=', ')
print()
'''
key = [0x0CAA5BDD,0xD6846924,0x51041EB8,0x8B2AAB06]
round = 100
for i in range(0,len(enc_uint32)-1,2):
tmp = [0]*2
tmp[0] = enc_uint32[i]
tmp[1] = enc_uint32[i+1]
res = xtea_decrypt(tmp,key,round)
for j in res:
print(hex(j), end=', ')
print()
enc1 = [0x7b00edbc, 0x9316f486,
0xdc87f995, 0x7fa2a867,
0x9f62e24d, 0xe9ae347b,
0x357e0345, 0x708bd042,
0xc72efbf0, 0x73b9e9dd,
0x751acce3, 0x14fddcad,
0x1645c8a8, 0x82a6e31,
0x9f1d0f2c, 0xefd5ba07]
enc1_byte = uint322byte(enc1)
# 0xbc, 0xed, 0x0, 0x7b, 0x86, 0xf4, 0x16, 0x93, 0x95, 0xf9, 0x87, 0xdc, 0x67, 0xa8, 0xa2, 0x7f,
# 0x4d, 0xe2, 0x62, 0x9f, 0x7b, 0x34, 0xae, 0xe9, 0x45, 0x3, 0x7e, 0x35, 0x42, 0xd0, 0x8b, 0x70,
# 0xf0, 0xfb, 0x2e, 0xc7, 0xdd, 0xe9, 0xb9, 0x73, 0xe3, 0xcc, 0x1a, 0x75, 0xad, 0xdc, 0xfd, 0x14,
# 0xa8, 0xc8, 0x45, 0x16, 0x31, 0x6e, 0x2a, 0x8, 0x2c, 0xf, 0x1d, 0x9f, 0x7, 0xba, 0xd5, 0xef
'''
for byte in enc1_byte:
print(hex(byte), end=', ')
print()
'''
#RC4
data = bytes(enc1_byte)
key = bytes([0x76, 0x89, 0x33, 0x49, 0x19, 0x13, 0xC3, 0xC7, 0xAD, 0xD8, 0xE4, 0x68, 0xFC, 0x48, 0x04, 0xBC])
enc2 = rc4(data, key)
print(enc2)
# b'C+vFCnHRGPghbmyQMXvFMRNd7fNCG8jcU+jcbnjRJTj2GTCOGUvgtOS0CTge7fNs'
#base64
table = "4yZRiNP8LoK/GSA5ElWkUjXtJCz7bMYcuFfpm6+hV0rxeHIdwv32QOTnqg1BDsa9"
print(base64_kai_decode(enc2.decode(),table))
# b'flag{C0ngr@tulat1on!Y0u_Re_suCces3fu1Ly_Signln!}'
3. bedtea
前面就是输入和两个反调试
29行的反调试动调的时候改一下rax寄存器的值就行
40行的反调试改一下ZF值为1即可,本来是往左边跳转(检测到调试),修改后往右边,异或0x33
主要加密部分,三个魔改TEA
轮数改了,key也是变化的
动调直接取key,是斐波那契数列
HIDWORD取最高位的dword,就是最左边(图一中是0xD),key就是最低位(图一中0x3),DWORD1比最低位高一个dword(图一中0x5),DWORD2比最低位高两个dword(图一中0x8)
37-39操作比较难看,实际上是通过二叉树对数据倒序,比较难看出来
数据都存到xmmword里面去了,可以查看一下xmmword_408060,发现里面的数据是动调出来密文的倒序
最后比对的地方,可以得到密文
#beatea_wp
from ctypes import *
enc = [0x76, 0x71, 0x9D, 0xE7, 0x70, 0x77, 0x3F, 0xA3,
0x02, 0xF1, 0x8D, 0xC9, 0x02, 0xC6, 0xA2, 0x4B,
0xBA, 0x19, 0x56, 0x05, 0xF2, 0x89, 0x5E, 0xE0]
def byte2uint32_r(d):
l=[]
for i in range(len(d)//4):
tmp=d[i*4:i*4+4]
l.append(tmp[0]*256**3+tmp[1]*256**2+tmp[2]*256+tmp[3])
return l
def hexprint(arr):
for byte in arr:
print(hex(byte), end=', ')
print()
for i in range(len(enc)):
enc[i] ^= 0x33
hexprint(enc)
enc_uint32 = byte2uint32_r(enc)
enc_uint32 = enc_uint32[::-1]
hexprint(enc_uint32)
def tea_kai_de(v,k):
v0=c_uint32(v[0])
v1=c_uint32(v[1])
delta=0x9E3449B8
sum1=c_uint32(0x987E55D0)
while(sum1.value != 0):
v1.value -= ( (v0.value*32) + k[2] )^(v0.value + sum1.value)^( (v0.value >> 4) + k[3] )
v0.value -= ( (v1.value*32) + k[0] )^(v1.value + sum1.value)^((v1.value >> 4) + k[1])
sum1.value -= delta
return v0.value,v1.value
def dec(enc,k,i):
tmp = [0]*2
tmp[0] = enc[i]
tmp[1] = enc[i+1]
tmp = tea_kai_de(tmp,k)
enc[i] = tmp[0]
enc[i+1] = tmp[1]
key1 = [0x3,0x5,0x8,0xD]
key2 = [0x15,0x22,0x37,0x59]
key3 = [0x90,0xE9,0x179,0x262]
dec(enc_uint32,key1,0)
dec(enc_uint32,key2,2)
dec(enc_uint32,key3,4)
hexprint(enc_uint32)
def uint322byte(uint32_list):
byte_array = []
for number in uint32_list:
byte_array.append(number & 0xFF)
byte_array.append((number >> 8) & 0xFF)
byte_array.append((number >> 16) & 0xFF)
byte_array.append((number >> 24) & 0xFF)
return byte_array
flag_byte = uint322byte(enc_uint32)
hexprint(flag_byte)
flag = ''
for i in flag_byte:
flag += chr(i)
print(flag)
#flag{y0u_reallyl1ke_te@}