From d082be9cda2ec7e9a0e0cd86225d14abfd68c47c Mon Sep 17 00:00:00 2001 From: Knine Date: Tue, 19 Mar 2024 11:39:48 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90Frida=E3=80=91=2006=5F=E5=88=86?= =?UTF-8?q?=E6=9E=90=E6=89=AB=E9=9B=B7=E6=B8=B8=E6=88=8F=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=EF=BC=8C=E6=98=BE=E7=A4=BA=E5=9C=B0=E9=9B=B7=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=20=E3=80=90Frida=E3=80=91=2007=5F=E8=AE=A9=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E9=87=8D=E6=96=B0=E7=BB=98=E5=88=B6=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index.ts" | 6 +- .../index.ts" | 49 +++++++++++++++ .../index.ts" | 63 +++++++++++++++++++ course/frida/package.json | 4 +- course/frida/winapi/user32.ts | 26 ++++++++ 5 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 "course/frida/06_\345\210\206\346\236\220\346\211\253\351\233\267\346\270\270\346\210\217\347\232\204\346\225\260\346\215\256\357\274\214\346\230\276\347\244\272\345\234\260\351\233\267\344\275\215\347\275\256/index.ts" create mode 100644 "course/frida/07_\350\256\251\347\263\273\347\273\237\351\207\215\346\226\260\347\273\230\345\210\266\346\214\207\345\256\232\347\252\227\345\217\243/index.ts" create mode 100644 course/frida/winapi/user32.ts diff --git "a/course/frida/05_\350\257\273\345\217\226\346\243\213\347\233\230\346\225\260\346\215\256/index.ts" "b/course/frida/05_\350\257\273\345\217\226\346\243\213\347\233\230\346\225\260\346\215\256/index.ts" index 4804539..257dd8d 100644 --- "a/course/frida/05_\350\257\273\345\217\226\346\243\213\347\233\230\346\225\260\346\215\256/index.ts" +++ "b/course/frida/05_\350\257\273\345\217\226\346\243\213\347\233\230\346\225\260\346\215\256/index.ts" @@ -1,4 +1,4 @@ -class L07 { +class L05 { private module_name_winmine = "winmine.exe"; private module_winmine: Module; private offset地雷数量: number = 0x56A4; @@ -37,5 +37,5 @@ class L07 { } } -let l07 = new L07(); -l07.board_info(); \ No newline at end of file +let l05 = new L05(); +l05.board_info(); \ No newline at end of file diff --git "a/course/frida/06_\345\210\206\346\236\220\346\211\253\351\233\267\346\270\270\346\210\217\347\232\204\346\225\260\346\215\256\357\274\214\346\230\276\347\244\272\345\234\260\351\233\267\344\275\215\347\275\256/index.ts" "b/course/frida/06_\345\210\206\346\236\220\346\211\253\351\233\267\346\270\270\346\210\217\347\232\204\346\225\260\346\215\256\357\274\214\346\230\276\347\244\272\345\234\260\351\233\267\344\275\215\347\275\256/index.ts" new file mode 100644 index 0000000..2c4ce80 --- /dev/null +++ "b/course/frida/06_\345\210\206\346\236\220\346\211\253\351\233\267\346\270\270\346\210\217\347\232\204\346\225\260\346\215\256\357\274\214\346\230\276\347\244\272\345\234\260\351\233\267\344\275\215\347\275\256/index.ts" @@ -0,0 +1,49 @@ +class L06 { + private module_name_winmine = "winmine.exe"; + private module_winmine: Module; + private offset地雷数量: number = 0x56a4; + private offset棋盘高度: number = 0x56a8; + private offset棋盘宽度: number = 0x56ac; + private height: number = 0; + private width: number = 0; + private mine_count: number = 0; + private head: NativePointer = ptr(0); + + constructor() { + console.log( + "======================", + new Date().toISOString(), + "==========================" + ); + console.log("Frida.version", Frida.version); + //获取模块基址 + this.module_winmine = Process.getModuleByName(this.module_name_winmine); + + // 初始化游戏相关数据 + this.height = this.module_winmine.base.add(this.offset棋盘高度).readU32(); + this.width = this.module_winmine.base.add(this.offset棋盘宽度).readU32(); + this.mine_count = this.module_winmine.base.add(this.offset地雷数量).readU32(); + this.head = this.module_winmine.base.add(0x5340); + } + + run() { + //遍历棋盘,按行遍历 + for (let i = 0; i < this.height + 2; i++) { + //按列遍历 + let data = []; + for (let j = 0; j < this.width + 2; j++) { + let byte_data = this.head.add(j + 0x20 * i).readU8(); + data.push(byte_data.toString(16).padStart(2, "0")); + + // 如果是地雷,将其状态改为标记 + if (byte_data == 0x8F) { + this.head.add(j + 0x20 * i).writeU8(0x8E); + } + } + console.log(data.join(" ")); + } + } +} + +let l06 = new L06(); +l06.run(); diff --git "a/course/frida/07_\350\256\251\347\263\273\347\273\237\351\207\215\346\226\260\347\273\230\345\210\266\346\214\207\345\256\232\347\252\227\345\217\243/index.ts" "b/course/frida/07_\350\256\251\347\263\273\347\273\237\351\207\215\346\226\260\347\273\230\345\210\266\346\214\207\345\256\232\347\252\227\345\217\243/index.ts" new file mode 100644 index 0000000..592f652 --- /dev/null +++ "b/course/frida/07_\350\256\251\347\263\273\347\273\237\351\207\215\346\226\260\347\273\230\345\210\266\346\214\207\345\256\232\347\252\227\345\217\243/index.ts" @@ -0,0 +1,63 @@ +import User32 from '../winapi/user32' + +class L07 { + private module_name_winmine = "winmine.exe"; + private module_winmine: Module; + private offset地雷数量: number = 0x56a4; + private offset棋盘高度: number = 0x56a8; + private offset棋盘宽度: number = 0x56ac; + private height: number = 0; + private width: number = 0; + private mine_count: number = 0; + private head: NativePointer = ptr(0); + private hWnd: NativePointer = ptr(0); + + constructor() { + console.log( + "======================", + new Date().toISOString(), + "==========================" + ); + console.log("Frida.version", Frida.version); + //获取模块基址 + this.module_winmine = Process.getModuleByName(this.module_name_winmine); + + // 初始化游戏相关数据 + this.height = this.module_winmine.base.add(this.offset棋盘高度).readU32(); + this.width = this.module_winmine.base.add(this.offset棋盘宽度).readU32(); + this.mine_count = this.module_winmine.base.add(this.offset地雷数量).readU32(); + this.head = this.module_winmine.base.add(0x5340); + this.hWnd = this.module_winmine.base.add(0x5B24).readPointer(); + } + + board_repaint() { + const lpRect = Memory.alloc(4 * 4); + User32.GetClientRect(this.hWnd, lpRect); + + User32.InvalidateRect(this.hWnd, lpRect, 1); + } + + run() { + //遍历棋盘,按行遍历 + for (let i = 0; i < this.height + 2; i++) { + //按列遍历 + let data = []; + for (let j = 0; j < this.width + 2; j++) { + let byte_data = this.head.add(j + 0x20 * i).readU8(); + data.push(byte_data.toString(16).padStart(2, "0")); + + // 如果是地雷,将其状态改为标记 + if (byte_data == 0x8F) { + this.head.add(j + 0x20 * i).writeU8(0x8E); + } + } + console.log(data.join(" ")); + } + + // 重绘窗口区域 + this.board_repaint() + } +} + +let l07 = new L07(); +l07.run(); diff --git a/course/frida/package.json b/course/frida/package.json index f3f4ccc..b53125e 100644 --- a/course/frida/package.json +++ b/course/frida/package.json @@ -7,7 +7,9 @@ "build": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -c", "watch04": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -w", "watch05": "frida-compile ./05_读取棋盘数据/index.ts -o ./build/05.js -w", - "runx": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/05.js" + "watch06": "frida-compile ./06_分析扫雷游戏的数据,显示地雷位置/index.ts -o ./build/06.js -w", + "watch07": "frida-compile ./07_让系统重新绘制指定窗口/index.ts -o ./build/07.js -w", + "runx": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/07.js -q" }, "keywords": [], "author": "", diff --git a/course/frida/winapi/user32.ts b/course/frida/winapi/user32.ts new file mode 100644 index 0000000..7bb0182 --- /dev/null +++ b/course/frida/winapi/user32.ts @@ -0,0 +1,26 @@ +export default class User32 { + // BOOL GetClientRect( + // [in] HWND hWnd, + // [out] LPRECT lpRect + // ); + private static address_GetClientRect: NativePointerValue | null; + static GetClientRect(hWnd: NativePointerValue, lpRect: NativePointerValue): number { + if (this.address_GetClientRect == null) { + this.address_GetClientRect = Module.findExportByName("User32.dll", "GetClientRect"); + } + return new NativeFunction(this.address_GetClientRect!, "bool", ["pointer", "pointer"])(hWnd, lpRect); + } + + // BOOL InvalidateRect( + // [in] HWND hWnd, + // [in] const RECT * lpRect, + // [in] BOOL bErase + // ); + private static address_InvalidateRect: NativePointerValue | null; + static InvalidateRect(hWnd: NativePointerValue, lpRect: NativePointerValue, bErase: number): number { + if (this.address_InvalidateRect == null) { + this.address_InvalidateRect = Module.findExportByName("User32.dll", "InvalidateRect"); + } + return new NativeFunction(this.address_InvalidateRect!, "bool", ["pointer", "pointer", 'bool'])(hWnd, lpRect, bErase); + } +} \ No newline at end of file -- GitLab