以下仅供学习交流使用,禁止用于其他用途,如果侵权,请联系作者删除!!!
仅供学习!!!
仅供学习!!!
仅供学习!!!
一.ocr识别
原理:捕捉屏幕的图片,进行特定区域文字识别。
优点:环境配置简单,易上手,且不容易被封。
缺点:速度比较慢,大概是大学生水准,并且有错误,需要自己优化。
下面第一个代码是主代码,第二个是辅助你获取坐标的,第一个代码有些部分需要你改一下。
使用教程:下载一个模拟器,下载一个Tesseract,然后代码中路径填写为你的Tesseract路径,然后,用辅助代码获取你的区域坐标,更改主代码中的坐标即可。
主代码:
import cv2
import numpy as np
import pytesseract
import mss
import pyautogui
import time
from threading import Thread, Lock
# 设置Tesseract可执行文件路径 请自行安装 并更换成你的路径
pytesseract.pytesseract.tesseract_cmd = r'D:\see\tesseract.exe'
# 定义捕获区域,左上角和右下角坐标 题目的坐标
current_top_left = (71, 364)
current_bottom_right = (810, 760)
# 计算当前题目区域的宽度和高度
current_monitor = {
"top": current_top_left[1],
"left": current_top_left[0],
"width": current_bottom_right[0] - current_top_left[0],
"height": current_bottom_right[1] - current_top_left[1]
}
# 存储上一个绘制的符号
last_numbers = None # 用于记录上一次的数字
lock = Lock() # 创建一个锁以保证线程安全
def draw_symbol_with_mouse(symbol, position):
x, y = position
pyautogui.moveTo(x, y) # 移动到指定位置
pyautogui.mouseDown() # 按下鼠标左键
# 减少移动步骤
if symbol == ">":
pyautogui.moveRel(30, -30) # 添加 duration 减少移动时间
pyautogui.moveRel(-30, -30)
elif symbol == "<":
pyautogui.moveRel(-30, -30)
pyautogui.moveRel(30, -30)
pyautogui.mouseUp() # 放开鼠标左键
def print_result(numbers, comparison):
print(f"识别到的数字: {numbers[0]} 和 {numbers[1]}, 判断结果: {comparison}")
def ocr_process(frame):
global last_numbers
# 图像预处理
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
# OCR识别
custom_config = r'--oem 3 --psm 6 outputbase digits -c tessedit_char_whitelist=0123456789?'
result = pytesseract.image_to_string(binary, config=custom_config)
# 按问号分割识别结果
parts = result.split('?')
# 提取数字并处理
numbers = [int(''.join(filter(str.isdigit, part))) for part in parts if ''.join(filter(str.isdigit, part))]
# 进行比较并绘制符号
if len(numbers) == 2:
with lock: # 确保对共享资源的安全访问
if numbers != last_numbers: # 只有当新数字不同于上一个数字时才进行绘制
if numbers[0] > numbers[1]:
comparison = ">"
draw_symbol_with_mouse(">", (300, 1100))
elif numbers[0] < numbers[1]:
comparison = "<"
draw_symbol_with_mouse("<", (300, 1100))
else:
comparison = "="
last_numbers = numbers
print_thread = Thread(target=print_result, args=(numbers, comparison))
print_thread.start()
def capture_process():
with mss.mss() as sct:
while True:
img = sct.grab(current_monitor)
img_np = np.array(img)
img_bgr = cv2.cvtColor(img_np, cv2.COLOR_BGRA2BGR)
ocr_process(img_bgr)
capture_thread = Thread(target=capture_process)
capture_thread.start()
辅助代码(辅助获取屏幕坐标,用于ocr识别区域的设置):
import pyautogui
import time
#
#
# 本代码用来辅助获取屏幕定位
#
#
print("将鼠标移动到你想要的位置...")
time.sleep(3) # 给你3秒钟的时间来移动鼠标
x, y = pyautogui.position() # 获取鼠标当前的位置
print(f"当前鼠标坐标: ({x}, {y})")
效果图(不优化真的慢,一般人的速度):
二.抓包改包
原理:mitmproxy作为中间代理修改响应包。
缺点:配置环境较难,需要解决ssl pinnning问题,解决办法看我的另一篇文章 绕过ssl pinning,需要设置代理。本来没加密时,PK时也能用,加密后之能在练习场用了。
优点:快,可修改答案,题数等。
使用教程:安装必须的库,模拟器端使用代理
查看本机地址的方法,在cmd中输入ipconfig,找到ipv4地址,在模拟器上填入。
在python的终端输入mitmweb -s xyks.py,后面改成你文件的名字。
必须先解决ssl pinning,不然一抓包就断网,必须先解决证书验证。
我这里把答案改成了1,可以自行修改,自己分析一下json。
{
"addErrorCount": "",
"bestRecordQuestionCnt": 0,
"correctCnt": 0,
"correctRate": 0,
"correctRateRank": 0,
"costTime": 0,
"encourage": null,
"errorBookFlag": 0,
"id": 0,
"idString": "1295459193054003200",
"inspirationSection": {
"a": 42954,
"b": 29708,
"c": 18628,
"d": 3010
},
"keypoint": "分数的乘除混合运算",
"keypointId": 411,
"orionKeypointId": 0,
"practiceCntFlag": 0,
"questionCnt": 10,
"questions": [
{
"answer": "\\frac{1}{9}",
"answers": [
"\\frac{1}{9}"
],
"content": "\\frac{9}{56}\\times(\\frac{8}{3}\\div\\frac{27}{7})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{8}{63}",
"answers": [
"\\frac{8}{63}"
],
"content": "\\frac{20}{21}\\div(\\frac{9}{2}\\div\\frac{3}{5})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{24}{49}",
"answers": [
"\\frac{24}{49}"
],
"content": "\\frac{16}{21}\\div\\frac{1}{3}\\times\\frac{3}{14}=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{5}{16}",
"answers": [
"\\frac{5}{16}",
"0.3125"
],
"content": "\\frac{5}{18}\\times(\\frac{5}{8}\\div\\frac{5}{9})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{6}{7}",
"answers": [
"\\frac{6}{7}"
],
"content": "\\frac{27}{4}\\times(\\frac{4}{7}\\div\\frac{9}{2})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{5}{32}",
"answers": [
"\\frac{5}{32}",
"0.15625"
],
"content": "\\frac{25}{16}\\times\\frac{3}{4}\\div\\frac{15}{2}=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{27}{10}",
"answers": [
"\\frac{27}{10}",
"2\\frac{7}{10}",
"2.7"
],
"content": "\\frac{12}{25}\\div\\frac{2}{9}\\times\\frac{5}{4}=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{28}{5}",
"answers": [
"\\frac{28}{5}",
"5\\frac{3}{5}",
"5.6"
],
"content": "\\frac{35}{8}\\times(\\frac{8}{5}\\div\\frac{5}{4})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{32}{35}",
"answers": [
"\\frac{32}{35}"
],
"content": "\\frac{16}{45}\\div(\\frac{1}{8}\\div\\frac{9}{28})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
},
{
"answer": "\\frac{9}{28}",
"answers": [
"\\frac{9}{28}"
],
"content": "\\frac{25}{16}\\div(\\frac{5}{9}\\div\\frac{4}{35})=\\square",
"costTime": 0,
"errorState": 0,
"id": 1,
"script": null,
"status": 0,
"userAnswer": null,
"wrongScript": null
}
],
"rankFlag": 0,
"ruleType": 0,
"shareable": true,
"source": 0,
"speedRank": 0,
"trialExamId": "",
"updatedTime": 0
}
代码:
import mitmproxy
import json
import mitmproxy.test
from mitmproxy import http
class Kousuan:
def request(self, flow: http.HTTPFlow):
request = flow.request
def response(self, flow):
response = flow.response
request = flow.request
if "https://xyks.yuanfudao.com/leo-math/android/exams?" in request.url:
data = response.json()
for i in data["questions"]:
i["answer"] = "1" #修改的答案,可以任意改,上下两个都改
i["answers"] = ["1"]
response.set_text(json.dumps(data))
addons = [Kousuan()]
效果图:
三.frida
原理:自己查。
优点:超级快,可修改PK场的数据。
缺点:环境配置难,不适合新手,需要懂adb,frida,安卓逆向等,frida的安装也比较难,不会的看看我的另一篇文章 frida的安装。
使用教程:模拟器段启动frida-server,不会的上面有教程,pc端启动代码。
代码:https://gitee.com/xiamuceer/little-ape-arithmetic自己去下。
效果图:
仅供学习!!!!!!!!