$version01 = "A" $version01update = "9.8" ;============================== ; Author: Toady ; Site: www.itoady.com ; Updated: May 21, 2008 ; AutoIt Ver: 3.2.12.0 ; ; A * Searching Alorithm ; Artificial Intelligence ; Robot path finding ;============================== #include #include #Include #Include #include ;#include "FastFind.au3" #include #include #RequireAdmin ; ko thong bao khi thieu var co them quyen admin ghi vao bo x32 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "WinHttp.au3" #include "demem.au3" #include #include ;#include "VirtDsktLibrary01.au3" #include #include _WinAPI_SetErrorMode($SEM_FAILCRITICALERRORS Or $SEM_NOGPFAULTERRORBOX) $process_autoit01 = @AutoItPID Global $procHwnd_autoit01 = _Memoryopen($process_autoit01,0x1f0fff,0) Global $width05 = 50 Global $height05 = 50 Global $sx = 9 Global $sy = 11 Global $gx = 22 Global $gy = 22 ; ============================ ; Khởi tạo vùng nhớ BFS 50x50 ; ============================ Global $mapBase = _MemVirtualAlloc(0x0, 0x9C4, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; MAP[50][50] = 2500 ô × 1 byte = 2500 bytes Global $visitedBase = _MemVirtualAlloc(0x0, 0x9C4, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; Visited[50][50] = 2500 ô × 1 byte = 2500 bytes Global $prevBase = _MemVirtualAlloc(0x0, 0x4E20, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; Prev[50][50][2] = 5000 ô × 4 bytes = 20,000 bytes Global $queueBase = _MemVirtualAlloc(0x0, 0x4E20, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; Queue[2500][2] = 5000 ô × 4 bytes = 20,000 bytes Global $pathBase = _MemVirtualAlloc(0x0, 0x4E20, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; Path[2500][2] = 5000 ô × 4 bytes = 20,000 bytes Global $BFS = _MemVirtualAlloc(0x0, 0x1000, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; BFS variables (front, rear, sx, sy, gx, gy) giữ nguyên 4096 bytes Global $newmem = _MemVirtualAlloc(0x0, 0x2000, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; newmem workspace giữ nguyên 8192 bytes Global $rows = 50 Global $cols = 50 Global $data_map[$rows][$cols] = [ _ ["x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x","0","0","0","x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x","x","x","x","x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","x"], _ ["x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x"]] Func SyncMapToMemory01($hProc, $pMapBase) For $y = 0 To $rows - 1 For $x = 0 To $cols - 1 Local $char = $data_map[$y][$x] Local $byteVal = Asc($char) ; Chuyển ký tự thành giá trị số (ví dụ: 'x' = 120) ; Ghi từng byte vào địa chỉ tương ứng ; Mỗi ô nhớ cách nhau 1 byte (offset = y * 50 + x) Local $offset = ($x * $cols) + $y _MemoryWrite64($pMapBase + $offset, $hProc, ptr($byteVal), 'byte[1]') Next Next EndFunc Func SyncMapToMemory02($hProc, $pMapBase) ; Duyệt theo cột trước (X), hàng sau (Y) để khớp với cách bạn đã tìm ra offset ($x * $cols + $y) For $x = 0 To $cols - 1 Local $string_x_add01 = "" For $y = 0 To $rows - 1 Local $char = $data_map[$y][$x] Local $byteVal = Asc($char) $string_x_add01 &= Hex($byteVal, 2) Next ; Offset bây giờ được tính theo X (cột) ; Vì mỗi cột có 50 ô (rows), nên $x * 50 sẽ nhảy sang cột tiếp theo Local $offset = ($x * $rows) _MemoryWrite64($pMapBase + $offset, $hProc, "0x" & $string_x_add01, 'byte[50]') Next EndFunc ; ============================ ; Tạo buffer ASM 64-bit tại BFS ; ============================ Global $startBFS = ASM64_opcode02vtmem("1000",$BFS) ; Ghi opcode NOP và RET ;DllStructSetData($startBFS, "ASM", 0x90C3, 1) ; ASM[1] = NOP ;DllStructSetData($startBFS, "ASM", 0xC3, 2) ; ASM[2] = RE Global $startBFS_address = DllStructGetPtr( $startBFS ) _cmp_BFS01($mapBase,$visitedBase,$prevBase,$queueBase,$pathBase,$BFS,$newmem,$startBFS) ; Khởi tạo timer Local $hTimer = TimerInit() SyncMapToMemory02($procHwnd_autoit01, $mapBase) $pathArray = _BFS_RESET01($sx,$sy,$gx,$gy,$procHwnd_autoit01,$startBFS_address,$mapBase,$visitedBase,$prevBase,$queueBase,$pathBase,$newmem) Local $elapsed = TimerDiff($hTimer) _ArrayDisplay($pathArray, $elapsed & " ms01") ; Khởi tạo timer Local $hTimer = TimerInit() Global $sx = 9 Global $sy = 11 Global $gx = 22 Global $gy = 44 SyncMapToMemory02($procHwnd_autoit01, $mapBase) $pathArray = _BFS_RESET01($sx,$sy,$gx,$gy,$procHwnd_autoit01,$startBFS_address,$mapBase,$visitedBase,$prevBase,$queueBase,$pathBase,$newmem) ; Tính thời gian đã trôi qua (ms) Local $elapsed = TimerDiff($hTimer) _ArrayDisplay($pathArray, $elapsed & " ms02") ; ===================================================================== ; TÍCH HỢP GDI+ ĐỂ VẼ BẢN ĐỒ VÀ ĐƯỜNG ĐI ASM TÌM ĐƯỢC ; ===================================================================== ; Khởi tạo GDI+ và tạo cửa sổ hiển thị _GDIPlus_Startup() Local $tileW = 12, $tileH = 12 Local $GUI_W = 50 * $tileW ; Map 50 ô Local $GUI_H = 50 * $tileH ; Map 50 ô Global $hGUI_Map = GUICreate("Radar ASM BFS - 50x50", $GUI_W, $GUI_H) Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI_Map) GUISetState(@SW_SHOW, $hGUI_Map) ; Tạo các bảng màu (Brush) Global $BrushWall = _GDIPlus_BrushCreateSolid(0xFF333333) ; Xám đen (Tường - x) Global $BrushPath = _GDIPlus_BrushCreateSolid(0xFFEEEEEE) ; Trắng xám (Đường trống - 0) Global $BrushRoute = _GDIPlus_BrushCreateSolid(0xFF00AFFF) ; Xanh dương (Đường đi của ASM) Global $BrushStart = _GDIPlus_BrushCreateSolid(0xFF00FF00) ; Xanh lá cây (Điểm Start) Global $BrushGoal = _GDIPlus_BrushCreateSolid(0xFFFF0000) ; Đỏ (Điểm Goal) ; 1. Vẽ nền bản đồ (Đọc thẳng từ RAM chứa mapBase) For $y = 0 To 49 For $x = 0 To 49 Local $addr = $mapBase + ($x * 50 + $y) ; Đọc 1 byte từ RAM và ép về ký tự Local $val = Chr(_MemoryRead64($addr, $procHwnd_autoit01, "byte[1]", "dec")) If $val == "x" Then _GDIPlus_GraphicsFillRect($hGraphic, $x * $tileW, $y * $tileH, $tileW, $tileH, $BrushWall) Else _GDIPlus_GraphicsFillRect($hGraphic, $x * $tileW, $y * $tileH, $tileW, $tileH, $BrushPath) EndIf Next Next ; 2. Vẽ đường đi (Dựa vào mảng $pathArray do ASM trả về) If IsArray($pathArray) Then ; Chạy từ 1 để không tô đè lên Goal (index 0) For $i = 1 To UBound($pathArray) - 1 Local $px = $pathArray[$i][0] Local $py = $pathArray[$i][1] ; Vẽ đường đi bằng màu xanh dương _GDIPlus_GraphicsFillRect($hGraphic, $px * $tileW, $py * $tileH, $tileW, $tileH, $BrushRoute) Next EndIf ; 3. Vẽ đè làm nổi bật điểm Start và Goal _GDIPlus_GraphicsFillRect($hGraphic, $sx * $tileW, $sy * $tileH, $tileW, $tileH, $BrushStart) _GDIPlus_GraphicsFillRect($hGraphic, $gx * $tileW, $gy * $tileH, $tileW, $tileH, $BrushGoal) ; Vòng lặp giữ cửa sổ không bị tắt While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Dọn dẹp RAM đồ họa sau khi tắt cửa sổ Radar _GDIPlus_BrushDispose($BrushWall) _GDIPlus_BrushDispose($BrushPath) _GDIPlus_BrushDispose($BrushRoute) _GDIPlus_BrushDispose($BrushStart) _GDIPlus_BrushDispose($BrushGoal) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() GUIDelete($hGUI_Map) ; ... (Có thể gọi tiếp các hàm khác sau khi đóng bảng vẽ) ... Func _BFS_RESET01($sx0,$sy0,$gx0,$gy0,$procHwnd0,$startBFS_address0,$mapBase0,$visitedBase0,$prevBase0,$queueBase0,$pathBase0,$newmem0) _MemoryWrite64($startBFS_address0+0x24, $procHwnd0, ptr($sx0),'byte[1]') ; reset value = 0 _MemoryWrite64($startBFS_address0+0x2C, $procHwnd0, ptr($sy0),'byte[1]') ; reset value = 0 _MemoryWrite64($startBFS_address0+0x34, $procHwnd0, ptr($gx0),'byte[1]') ; reset value = 0 _MemoryWrite64($startBFS_address0+0x3C, $procHwnd0, ptr($gy0),'byte[1]') ; reset value = 0 ; gọi hàm ASM tại địa chỉ $startBFS_address DllCallAddress("uint:cdecl", $startBFS_address0) ; Fill toàn bộ vùng nhớ bằng 0 ;DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $mapBase, "dword", 0x9C4, "byte", 0) DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $visitedBase, "dword", 0x9C4, "byte", 0) DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $prevBase, "dword", 0x4E20, "byte", 0) DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $queueBase, "dword", 0x4E20, "byte", 0) DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $pathBase, "dword", 0x4E20, "byte", 0) ;ClipPut($mapBase0) Return GetPathArray($newmem+0x1000, $procHwnd0 ) EndFunc ;ClipPut($newmem+0x1000) ;_ArrayDisplay($pathArray, $elapsed & " ms") ; tạo mảng 2D bản đồ Global $map[$height05][$width05] ; khởi tạo toàn bộ bằng "." For $y = 0 To $height05-1 For $x = 0 To $width05-1 $map[$y][$x] = "." Next Next ; đánh dấu đường đi For $i = 0 To UBound($pathArray)-1 Local $px = $pathArray[$i][0] Local $py = $pathArray[$i][1] $map[$py][$px] = "*" Next ; đánh dấu start và goal $map[$sy][$sx] = "S" $map[$gy][$gx] = "G" ; hiển thị bằng ArrayDisplay ;_ArrayDisplay($map, "Bản đồ 20x20 với đường đi") Func GetPathArray($baseAddr, $procHwnd) ; đọc số bước (dword tại offset 0) Local $steps = _MemoryRead64($baseAddr, $procHwnd, 'byte[4]', "dec") ;MsgBox("","check","$baseAddr = "&$baseAddr& "$steps = "&$steps,0) ; tạo mảng chứa các cặp tọa độ Local $path[1][2] If $steps > 1 and $steps < 100 Then Local $path[$steps][2] ; $path[0][0] = $gx0 ; x ; $path[0][1] = $gy0 ; y For $i = 0 To $steps - 1 ; mỗi bước chiếm 16 byte (0x10) Local $x0 = _MemoryRead64($baseAddr + (0x8 * $i)+0x4, $procHwnd, 'byte[4]', "dec") Local $y0 = _MemoryRead64($baseAddr + (0x8 * $i)+0x8, $procHwnd, 'byte[4]', "dec") If $x0 <> 0 and $y0 <> 0 Then $path[$i][0] = $x0 ; x $path[$i][1] = $y0 ; y EndIf Next Return $path EndIf Return $path EndFunc Func _MemoryRead6401($ivAddress, $ahHandle, $sType = "dword", $value_type00="not_hex") ; type = ( byte, float, dword, char[], byte[] ... etc ) If Not IsArray($ahHandle) Then SetError(1, 0, False) Return 0 EndIf Local $vReadData = DllStructCreate("dword_ptr") ; hex > dec Local $vReadData01 = DllStructCreate($sType) ; hex array bytes Local $vNumberOfBytesRead = DllStructCreate("ulong_ptr lpNumberOfBytesRead") If @Error Then SetError(@Error + 1) Return 0 EndIf If Not @Error Then Local $ahCall = DllCall($ahHandle[0], "bool", "ReadProcessMemory", _ "handle", $ahHandle[1], _ "dword_ptr", $ivAddress, _ "ptr", DllStructGetPtr($vReadData01), _ "ulong_ptr", DllStructGetSize($vReadData01), _ "ptr", DllStructGetPtr($vNumberOfBytesRead)) ;ConsoleWrite(DllStructGetData($vNumberOfBytesRead, "lpNumberOfBytesRead") & @CRLF & DllStructGetSize($vReadData01) & @CRLF) If (Not $ahCall[0]) Or (DllStructGetData($vNumberOfBytesRead, "lpNumberOfBytesRead") <> DllStructGetSize($vReadData01)) Then SetError(2, 0, False) ;Return False EndIf If $value_type00 <> "Hex" Then Local $DllStructGetData_fix01 = DllStructGetData($vReadData01, 1) If StringInStr($sType, 'wchar') > 0 Then $DllStructGetData_fix01 = StringRegExpReplace($DllStructGetData_fix01, "[^\x20-\x7E]", "") ; giữ lại ký tự ASCII printable Return $DllStructGetData_fix01 EndIf If $value_type00 = "Hex" Then Return Hex("0x"&(DllStructGetData($vReadData01, 1))) EndIf EndFunc ;==>_Process_ReadMemory Func _cmp_BFS01($mapBase0,$visitedBase0,$prevBase0,$queueBase0,$pathBase0,$BFS0,$newmem0,$startBFS0) $int_20 = 32 ; width hex 32 dec 50 $op_code00 = "" $op_code01 = "" ;// DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", DllStructGetPtr($tPixelData), "ptr", DllStructGetPtr($tStruct_ARGB), "int", $iPixels) ;// ;64Bit! -> ;first 4 parameters will be saved in rcx,rdx,r8,r9 ;push rdi ;push rsi ;push rbx ;push rbp $op_code01 &= "57 56 53 55 48 8B F1" ; mov r14, newmem // r14 = base của newmem $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov [r14+0], 0 // $front = 0 r10 = $front ;mov [r14+4], 1 // $rear = 1 r11 = $rear ;mov [r14+10], (Int)9 // $sx rsi = $sx ;mov [r14+14], (Int)11 // $sy rdi = $sy ;mov [r14+20], (Int)19 // $gx r12 = $gx ;mov [r14+24], (Int)19 // $gy r13 = $gy ;mov [r14+30], (Int)10 // $px ;mov [r14+34], (Int)10 // $py ;mov r10d, [r14+0] // Global $front = 0 ;mov r11d, [r14+4] // Global $rear = 1 ;mov rsi, [r14+10] // Global rsi = $sx ;mov rdi, [r14+14] // Global rdi = $sy $op_code01 &= "41 C7 06 00 00 00 00 41 C7 46 04 01 00 00 00 41 C7 46 10 09 00 00 00 41 C7 46 14 0B 00 00 00 41 C7 46 20 13 00 00 00 41 C7 46 24 13 00 00 00 41 C7 46 30 0A 00 00 00 41 C7 46 34 0A 00 00 00 45 8B 16 45 8B 5E 04 49 8B 76 10 49 8B 7E 14" ;mov r15, queueBase // r15 = base của Queue ;mov [r15+0],rsi // $Queue[0][0] = $sx ;mov [r15+4],rdi // $Queue[0][1] = $sy $op_code01 &= "49 BF "&_ReadF($queueBase0,0) $op_code01 &= "49 89 37 49 89 7F 04" ;// Gán "s" vào MAP[$sx][$sy] ; mov r14, newmem // r14 = base của newmem $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov esi, [r14+10] // $sx = 9 ;mov edi, [r14+14] // $sy = 11 ;imul edx, esi, (Int)20 // edx = $sx * 20 ;add edx, edi // edx = $sx * 20 + $sy $op_code01 &= "41 8B 76 10 41 8B 7E 14 69 D6 "&$int_20&" 00 00 00 01 FA" ;mov rsi, mapBase // base của MAP $op_code01 &= "48 BE "&_ReadF($mapBase0,0) ;mov r14, rsi ;add r14, edx // rax = địa chỉ MAP[$sx][$sy] ;mov byte ptr [r14], 's' // gán ký tự 's' $op_code01 &= "4C 8B F6 49 01 D6 41 C6 06 73" ;//Gán "g" vào MAP[$gx][$gy] ; mov r14, newmem $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov esi, [r14+20] // $gx ;mov edi, [r14+24] // $gy ;imul edx, esi, (Int)20 ;add edx, edi // edx = $gx * 20 + $gy $op_code01 &= "41 8B 76 20 41 8B 7E 24 69 D6 "&$int_20&" 00 00 00 01 FA" ;mov rsi, mapBase // base của MAP $op_code01 &= "48 BE "&_ReadF($mapBase0,0) ;mov r14, rsi ;add r14, edx ;mov byte ptr [r14], 'g' // gán ký tự 'g' $op_code01 &= "4C 8B F6 49 01 D6 41 C6 06 67" ;// $Visited[$sx][$sy] = 1 ; mov r14, newmem $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov esi, [r14+10] // Global esi = $sx = 10 ;mov edi, [r14+14] // Global edi = $sy = 10 $op_code01 &= "41 8B 76 10 41 8B 7E 14" ; mov r14, visitedBase // base của Visited $op_code01 &= "49 BE "&_ReadF($visitedBase0,0) ;mov rdx, esi // rdx = $sx ;imul rdx, (Int)20 // rdx = $sx * 20 ;add rdx, edi // rdx = $sx * 20 + $sy ;mov byte ptr [r14+rdx], 1 // Visited[$sx][$sy] = 1 $op_code01 &= "48 8B D6 48 6B D2 "&$int_20&" 48 01 FA 42 C6 04 32 01" ;// Func BFS_Search($gx, $gy) ---------------------------------------- ; mov r14, newmem // r14 = base của newmem $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov r15, queueBase // r15 = base của Queue $op_code01 &= "49 BF "&_ReadF($queueBase0,0) ;mov r10d, [r14+0] // r10d = front ;mov r11d, [r14+4] // r11d = rear ;mov r12d, [r14+20] // r12d = gx ;mov r13d, [r14+24] // r13d = gy ;mov ecx, 1 // ecx = i = 1 ;LoopStart: ;cmp ecx, 9C4 // For $i = 1 to 2500 $op_code01 &= "45 8B 16 45 8B 5E 04 45 8B 66 20 45 8B 6E 24 B9 01 00 00 00 81 F9 C4 09 00 00" ;jge LoopEnd $op_code01 &= "0F 8D 95 01 00 00" ;cmp r10d, r11d // If $front < $rear Then ;jge SkipBody ;imul r8d, r10d, 8 // offset = front * 8 ;mov rdx, r15 // rdx = base của Queue ;add rdx, r8 // rdx = Queue + offset ;mov esi, [rdx] // $x = Queue[front][0] ;mov edi, [rdx+4] // $y = Queue[front][1] ;inc r10d // $front += 1 $op_code01 &= "45 39 DA 0F 8D 85 01 00 00 45 6B C2 08 49 8B D7 4C 01 C2 8B 32 8B 7A 04 41 FF C2" ;cmp esi, r12d // If $x = $gx ;jne SkipCheck ; cmp edi, r13d // And $y = $gy ; jne SkipCheck ;// Đến đích rồi → dùng lại thanh ghi thoải mái ;jmp LoopEnd // ExitLoop nếu đến đích ;SkipCheck: ;mov [r14+30], esi // lưu $x cũ ;mov [r14+34], edi // lưu $y cũ $op_code01 &= "44 39 E6 75 1B 90 90 90 90 44 39 EF 75 12 90 90 90 90 E9 63 01 00 00 90 90 90 90 90 90 90 90 90 41 89 76 30 41 89 7E 34" ;mov r9d, 0 // For $d = 0 to 3 ;DirectionLoop: ;cmp r9d, 4 // kiểm tra d < 4 ;jge EndDirection ;mov eax, [r14+30] // load $nx = $x cũ ;mov ebx, [r14+34] // load $ny = $y cũ $op_code01 &= "41 B9 00 00 00 00 41 83 F9 04 0F 8D 3B 01 00 00 41 8B 46 30 41 8B 5E 34" ;cmp r9d, 0 ;jne Case1 ;dec eax // Case 0: $ny -= 1 → đi sang trái (←) ;jmp AfterSwitch ;Case1: ;cmp r9d, 1 ;jne Case2 ;inc eax // Case 1: $ny += 1 → đi sang phải (→) lỗi ;jmp AfterSwitch ;Case2: ;cmp r9d, 2 ;jne Case3 ;dec ebx // Case 2: $nx -= 1 → đi lên (↑) ;jmp AfterSwitch ;Case3: ;inc ebx // Case 3: $nx += 1 → đi xuống (↓) lỗi ;AfterSwitch: ;mov rsi, eax // rsi = nx hiện tại ;mov rdi, ebx // rdi = ny hiện tại $op_code01 &= "41 83 F9 00 75 14 90 90 90 90 FF C8 EB 42 90 90 90 90 90 90 90 90 90 90 90 90 41 83 F9 01 75 14 90 90 90 90 FF C0 EB 28 90 90 90 90 90 90 90 90 90 90 90 90 41 83 F9 02 75 14 90 90 90 90 FF CB EB 0E 90 90 90 90 90 90 90 90 90 90 90 90 FF C3 48 8B F0 48 8B FB" ;// If $nx < 0 Or $ny < 0 Or $nx >= 20 Or $ny >= 20 Then ContinueLoop ;cmp rsi, 0 // $nx < 0 ;jl SkipDirection ;cmp rdi, 0 // $ny < 0 ;jl SkipDirection ;cmp rsi, (Int)20 // $nx >= 20 ;jnl SkipDirection ;cmp rdi, (Int)20 // $ny >= 20 ;jnl SkipDirection ;// end kiểm tra biên $op_code01 &= "48 83 FE 00 0F 8C CB 00 00 00 48 83 FF 00 0F 8C C1 00 00 00 48 81 FE "&$int_20&" 00 00 00 0F 8D B4 00 00 00 48 81 FF "&$int_20&" 00 00 00 0F 8D A7 00 00 00" ;// If $MAP[$nx][$ny] = "x" Or $Visited[$nx][$ny] = 1 Then ContinueLoop ;mov r8d, rsi ;imul r8d, (Int)20 ;add r8d, rdi // r8d = nx * 20 + ny $op_code01 &= "4C 8B C6 45 6B C0 "&$int_20&" 49 01 F8" ;mov rdx, mapBase $op_code01 &= "48 BA "&_ReadF($mapBase0,0) ;add rdx, r8 ;mov al, [rdx] // đọc MAP[nx][ny] ;cmp al, 'x' // nếu là 'x' thì bỏ qua ;je SkipDirection $op_code01 &= "4C 01 C2 8A 02 3C 78 0F 84 86 00 00 00" ; mov rdx, visitedBase $op_code01 &= "48 BA "&_ReadF($visitedBase0,0) ;add rdx, r8 ;mov al, [rdx] // kiểm tra Visited[nx][ny] = 1 ;cmp al, 1 ;je SkipDirection ;// end kiểm tra chướng ngại và đã đi ;mov [r14+40], rsi // lưu $nx hiện tại ;mov [r14+44], rdi // lưu $ny hiện tại $op_code01 &= "4C 01 C2 8A 02 3C 01 74 73 90 90 90 90 49 89 76 40 49 89 7E 44" ; // $Visited[$nx][$ny] = 1 $op_code01 &= "48 BA "&_ReadF($visitedBase0,0) ;mov r8d, rsi ;imul r8d, (Int)20 ;add r8d, rdi // r8d = nx * 20 + ny ;add rdx, r8 ;mov byte ptr [rdx], 1 $op_code01 &= "4C 8B C6 45 6B C0 "&$int_20&" 49 01 F8 4C 01 C2 C6 02 01" ;// $Prev[$nx][$ny][0] = $x ;// $Prev[$nx][$ny][1] = $y ;mov rax, rsi // rsi = nx ;imul rax, (Int)20 // bị đổi thành imul rax,rax,14 ;add rax, rdi // rax = nx*20 + ny ;shl rax, 3 // *8 $op_code01 &= "48 8B C6 48 6B C0 "&$int_20&" 48 01 F8 48 C1 E0 03" ;mov rdx, prevBase $op_code01 &= "48 BA "&_ReadF($prevBase0,0) ;add rdx, rax ;mov esi, [r14+30] // load $x lúc đầu ;mov edi, [r14+34] // load $y lúc đầu ;mov [rdx], esi // x hiện tại ;mov [rdx+4], edi // y hiện tại ;mov rsi, [r14+40] // load $nx hiện tại ;mov rdi, [r14+44] // load $ny hiện tại $op_code01 &= "48 01 C2 41 8B 76 30 41 8B 7E 34 89 32 89 7A 04 49 8B 76 40 49 8B 7E 44" ;// $Queue[$rear][0] = $nx ;// $Queue[$rear][1] = $ny ;mov eax, r11d // eax = rear ;imul eax,eax,08 // eax = rear * 8 $op_code01 &= "41 8B C3 6B C0 08" ;mov rdx, queueBase $op_code01 &= "48 BA "&_ReadF($queueBase0,0) ;add rdx, rax ;mov [rdx+0], rsi // Queue[rear][0] = nx ;mov [rdx+4], rdi // Queue[rear][1] = ny ;//mov r10d, r11d // eax = rear bớt đường đi ;inc r11d // $rear += 1 ;SkipDirection: ;inc r9d // d++ ;jmp DirectionLoop ;EndDirection: ;SkipBody: ;inc ecx // i++ ;jmp LoopStart ;LoopEnd: $op_code01 &= "48 01 C2 48 89 32 48 89 7A 04 41 FF C3 41 FF C1 E9 BB FE FF FF FF C1 E9 5F FE FF FF" ; push r15 $op_code01 &= "41 57" ; mov r15, newmem+1000 // r15 = địa chỉ bắt đầu ghi đường đi 4096 = 0x1000 $op_code01 &= "49 BF "&_ReadF($newmem0+0x1000,0) ; mov r14, newmem // r14 = base chứa các biến sx, sy, gx, gy $op_code01 &= "49 BE "&_ReadF($newmem0,0) ;mov esi, [r14+20] // esi = gx (tọa độ x đích) ;mov edi, [r14+24] // edi = gy (tọa độ y đích) ;xor rbx, rbx // rbx = số bước đã ghi = 0 $op_code01 &= "41 8B 76 20 41 8B 7E 24 48 31 DB" ;LoopBack: ; cmp rbx, (Int)400 // giới hạn số bước tối đa ; jge ExitLoop // nếu vượt quá → thoát ; imul rcx, rbx, 8 // rcx = offset của bước thứ rbx ; add rcx, 4 // bỏ qua ô đầu tiên chứa số bước ; mov rdx, r15 ; add rdx, rcx // rdx = địa chỉ ghi bước hiện tại ; mov [rdx], esi // ghi x vào Path[rbx][0] ; mov [rdx+4], edi // ghi y vào Path[rbx][1] ; inc rbx // tăng số bước $op_code01 &= "48 81 FB 90 01 00 00 7D 68 90 90 90 90 48 6B CB 08 48 83 C1 04 49 8B D7 48 01 CA 89 32 89 7A 04 48 FF C3" ; // === Truy ngược từ prevBase[x][y] === ; mov eax, esi // eax = x ; imul eax, (Int)20 // x * 20 ; add eax, edi // x * 20 + y ; imul eax, 8 // offset trong prevBase $op_code01 &= "8B C6 6B C0 "&$int_20&" 01 F8 6B C0 08" ; mov r13, prevBase $op_code01 &= "49 BD"&_ReadF($prevBase0,0) ; add r13, rax // r13 = địa chỉ prevBase[x][y] ; mov esi, [r13] // esi = px (tọa độ x bước trước) ; mov edi, [r13+4] // edi = py (tọa độ y bước trước) $op_code01 &= "49 01 C5 41 8B 75 00 41 8B 7D 04" ; // === Kiểm tra đã về tới nguồn chưa === ; cmp esi, [r14+10] // sx ; jne LoopBack ; cmp edi, [r14+14] // sy ; jne LoopBack $op_code01 &= "41 3B 76 10 75 B8 41 3B 7E 14 75 B2" ; // === Ghi bước cuối cùng (nguồn) === ; cmp rbx, (Int)400 ; jge ExitLoop ; imul rcx, rbx, 8 ; add rcx, 4 ; mov rdx, r15 ; add rdx, rcx ; mov [rdx], esi // ghi sx vào Path[rbx][0] ; mov [rdx+4], edi // ghi sy vào Path[rbx][1] ; inc rbx ;ExitLoop: ;mov dword ptr [r15], ebx // ghi tổng số bước vào Path[0] ;pop r15 // khôi phục r15 $op_code01 &= "48 81 FB 90 01 00 00 7D 1A 90 90 90 90 48 6B CB 08 48 83 C1 04 49 8B D7 48 01 CA 89 32 89 7A 04 48 FF C3 41 89 1F 41 5F" ;pop rbp ;pop rbx ;pop rsi ;pop rdi ;ret // kết thúc an toàn $op_code01 &= "5D 5B 5E 5F C3" $op_code01 &= "" $op_code00 &= $op_code01 $op_code00 = StringReplace($op_code00, " ", "") $startBFS0.ASM = "0x"&$op_code00 EndFunc Func ASM64_opcode02vtmem($bytes0="1000", $alloc_address0=0) ; Tạo struct byte ASM[$bytes0] tại địa chỉ $alloc_address0 Local $tCodeBuffer = _DllStructCreate64("byte ASM[" & $bytes0 & "]", $alloc_address0) Return $tCodeBuffer EndFunc Func _DllStructCreate64($struct, $alloc_address0=0) ; align auf 16-byte adresse ; Nếu có địa chỉ cấp phát thì dùng luôn If $alloc_address0 <> 0 Then Local $sstruct = DllStructCreate($struct, $alloc_address0) Return $sstruct EndIf ; Nếu không có địa chỉ thì tự cấp phát mới Local $temp = DllStructCreate($struct) Local $tempsize = DllStructGetSize($temp) + 64 Local $ptr = DllStructGetPtr($temp) Local $a1 = Mod(Number($ptr), 64) Local $mem = _MemVirtualAlloc($ptr + $a1, $tempsize, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) Local $a2 = Mod(Number($mem), 64) ; rest div 16 adresse = offset Local $sstruct = DllStructCreate($struct, (Number($mem) - $a2 + 64)) Return $sstruct ; auf 16 aligned pointer EndFunc ; Tạo GUI Global $hGUI = GUICreate("Memory Alloc Viewer", 600, 400) Global $editBox = GUICtrlCreateEdit("", 10, 10, 580, 380, BitOR($ES_AUTOVSCROLL, $ES_MULTILINE, $WS_VSCROLL)) ; Đặt font monospace để căn thẳng hàng GUICtrlSetFont($editBox, 10, 400, 0, "Consolas") ; Tạo text với StringFormat (cột cố định) Local $text = "" $text &= StringFormat("%-16s 0x%s size=0x%X\n", "mapBase", Hex($mapBase, 16), 0x9C4) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "visitedBase", Hex($visitedBase, 16), 0x9C4) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "prevBase", Hex($prevBase, 16), 0x4E20) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "queueBase", Hex($queueBase, 16), 0x4E20) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "pathBase", Hex($pathBase, 16), 0x4E20) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "BFS", Hex($BFS, 16), 0x1000) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "newmem", Hex($newmem, 16), 0x2000) & @CRLF $text &= StringFormat("%-16s 0x%s size=0x%X\n", "startBFS_address", Hex($startBFS_address, 16), 0x1000) & @CRLF GUICtrlSetData($editBox, $text) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd