From 201149a85d9d15e7aab669f7e355fa59891b7fca Mon Sep 17 00:00:00 2001 From: Knine Date: Tue, 19 Mar 2024 20:02:27 +0800 Subject: [PATCH] =?UTF-8?q?frida=20=E8=AF=BE=E7=A8=8B8-11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index.ts" | 79 +++++++ .../index.ts" | 105 +++++++++ .../index.ts" | 129 +++++++++++ .../index.ts" | 132 +++++++++++ course/frida/package.json | 6 +- course/frida/winapi/kernel32.ts | 39 ++++ course/frida/winapi/user32.ts | 209 ++++++++++++++++++ 7 files changed, 698 insertions(+), 1 deletion(-) create mode 100644 "course/frida/08_\345\260\206\347\233\256\346\240\207\347\252\227\345\217\243\345\210\207\346\215\242\345\210\260\345\211\215\345\217\260/index.ts" create mode 100644 "course/frida/09_\350\216\267\345\217\226\350\275\257\344\273\266\347\252\227\345\217\243\344\275\215\347\275\256\357\274\214\350\256\276\347\275\256\351\274\240\346\240\207\346\214\207\351\222\210\344\275\215\347\275\256/index.ts" create mode 100644 "course/frida/10_\350\256\276\347\275\256\351\274\240\346\240\207\344\275\215\347\275\256\357\274\214\350\207\252\345\212\250\347\202\271\345\207\273\351\274\240\346\240\207/index.ts" create mode 100644 "course/frida/11_\347\224\250\351\274\240\346\240\207\350\207\252\345\212\250\346\240\207\350\256\260\346\243\213\347\233\230\344\270\212\347\232\204\351\233\267\345\214\272/index.ts" create mode 100644 course/frida/winapi/kernel32.ts diff --git "a/course/frida/08_\345\260\206\347\233\256\346\240\207\347\252\227\345\217\243\345\210\207\346\215\242\345\210\260\345\211\215\345\217\260/index.ts" "b/course/frida/08_\345\260\206\347\233\256\346\240\207\347\252\227\345\217\243\345\210\207\346\215\242\345\210\260\345\211\215\345\217\260/index.ts" new file mode 100644 index 0000000..ed13507 --- /dev/null +++ "b/course/frida/08_\345\260\206\347\233\256\346\240\207\347\252\227\345\217\243\345\210\207\346\215\242\345\210\260\345\211\215\345\217\260/index.ts" @@ -0,0 +1,79 @@ +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); + } + + 将目标窗口切换到前台() { + let hForeWnd = User32.GetForegroundWindow(); + let dwCurID = User32.GetCurrentThreadId(); + let dwForeID = User32.GetWindowThreadProcessId(hForeWnd, ptr(0)); + // User32.AttachThreadInput(dwCurID, dwForeID, 1); + User32.ShowWindow(this.hWnd, User32.Const.SW_RESTORE); + + User32.SetForegroundWindow(this.hWnd) + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_TOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_NOTOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + + // User32.AttachThreadInput(dwCurID, dwForeID, 0); + } + + 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() + + this.将目标窗口切换到前台() + } +} + +let l07 = new L07(); +l07.run(); diff --git "a/course/frida/09_\350\216\267\345\217\226\350\275\257\344\273\266\347\252\227\345\217\243\344\275\215\347\275\256\357\274\214\350\256\276\347\275\256\351\274\240\346\240\207\346\214\207\351\222\210\344\275\215\347\275\256/index.ts" "b/course/frida/09_\350\216\267\345\217\226\350\275\257\344\273\266\347\252\227\345\217\243\344\275\215\347\275\256\357\274\214\350\256\276\347\275\256\351\274\240\346\240\207\346\214\207\351\222\210\344\275\215\347\275\256/index.ts" new file mode 100644 index 0000000..8924ded --- /dev/null +++ "b/course/frida/09_\350\216\267\345\217\226\350\275\257\344\273\266\347\252\227\345\217\243\344\275\215\347\275\256\357\274\214\350\256\276\347\275\256\351\274\240\346\240\207\346\214\207\351\222\210\344\275\215\347\275\256/index.ts" @@ -0,0 +1,105 @@ +import User32 from '../winapi/user32' +import Kernel32 from '../winapi/kernel32' + +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); + } + + 将目标窗口切换到前台() { + let hForeWnd = User32.GetForegroundWindow(); + let dwCurID = Kernel32.GetCurrentThreadId(); + let dwForeID = User32.GetWindowThreadProcessId(hForeWnd, ptr(0)); + // User32.AttachThreadInput(dwCurID, dwForeID, 1); + User32.ShowWindow(this.hWnd, User32.Const.SW_RESTORE); + + User32.SetForegroundWindow(this.hWnd) + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_TOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_NOTOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + + // User32.AttachThreadInput(dwCurID, dwForeID, 0); + } + + 获取软件窗口位置_设置鼠标指针位置() { + let lpOrgRect = Memory.alloc(4 * 4); + User32.GetCursorPos(lpOrgRect); + + // typedef struct tagRECT { + // LONG left; + // LONG top; + // LONG right; + // LONG bottom; + // } RECT, *PRECT, *NPRECT, *LPRECT; + let lpRect = Memory.alloc(4 * 4); + User32.GetWindowRect(this.hWnd, lpRect); + console.log("left", lpRect.readU32()); + console.log("top", lpRect.add(4).readU32()); + console.log("right", lpRect.add(8).readU32()); + console.log("bottom", lpRect.add(12).readU32()); + + User32.SetCursorPos(lpRect.readU32(), lpRect.add(4).readU32()); + + Kernel32.Sleep(2000); + User32.SetCursorPos(lpOrgRect.readU32(), lpOrgRect.add(4).readU32()); + + } + + 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() + + this.将目标窗口切换到前台() + this.获取软件窗口位置_设置鼠标指针位置() + } +} + +let l07 = new L07(); +l07.run(); diff --git "a/course/frida/10_\350\256\276\347\275\256\351\274\240\346\240\207\344\275\215\347\275\256\357\274\214\350\207\252\345\212\250\347\202\271\345\207\273\351\274\240\346\240\207/index.ts" "b/course/frida/10_\350\256\276\347\275\256\351\274\240\346\240\207\344\275\215\347\275\256\357\274\214\350\207\252\345\212\250\347\202\271\345\207\273\351\274\240\346\240\207/index.ts" new file mode 100644 index 0000000..b1d38a5 --- /dev/null +++ "b/course/frida/10_\350\256\276\347\275\256\351\274\240\346\240\207\344\275\215\347\275\256\357\274\214\350\207\252\345\212\250\347\202\271\345\207\273\351\274\240\346\240\207/index.ts" @@ -0,0 +1,129 @@ +import User32 from '../winapi/user32' +import Kernel32 from '../winapi/kernel32' + +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); + // 设置鼠标位置_自动点击鼠标 + private start_x = 0; + private start_y = 0; + private step = 16; + + 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); + } + + 将目标窗口切换到前台() { + let hForeWnd = User32.GetForegroundWindow(); + let dwCurID = Kernel32.GetCurrentThreadId(); + let dwForeID = User32.GetWindowThreadProcessId(hForeWnd, ptr(0)); + // User32.AttachThreadInput(dwCurID, dwForeID, 1); + User32.ShowWindow(this.hWnd, User32.Const.SW_RESTORE); + + User32.SetForegroundWindow(this.hWnd) + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_TOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_NOTOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + + // User32.AttachThreadInput(dwCurID, dwForeID, 0); + } + + 获取软件窗口位置_设置鼠标指针位置() { + let lpOrgRect = Memory.alloc(4 * 4); + User32.GetCursorPos(lpOrgRect); + + // typedef struct tagRECT { + // LONG left; + // LONG top; + // LONG right; + // LONG bottom; + // } RECT, *PRECT, *NPRECT, *LPRECT; + let lpRect = Memory.alloc(4 * 4); + User32.GetWindowRect(this.hWnd, lpRect); + console.log("left", lpRect.readU32()); + console.log("top", lpRect.add(4).readU32()); + console.log("right", lpRect.add(8).readU32()); + console.log("bottom", lpRect.add(12).readU32()); + this.start_x = lpRect.readU32() + 7; + this.start_y = lpRect.add(4).readU32() + 92; + console.log("start_x", this.start_x); + console.log("start_y", this.start_y); + + // User32.SetCursorPos(lpRect.readU32(), lpRect.add(4).readU32()); + // Kernel32.Sleep(2000); + // User32.SetCursorPos(lpOrgRect.readU32(), lpOrgRect.add(4).readU32()); + + } + + mouse_click(x: number, y: number, left_click: boolean = true) { + User32.SetCursorPos(this.start_x + this.step * x, this.start_y + this.step * y); + if (left_click) { + User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, User32.GetMessageExtraInfo()); + User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTUP, 0, 0, 0, User32.GetMessageExtraInfo()); + } + else { + User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, User32.GetMessageExtraInfo()); + User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTUP, 0, 0, 0, User32.GetMessageExtraInfo()); + } + } + + 设置鼠标位置_自动点击鼠标() { + this.mouse_click(2, 2, false); + } + + 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() + + this.将目标窗口切换到前台() + this.获取软件窗口位置_设置鼠标指针位置() + this.设置鼠标位置_自动点击鼠标() + } +} + +let l07 = new L07(); +l07.run(); diff --git "a/course/frida/11_\347\224\250\351\274\240\346\240\207\350\207\252\345\212\250\346\240\207\350\256\260\346\243\213\347\233\230\344\270\212\347\232\204\351\233\267\345\214\272/index.ts" "b/course/frida/11_\347\224\250\351\274\240\346\240\207\350\207\252\345\212\250\346\240\207\350\256\260\346\243\213\347\233\230\344\270\212\347\232\204\351\233\267\345\214\272/index.ts" new file mode 100644 index 0000000..cdf490a --- /dev/null +++ "b/course/frida/11_\347\224\250\351\274\240\346\240\207\350\207\252\345\212\250\346\240\207\350\256\260\346\243\213\347\233\230\344\270\212\347\232\204\351\233\267\345\214\272/index.ts" @@ -0,0 +1,132 @@ +import User32 from '../winapi/user32' +import Kernel32 from '../winapi/kernel32' + +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); + // 设置鼠标位置_自动点击鼠标 + private start_x = 0; + private start_y = 0; + private step = 16; + + 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); + } + + 将目标窗口切换到前台() { + let hForeWnd = User32.GetForegroundWindow(); + let dwCurID = Kernel32.GetCurrentThreadId(); + let dwForeID = User32.GetWindowThreadProcessId(hForeWnd, ptr(0)); + // User32.AttachThreadInput(dwCurID, dwForeID, 1); + User32.ShowWindow(this.hWnd, User32.Const.SW_RESTORE); + + User32.SetForegroundWindow(this.hWnd) + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_TOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + // User32.SetWindowPos(this.hWnd, User32.Const.HWND_NOTOPMOST, 0, 0, 0, 0, User32.Const.SWP_NOSIZE | User32.Const.SWP_NOMOVE); + + // User32.AttachThreadInput(dwCurID, dwForeID, 0); + } + + 获取软件窗口位置_设置鼠标指针位置() { + let lpOrgRect = Memory.alloc(4 * 4); + User32.GetCursorPos(lpOrgRect); + + // typedef struct tagRECT { + // LONG left; + // LONG top; + // LONG right; + // LONG bottom; + // } RECT, *PRECT, *NPRECT, *LPRECT; + let lpRect = Memory.alloc(4 * 4); + User32.GetWindowRect(this.hWnd, lpRect); + console.log("left", lpRect.readU32()); + console.log("top", lpRect.add(4).readU32()); + console.log("right", lpRect.add(8).readU32()); + console.log("bottom", lpRect.add(12).readU32()); + this.start_x = lpRect.readU32() + 7; + this.start_y = lpRect.add(4).readU32() + 92; + console.log("start_x", this.start_x); + console.log("start_y", this.start_y); + + // User32.SetCursorPos(lpRect.readU32(), lpRect.add(4).readU32()); + // Kernel32.Sleep(2000); + // User32.SetCursorPos(lpOrgRect.readU32(), lpOrgRect.add(4).readU32()); + + } + + mouse_click(x: number, y: number, left_click: boolean = true) { + User32.SetCursorPos(this.start_x + this.step * x, this.start_y + this.step * y); + if (left_click) { + User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, User32.GetMessageExtraInfo()); + User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTUP, 0, 0, 0, User32.GetMessageExtraInfo()); + } + else { + User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, User32.GetMessageExtraInfo()); + User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTUP, 0, 0, 0, User32.GetMessageExtraInfo()); + } + } + + 设置鼠标位置_自动点击鼠标() { + this.mouse_click(2, 2, false); + } + + run() { + this.将目标窗口切换到前台() + this.获取软件窗口位置_设置鼠标指针位置() + + //遍历棋盘,按行遍历 + 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.mouse_click(j, i, false); + } + // 点击无雷区 + if (byte_data == 0x0F) { + this.mouse_click(j, i); + } + } + 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 b53125e..daff13a 100644 --- a/course/frida/package.json +++ b/course/frida/package.json @@ -9,7 +9,11 @@ "watch05": "frida-compile ./05_读取棋盘数据/index.ts -o ./build/05.js -w", "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" + "watch08": "frida-compile ./08_将目标窗口切换到前台/index.ts -o ./build/08.js -w", + "watch09": "frida-compile ./09_获取软件窗口位置,设置鼠标指针位置/index.ts -o ./build/09.js -w", + "watch10": "frida-compile ./10_设置鼠标位置,自动点击鼠标/index.ts -o ./build/10.js -w", + "watch11": "frida-compile ./11_用鼠标自动标记棋盘上的雷区/index.ts -o ./build/11.js -w", + "runx": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/11.js -q" }, "keywords": [], "author": "", diff --git a/course/frida/winapi/kernel32.ts b/course/frida/winapi/kernel32.ts new file mode 100644 index 0000000..444628e --- /dev/null +++ b/course/frida/winapi/kernel32.ts @@ -0,0 +1,39 @@ + +/* +@param moduleName — Module name or path. +@param exportName +@param retType +@param argTypes +@param abiOrOptions +*/ +function EZ生成NativeFunction(exportName: string, + retType: NativeFunctionReturnType, argTypes: [] | NativeFunctionArgumentType[], + abiOrOptions: NativeABI | NativeFunctionOptions = "default", + moduleName: string = "Kernel32.dll", + ) { + let address = Module.findExportByName(moduleName, exportName); + return new NativeFunction(address!, retType, argTypes, abiOrOptions); +} + +export default class Kernel32 { + private static address_GetCurrentThreadId: NativePointerValue | null; + static GetCurrentThreadId(): number { + if (this.address_GetCurrentThreadId == null) { + this.address_GetCurrentThreadId = Module.findExportByName("Kernel32.dll", "GetCurrentThreadId"); + } + return new NativeFunction(this.address_GetCurrentThreadId!, "int", [])(); + } + + private static func_Sleep: AnyFunction; + static Sleep(dwMilliseconds: number): void { + // void Sleep( + // [in] DWORD dwMilliseconds + // ); + if (this.func_Sleep == null) { + let address = Module.findExportByName("Kernel32.dll", "Sleep"); + this.func_Sleep = new NativeFunction(address!, "void", ["int"]); + } + return this.func_Sleep(dwMilliseconds); + } + +} \ No newline at end of file diff --git a/course/frida/winapi/user32.ts b/course/frida/winapi/user32.ts index 7bb0182..ff7d595 100644 --- a/course/frida/winapi/user32.ts +++ b/course/frida/winapi/user32.ts @@ -1,4 +1,34 @@ + +/* +@param moduleName — Module name or path. +@param exportName +@param retType +@param argTypes +@param abiOrOptions +*/ +function EZ生成NativeFunction(exportName: string, + retType: NativeFunctionReturnType, argTypes: [] | NativeFunctionArgumentType[], + abiOrOptions: NativeABI | NativeFunctionOptions = "default", + moduleName: string = "User32.dll", + ) { + let address = Module.findExportByName(moduleName, exportName); + return new NativeFunction(address!, retType, argTypes, abiOrOptions); +} + export default class User32 { + static Const = { + SW_RESTORE: 9, + HWND_TOPMOST: -1, + HWND_NOTOPMOST: -2, + SWP_NOSIZE: 0x0001, + SWP_NOMOVE: 0x0002, + + MOUSEEVENTF_LEFTDOWN: 0x0002, + MOUSEEVENTF_LEFTUP: 0x0004, + MOUSEEVENTF_RIGHTDOWN: 0x0008, + MOUSEEVENTF_RIGHTUP: 0x0010, + } + // BOOL GetClientRect( // [in] HWND hWnd, // [out] LPRECT lpRect @@ -23,4 +53,183 @@ export default class User32 { } return new NativeFunction(this.address_InvalidateRect!, "bool", ["pointer", "pointer", 'bool'])(hWnd, lpRect, bErase); } + + + // BOOL SetForegroundWindow( + // [in] HWND hWnd + // ); + private static func_SetForegroundWindow: AnyFunction; + static SetForegroundWindow(hWnd: NativePointerValue): number { + if (this.func_SetForegroundWindow == null) { + this.func_SetForegroundWindow = EZ生成NativeFunction("SetForegroundWindow", "bool", ["pointer"]); + } + return this.func_SetForegroundWindow(hWnd); + } + + // BOOL ShowWindow( + // [in] HWND hWnd, + // [in] int nCmdShow + // ); + private static address_ShowWindow: NativePointerValue | null; + static ShowWindow(hWnd: NativePointerValue, nCmdShow: number): number { + if (this.address_ShowWindow == null) { + this.address_ShowWindow = Module.findExportByName("User32.dll", "ShowWindow"); + } + return new NativeFunction(this.address_ShowWindow!, "bool", ["pointer", "int"])(hWnd, nCmdShow); + } + + // BOOL SetWindowPos( + // [in] HWND hWnd, + // [in, optional] HWND hWndInsertAfter, + // [in] int X, + // [in] int Y, + // [in] int cx, + // [in] int cy, + // [in] UINT uFlags + // ); + private static address_SetWindowPos: NativePointerValue | null; + static SetWindowPos(hWnd: NativePointerValue, hWndInsertAfter: number, X: number, Y: number, cx: number, cy: number, uFlags: number): number { + if (this.address_SetWindowPos == null) { + this.address_SetWindowPos = Module.findExportByName("User32.dll", "SetWindowPos"); + } + return new NativeFunction(this.address_SetWindowPos!, "bool", ["pointer", "int", "int", "int", "int", "int", "int"])(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); + } + + private static address_GetForegroundWindow: NativePointerValue | null; + static GetForegroundWindow(): NativePointerValue { + // HWND GetForegroundWindow(); + if (this.address_GetForegroundWindow == null) { + this.address_GetForegroundWindow = Module.findExportByName("User32.dll", "GetForegroundWindow"); + } + return new NativeFunction(this.address_GetForegroundWindow!, "pointer", [])(); + } + + private static address_GetCurrentThreadId: NativePointerValue | null; + static GetCurrentThreadId(): number { + if (this.address_GetCurrentThreadId == null) { + this.address_GetCurrentThreadId = Module.findExportByName("Kernel32.dll", "GetCurrentThreadId"); + } + return new NativeFunction(this.address_GetCurrentThreadId!, "int", [])(); + } + + // DWORD GetWindowThreadProcessId( + // [in] HWND hWnd, + // [out, optional] LPDWORD lpdwProcessId + // ); + private static func_GetWindowThreadProcessId: AnyFunction; + static GetWindowThreadProcessId(hWnd: NativePointerValue, lpdwProcessId: NativePointerValue): number { + if (this.func_GetWindowThreadProcessId == undefined) { + let address = Module.findExportByName("User32.dll", "GetWindowThreadProcessId"); + this.func_GetWindowThreadProcessId = new NativeFunction(address!, "int", ["pointer", "pointer"]); + } + return this.func_GetWindowThreadProcessId(hWnd, lpdwProcessId); + } + + // BOOL AttachThreadInput( + // [in] DWORD idAttach, + // [in] DWORD idAttachTo, + // [in] BOOL fAttach + // ); + private static func_AttachThreadInput: AnyFunction; + static AttachThreadInput(idAttach: number, idAttachTo: number, fAttach: number): number { + if (this.func_AttachThreadInput == null) { + let address_AttachThreadInput = Module.findExportByName("User32.dll", "AttachThreadInput"); + this.func_AttachThreadInput = new NativeFunction(address_AttachThreadInput!, "int", ["int", "int", "int"]); + } + return this.func_AttachThreadInput(idAttach, idAttachTo, fAttach); + } + + // 获取软件窗口位置_设置鼠标指针位置() + private static func_GetWindowRect: AnyFunction; + static GetWindowRect(hWnd: NativePointerValue, lpRect: NativePointerValue): number { + // BOOL GetWindowRect( + // [in] HWND hWnd, + // [out] LPRECT lpRect + // ); + if (this.func_GetWindowRect == null) { + let address = Module.findExportByName("User32.dll", "GetWindowRect"); + this.func_GetWindowRect = new NativeFunction(address!, "bool", ["pointer", "pointer"]); + } + return this.func_GetWindowRect(hWnd, lpRect); + } + + private static func_SetCursorPos: AnyFunction; + static SetCursorPos(X: number, Y: number): number { + // BOOL SetCursorPos( + // [in] int X, + // [in] int Y + // ); + if (this.func_SetCursorPos == null) { + let address = Module.findExportByName("User32.dll", "SetCursorPos"); + this.func_SetCursorPos = new NativeFunction(address!, "bool", ["int", "int"]); + } + return this.func_SetCursorPos(X, Y); + } + + private static func_GetCursorPos: AnyFunction; + static GetCursorPos(lpPoint: NativePointerValue): number { + // BOOL GetCursorPos( + // [out] LPPOINT lpPoint + // ); + if (this.func_GetCursorPos == null) { + let address = Module.findExportByName("User32.dll", "GetCursorPos"); + this.func_GetCursorPos = new NativeFunction(address!, "bool", ["pointer"]); + } + return this.func_GetCursorPos(lpPoint); + } + + private static func_Sleep: AnyFunction; + static Sleep(dwMilliseconds: number): void { + // void Sleep( + // [in] DWORD dwMilliseconds + // ); + if (this.func_Sleep == null) { + let address = Module.findExportByName("Kernel32.dll", "Sleep"); + this.func_Sleep = new NativeFunction(address!, "void", ["int"]); + } + return this.func_Sleep(dwMilliseconds); + } + + //mouse_event + private static func_MouseEvent: AnyFunction; + static MouseEvent(dwFlags: number, dx: number, dy: number, dwData: number, dwExtraInfo: NativePointerValue): void { + // void mouse_event( + // [in] DWORD dwFlags, + // [in] DWORD dx, + // [in] DWORD dy, + // [in] DWORD dwData, + // [in] ULONG_PTR dwExtraInfo + // ); + if (this.func_MouseEvent == null) { + let address = Module.findExportByName("User32.dll", "mouse_event"); + this.func_MouseEvent = new NativeFunction(address!, "void", ["int", "int", "int", "int", "pointer"]); + } + return this.func_MouseEvent(dwFlags, dx, dy, dwData, dwExtraInfo); + } + + //GetMessageExtraInfo + private static func_GetMessageExtraInfo: AnyFunction; + static GetMessageExtraInfo(): NativePointerValue { + // LPARAM GetMessageExtraInfo(); + if (this.func_GetMessageExtraInfo == null) { + let address = Module.findExportByName("User32.dll", "GetMessageExtraInfo"); + this.func_GetMessageExtraInfo = new NativeFunction(address!, "pointer", []); + } + return this.func_GetMessageExtraInfo(); + } + + private static func_MessageBox: AnyFunction; + static MessageBox(hWnd: NativePointerValue, lpText: NativePointerValue, lpCaption: NativePointerValue, uType: number): number { + // int MessageBox( + // [in, optional] HWND hWnd, + // [in, optional] LPCTSTR lpText, + // [in, optional] LPCTSTR lpCaption, + // [in] UINT uType + // ); + if (this.func_MessageBox == null) { + let address = Module.findExportByName("User32.dll", "MessageBoxW"); + this.func_MessageBox = new NativeFunction(address!, "int", ["pointer", "pointer", "pointer", 'int']); + } + return this.func_MessageBox(hWnd, lpText, lpCaption, uType); + } } \ No newline at end of file -- GitLab