From 5d1fcaeca2263ab48fae5d585c05c6126d016a04 Mon Sep 17 00:00:00 2001 From: 91c0e59d-6161-45ab-8aa4-2371574db28f <91c0e59d-6161-45ab-8aa4-2371574db28f@bankofchina.com> Date: Sun, 19 Jan 2025 14:13:14 +0800 Subject: [PATCH] add sdga part --- .gitignore | 1 - sdga/.settings.py | 31 +++++++++++++ sdga/login.py | 30 +++++++++++++ sdga/logout.py | 28 ++++++++++++ sdga/preview.py | 18 ++++++++ sdga/sdgb.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++ sdga/ticket.py | 44 +++++++++++++++++++ 7 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 sdga/.settings.py create mode 100644 sdga/login.py create mode 100644 sdga/logout.py create mode 100644 sdga/preview.py create mode 100644 sdga/sdgb.py create mode 100644 sdga/ticket.py diff --git a/.gitignore b/.gitignore index c8256c5..083b6d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ **/__pycache__ **/settings.py -sdga/ evil.py \ No newline at end of file diff --git a/sdga/.settings.py b/sdga/.settings.py new file mode 100644 index 0000000..a44f672 --- /dev/null +++ b/sdga/.settings.py @@ -0,0 +1,31 @@ +# This file contains the config of the whole project. +# DO NOT share your crtical info to others. +# Change the file name from .settings.py to settings.py. + + +# UserId 自行获取 +userId = 10000000 +accessCode = 50000000000000000000 + +# 上传的乐曲成绩 +# 此成绩将覆盖原有成绩 + +music_data = ({ + "musicId": 11588, + "level": 3, + "playCount": 11, + "achievement": 1005627, + "comboStatus": 0, + "syncStatus": 0, + "deluxscoreMax": 2362, + "scoreRank": 13, + "extNum1": 0 +}) + +# 机厅信息 + +regionId = 114 +regionName = "Yau Tsim Mong" +placeId = 6412 +placeName = "GOLDEN ERA GAME CENTRE" +clientId = "A63E01E0048" diff --git a/sdga/login.py b/sdga/login.py new file mode 100644 index 0000000..4d3bd81 --- /dev/null +++ b/sdga/login.py @@ -0,0 +1,30 @@ +import json +import pytz + +from sdgb import sdgb_api +from sdgb import aimedb_api +from datetime import datetime + +from settings import userId, accessCode +from settings import regionId +from settings import clientId +from settings import placeId + +def login(timestamp): + data = json.dumps({ + "userId": userId, + "acsessCode": accessCode, + "regionId": regionId, + "placeId": placeId, + "clientId": clientId, + "dateTime": timestamp, + "isContinue": False, + "genericFlag": 0, + }) + + login_result = json.loads(sdgb_api(data, "UserLoginApi", userId)) + return login_result + +if __name__ == "__main__": + print(aimedb_api(accessCode)) + print(login(int(input()))) diff --git a/sdga/logout.py b/sdga/logout.py new file mode 100644 index 0000000..e1b369c --- /dev/null +++ b/sdga/logout.py @@ -0,0 +1,28 @@ +import json +import pytz + +from sdgb import sdgb_api +from datetime import datetime + +from settings import userId, accessCode +from settings import regionId +from settings import clientId +from settings import placeId + +def logout(timestamp): + data = json.dumps({ + "userId": int(userId), + "accessCode": int(accessCode), + "regionId": regionId, + "placeId": placeId, + "clientId": clientId, + "dateTime": timestamp, + "type": 1 + }) + + logout_result = json.loads(sdgb_api(data, "UserLogoutApi", userId)) + return logout_result + + +if __name__ == "__main__": + print(logout(int(input()))) diff --git a/sdga/preview.py b/sdga/preview.py new file mode 100644 index 0000000..5a4fe24 --- /dev/null +++ b/sdga/preview.py @@ -0,0 +1,18 @@ +import json + +from sdgb import sdgb_api +from sdgb import aimedb_api +from settings import userId, accessCode + +def preview(userId): + data = json.dumps({ + "userId": int(userId) + }) + + preview_result = sdgb_api(data, "GetUserPreviewApi", userId) + + return preview_result + +if __name__ == "__main__": + print(aimedb_api(accessCode)) + print(preview(userId)) diff --git a/sdga/sdgb.py b/sdga/sdgb.py new file mode 100644 index 0000000..20cfda3 --- /dev/null +++ b/sdga/sdgb.py @@ -0,0 +1,110 @@ +import json +import zlib +import pytz +import base64 +import hashlib +import requests + +from binascii import unhexlify, hexlify +import socket +import re + +from datetime import datetime +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad + +AesKey = "A;mv5YUpHBK3YxTy5KB^[;5]C2AL50Bq" +AesIV = "9FM:sd9xA91X14v]" +ObfuscateParam = "M9aBNKuY" +KeychipID = "A63E-01E00488964" + +class aes_pkcs7(object): + def __init__(self, key: str, iv: str): + self.key = key.encode('utf-8') + self.iv = iv.encode('utf-8') + self.mode = AES.MODE_CBC + + def encrypt(self, content: bytes) -> bytes: + cipher = AES.new(self.key, self.mode, self.iv) + content_padded = pad(content, AES.block_size) + encrypted_bytes = cipher.encrypt(content_padded) + return encrypted_bytes + + def decrypt(self, content): + cipher = AES.new(self.key, self.mode, self.iv) + decrypted_padded = cipher.decrypt(content) + decrypted = unpad(decrypted_padded, AES.block_size) + return decrypted + + def pkcs7unpadding(self, text): + length = len(text) + unpadding = ord(text[length - 1]) + return text[0:length - unpadding] + + def pkcs7padding(self, text): + bs = 16 + length = len(text) + bytes_length = len(text.encode('utf-8')) + padding_size = length if (bytes_length == length) else bytes_length + padding = bs - padding_size % bs + padding_text = chr(padding) * padding + return text + padding_text + +def get_hash_api(api): + return hashlib.md5((api+"MaimaiExp"+ObfuscateParam).encode()).hexdigest() + +def sdgb_api(data, useApi, userId): + aes = aes_pkcs7(AesKey,AesIV) + data = bytes(data, encoding="utf-8") + data_def = zlib.compress(data) + data_enc = aes.encrypt(data_def) + endpoint = "https://mai2exp.sic-rd1.jp:42081/Maimai2Servlet/" + r = requests.post(endpoint + get_hash_api(useApi), headers={ + "User-Agent": "%s#%d"%(get_hash_api(useApi), userId), + "Content-Type": "application/json", + "Mai-Encoding": "1.51", + "Accept-Encoding": "", + "Charset": "UTF-8", + "Content-Encoding": "deflate", + "Expect": "100-continue" + }, data = data_enc,verify=False) + resp_enc = r.content + try: + resp_def = aes.decrypt(resp_enc) + except: + resp_def = resp_enc + return zlib.decompress(resp_def).decode('utf-8') + +def aimedb_api(accessCode): + key = b'Copyright(C)SEGA' + base_hex_stream = "3ea121400f00300000005344474100000c190000413633453031453030343800" + access_code = str(accessCode) + end_stream = "000201020304" + plaintext_hex_stream = base_hex_stream + access_code + end_stream + + plaintext = unhexlify(plaintext_hex_stream) + + cipher = AES.new(key, AES.MODE_ECB) + encrypted_message = cipher.encrypt(plaintext) + + encrypted_hex_stream = hexlify(encrypted_message).decode('utf-8') + + server_address = ('aime.naominet.jp', 22345) + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect(server_address) + sock.sendall(encrypted_message) + + response = sock.recv(1024) + + decrypted_response = cipher.decrypt(response) + + decrypted_hex_stream = hexlify(decrypted_response).decode('utf-8') + + match = re.search(r'[0-9a-f]{64}([0-9a-f]{6})', decrypted_hex_stream) + if match: + six_digit_code = match.group(1) + + rearranged_hex = six_digit_code[4:6] + six_digit_code[2:4] + six_digit_code[0:2] + + decimal_value = int(rearranged_hex, 16) + return decimal_value diff --git a/sdga/ticket.py b/sdga/ticket.py new file mode 100644 index 0000000..6c3be7e --- /dev/null +++ b/sdga/ticket.py @@ -0,0 +1,44 @@ +import json +import pytz +import time + +from sdgb import sdgb_api +from datetime import datetime, timedelta + +from settings import userId +from settings import regionId +from settings import clientId +from settings import placeId + +from logout import logout +from login import login + +def get_ticket(): + data = json.dumps({ + "userId": userId, + "userCharge": { + "chargeId": 6, + "stock": 1, + "purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"), + "validDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1) + timedelta(days=90)).replace(hour=4, minute=0, second=0).strftime("%Y-%m-%d %H:%M:%S") + }, + "userChargelog": { + "chargeId": 6, + "price": 4, + "purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"), + "placeId": placeId, + "regionId": regionId, + "clientId": clientId + } + }) + + ticket_result = json.loads(sdgb_api(data, "UpsertUserChargelogApi", userId)) + + return ticket_result + +if __name__ == "__main__": + timestamp = int(time.time()) + print(timestamp) + print(login(timestamp)) + print(get_ticket()) + print(logout(timestamp))