|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-12, 02:45 AM | #1 (permalink) |
榮譽會員
|
從遊戲中得到動態記憶體資料(彙編+VC 例子:瘋狂坦克的X坐標)
sbsummer(原作)
各位朋友大家好,嗷嗷,我第一次在這裡發文章,好高興 本人技術有限,不要笑話,如有錯誤請您告訴我一聲[em09]。 剛才我玩了幾把瘋狂坦克,輸了好幾盤,覺得無聊就搞搞這個,下面開始說說如何得到遊戲中的動態資料( 位址改變),以得到瘋狂坦克中坦克X坐標為例 ------------------------------------------------------------------------------ 工具: SoftICE動態偵錯程序,遊戲修改工具(金山遊俠),反彙編(W32Dasm),Hex Workshop ------------------------------------------------------------------------------ 一、找到記憶體中坦克X坐標 1、用金山遊俠搜尋,方法如下(金山遊俠的使用我就不說了) 把坦克往左移動一些,就搜尋「減少」;坦克往右移動,就搜尋「增大」 反覆搜尋將會找到一個位址(當然其他遊戲可能不止一個),這裡是08BFAACC 註:動態的記憶體分配就是下次你如果再次搜尋,位址將不再是08BFAACC 2、找到那條程式碼修改了這個資料(X坐標) 載入 SoftIce 在遊戲狀態 Ctrl+D 調出SoftIce,輸入 BPM 08BFAACC W,這裡的W表示如果這個位址被寫將中斷 回到遊戲,移動坦克,左移一下,程序中斷,SoftIce指向的上面一句是 004640B3 MOV DWORD PTR [ESI+000001A4],EAX 這句就是修改坦克坐標的程式碼,當然右移也能找到一句,這裡就不重複了 3、修改程序使動態的資料變成靜態 這裡說點題外話,修改程序包括兩種,一種是直接修改程序,一種是修改記憶體中的程序(記憶體修正檔) ,這裡由於我懶,所以用了第一種 修改程序: 瘋狂坦克程序存在Fortress2.dat當中,如果你把這個文件改名為EXE文件一樣可以執行,這裡我 們就把他修改成Fortress2.exe 開啟W32Dasm反彙編,SHIFT+F12跳到004046B3,你看到這幾行 004046B3 8986A4010000 MOV DWORD PTR [ESI+000001A4],EAX 004046B9 8B8644020000 MOV EAX,DWORD PTR [ESI+00000244] 004046BF C744241001000000 MOV [ESP+10],00000001 剛才我們說了004046B3是修改X坐標的那條語句,現在我們要讓他每次修改完程序就能夠把X坐標 存儲到一個類BIOS的位址 現在要讓它執行到這裡就JMP到一個我們自己的程式碼的地方,於是在程序的尾部我們找到一段空 白的區域00465A52,於是我修改004046BF為程式碼 JMP 00465A52,機器碼為E98E130600,因為這句的長度不夠以前的那句長,所以要加入幾個NOP,機器碼為90,所以我們開啟HEX Workshop修改程序,CTRL+G跳到位移為000046BF的地方,看到了C744241001000000,我們把它修改為E98E130600909090,現在程序將一執行到這裡就跳到00465A52執行我們的程式碼。 4、實現我們自己的程式碼,然後跳回 我們的程式碼要做的是把動態變成靜態, PUSH EAX MOV EAX,[ESI+000001A4] MOV [00470000],EAX POP EAX JMP 004046C7 這樣這個數值無論執行多少次,只要你移動(當然右移也要修改)就能在00470000中找到X坐標 ,這段機器碼為50 8B86A4010000 A300004700 58 E95BECF9FF 忘了說剛才我們把004046BF替換掉的那句MOV [ESP+10],00000001也必須加上,所以開啟HEX Workshop,CTRL+G跳到00465A52,修改加入 C744241001000000 50 8B86A4010000 A300004700 58 E95BECF9FF 這樣動態資料就變成了靜態 ------------------------------------------------------------------------------ 現在回顧一下 .首先搜尋坐標位址 .找到改變這個位址的程式碼 .修改程式碼讓他跳到自己的程式碼中執行 .在程序的空白段加入自己的程式碼,當然要補上被替換了的那句,還有修改了暫存器,必須先 PUSH,再POP 下面的工作就是寫一個程序讀取這個位址了,我用VC寫了一個,順便貼一下關鍵程式碼 ------------------------------------------------------------------------------ CProcess m_process; bool m_ret = m_process.FindProcess("FortressII"); if (m_ret) { BYTE tank1xL = m_process.ReadByte(0x00470000); BYTE tank1xR = m_process.ReadByte(0x00470001); WORD tank1x = tank1xL+tank1xR*256; temp = tank1x; str.Format("%d",temp); m_tank1x=str; UpdateData(FALSE); return TRUE; } else return FALSE; ----------------------------------------------------------------------------- CProcess是一個我編寫的修改類,這裡用到的函數程式碼如下 HANDLE CProcess::OpenProcess(char *p_ClassName, char *p_WindowTitle) { HWND hWindow; DWORD pid; hWindow = FindWindow(p_ClassName, p_WindowTitle); if (hWindow) { GetWindowThreadProcessId(hWindow, &pid); return ::OpenProcess(PROCESS_ALL_ACCESS, false, pid); } return NULL; } bool CProcess::FindProcess(char *p_WindowTitle) { if (m_hProcess == NULL) { m_hProcess = this->OpenProcess(NULL, p_WindowTitle); if (m_hProcess) m_bGameRunning = true; return m_bGameRunning; } else return false; } BYTE CProcess::ReadByte(DWORD p_Address) { DWORD bytes; BYTE tmp類型; if (m_bGameRunning) { if (ReadProcessMemory(m_hProcess, (void*)p_Address, (void *)&tmp類型, 1, &bytes) == 0) return 0; else return tmp類型; } return 0; } ----------------------------------------------------------------------------- 這裡整個步驟就完成了,下面是我的程序的一個截取影圖,由於程序 http://www.goodassister.com/images/fortress.jpg |
送花文章: 3,
|