เพื่อให้เข้าใจยิ่งขึ้นก่อนจะเริ่มเขียนสคริปต์ AutoIt เพื่อแปลงชนิดข้อมูลใน Memory คุณจะต้องดูรูปด้านล่างนี้ก่อน
รูปด้านล่างจะแสดงข้อมูล 3 ชนิดที่ผมได้กล่าวมาข้างต้น เนื่องจากคำเรียกของชนิดข้อมูลระหว่างโปรแกรม CE และ AutoIt จะไม่เหมือนกัน ดังนั้นผมจึงต้องปรับความเข้าใจให้คุณได้รู้ก่อนคือ
4 Bytes = dword (ถ้าหากใช้ข้อมูลชนิดนี้ไม่ต้องตั้งค่าในสคริปต์ เพราะเป็นค่ามาตรฐานที่ใช้อยู่แล้ว)
Float = Float (ข้อมูลชนิดตัวเลขมีจุดทศนิยม)
Text = Char[ตัวเลข] (ตัวเลข คือจำนวนตัวอักษรที่ต้องการอ่านหรือเขียน ตั้งได้สูงสุดคือ 255)
ต่อไปเป็นวิธีการเปลี่ยนรูปแบบข้อมูลการแสดงข้อมูลในโปรแกรม CE (จากแอดเดรสที่เราหาได้)
1. คลิกขวาบนแอดเดรสด้านล่างเลือกคำสั่ง Change Record > Type ดังรูปด้านล่างนี้ (หรือคลิกที่แอดเดรสแล้วกดปุ่ม Alt + Enter)
2. หน้าต่างเลือกชนิดข้อมูลจะปรากฏขึ้นมา ลองคลิกเลือกแบบ Float จะเห็นว่าคอลัมน์ Type ใน CE เปลี่ยนไปเป็น Float และค่าในคอลัมน์ Value ก็จะเปลี่ยนไปเป็นแบบ Float (เป็นข้อมูลชนิดตัวเลขทศนิยม)
วิธีเขียนโปรแกรมเพื่ออ่านข้อมูลแบบ Float ทำได้ง่ายๆ ด้วยการใส่พารามิเตรอ์เข้าไปต่อท้ายคำสั่งเดิม คือ พิมพ์คำสั่ง ,“float” ลงไป (มีเครื่องหมายคอมม่า , คั่นทุกครั้ง) เช่น
_MemoryPointerRead($address, $memopen, $Offset,"float")
ตามตัวอย่างนี้ผมแสดงการดึงเอาข้อมูลชนิด Float สำหรับการเขียนสคริปต์อ่าน Memory แบบที่ 2 (ในบทที่ 6) บางท่านสงสัยว่าแบบที่ 1 และ 3 ต้องเขียนอย่างไร คำตอบคือเขียนเหมือนกันครับคือพิมพ์คำสั่ง ,“float” ต่อท้ายสคริปต์ที่ใช้อ่านข้อมูลไปได้เลยครับ (วิธีพิมพ์ต่อท้ายดูจากสคริปต์ด้านล่างนี้)
ด้านล่างนี้สคริปต์แบบเต็มที่อ่านข้อมูลแบบ Float
#AutoIt3Wrapper_UseX64=n #RequireAdmin #include <NomadMemoryPSsix.au3> Global $address = "0x00187F5C" Global $Offset[2] $Offset[0] = 0 ; ใส่ 0 เป็นค่าเริ่มต้นทุกครั้ง $Offset[1] = 0x5578 ;ค่าออฟเซ็ต $memopen = _MEMORYOPEN(ProcessExists("popcapgame1.exe")) ;เปลี่ยนชื่อไฟล์เกมส์ If $memopen = 0 Then ConsoleWrite('ผิดพลาดไม่มีโปรแกรม =' & $memopen & @CRLF) Exit EndIf ;แปลงชนิดข้อมูลที่จะอ่านออกมาจาก Memory เป็นแบบ Float $value = _MemoryPointerRead($address, $memopen, $Offset,"float") ConsoleWrite('ค่าที่อ่านได้จากแอดเดรส ' & $value[0] & ' = ' & $value[1] & @CRLF) _MEMORYCLOSE($memopen) |
3. ลองกดปุ่ม F5 เพื่อดูผลลัพธ์การแสดงข้อมูลชนิด Float ก็จะเป็นดังภาพด้านล่างนี้
4. ต่อไปก็เป็นวิธีการเขียนข้อมูลแบบ Float ลงใน Memory ของเกม ซึ่งก็จะใช้วิธีเดียวกับการอ่านคือ พิมพ์คำสั่ง ,“float” ลงไปต่อท้ายสคริปต์สำหรับเขียนข้อมูล เช่น
_MemoryPointerWrite($address, $memopen, $Offset, "7",”float”)
ตัวอย่างสคริปต์แบบเต็ม สำหรับการเขียนข้อมูลแบบ Float ลงไปใน Memory เกม
#AutoIt3Wrapper_UseX64=n #RequireAdmin #include <NomadMemoryPSsix.au3> Global $address = "0x00187F5C" Global $Offset[2] $Offset[0] = 0 ; ใส่ 0 เป็นค่าเริ่มต้นทุกครั้ง $Offset[1] = 0x5578 $memopen = _MEMORYOPEN(ProcessExists("popcapgame1.exe")) ;เปลี่ยนชื่อไฟล์เกมส์ If $memopen = 0 Then ConsoleWrite('ผิดพลาดไม่มีโปรแกรม =' & $memopen & @CRLF) Exit EndIf $value = _MemoryPointerRead($address, $memopen, $Offset,"float") ConsoleWrite('ค่าที่อ่านได้จากแอดเดรส ' & $value[0] & ' = ' & $value[1] & @CRLF) _MemoryPointerWrite($address, $memopen, $Offset, "7",”float”) _MEMORYCLOSE($memopen) |
ตัวอย่างสคริปต์ด้านบนเป็นการเขียนข้อมูลโดยใส่ค่า 7 แบบ Float ลงไปในหน่วยความจำ ข้อควรระวังอย่างมากในการเขียนค่าแบบอื่นก็คือ คุณสแกนหาค่าในโปรแกรม CE ชนิดใดแล้ว เวลาสร้างสคริปต์ AutoIt เพื่อเขียนค่า ก็ต้องกำหนดให้เขียนข้อมูลชนิดเดียวกันลงไปด้วย เช่น หากคุณสแกนค่าแบบปกติ (4 Byte) เมื่อได้ค่ามาแล้วก็ต้องสั่งเขียนแบบปกติ (4 Byte) อย่าเปลี่ยนไปเขียนแบบอื่น เพราะจะทำให้มีโอกาสเกิดข้อมูลผิดพลาด หรือกระทั่งทำให้โปรแกรมแฮงค์ได้ง่ายๆ
เนื่องจากเกมแต่ละเกมจะมีการกำหนดลิมิตการใส่ค่าไม่เหมือนกัน (หรือกระทั่งกระหนดชนิดข้อมูลที่ใส่เข้าไปด้วย) การแปลงค่าใส่ข้อมูลที่ไม่ตรงกับชนิดข้อมูลที่สแกนได้ จะทำให้ค่ามากหรือน้อยกว่าระดับปกติที่ควรจะเป็น ตัวอย่างง่ายๆ ผมสแกนค่าแบบ 4 Byte เพื่อหาค่าพระอาทิตย์ในเกม Plants Vs Zombies แล้วสั่งเขียนข้อมูลแบบ Float ลงไป ผลลัพธ์ที่ได้ก็จะเหมือนภาพด้านล่างนี้ จะเห็นว่าตัวเลขเกินมาเป็นจำนวนมากเลยกรอบข้อมูลของเกมไป
*** ขอย้ำอีกครั้งสำหรับสคริปต์ใน AutoIt ค่า 4 Byte ไม่ต้องเขียนพารามิเตอร์เพิ่มเพราะเป็นค่ามาตรฐานอยู่แล้ว คุณจะเขียนพารามิเตอร์เพิ่มเติม ในกรณีที่ต้องการอ่านเขียนค่าแบบ Float หรือ Char เท่านั้น
สำหรับการอ่านเขียนข้อมูลแบบ Char จะเขียนสคริปต์เหมือนกับ Float เพียงแต่มีการกำหนดจำนวนตัวอักษรที่ต้องการจะอ่านหรือเขียนต่อท้ายด้วยเท่านั้นเช่น
;อ่านข้อมูลชนิด Char ใน Memory จำนวน 64 ตัวอักษร
_MemoryPointerRead($address, $memopen, $Offset,"char[64]")
;เขียนข้อมูลชนิด Char ใน Memory จำนวน 32 ตัวอักษร
_MemoryPointerWrite($address, $memopen, $Offset, "สวัสดี PSsix","char[32]")
###จบแล้วครับ###
งง งง แต่ก็ขอบคุณครับ อยากทราบวิธ๊หา Pointer เกมส์ออนไลน์ แล้วไม่ให้เด้งออกจากเกมส์อะครับ
ReplyDeleteต้องทำยังไง เหรอ ผมหาไม่ได้สักที ส่วนค่า Address คงที่นั้นเราต้องหายังไง ครับ
แล้วค่าโปรที่ทำให้ตัวละครเรา ขยับ (เคลื่อนที่ได้เร็ว กว่าคนอื่นต้องทำไงอะคัรบ)
ลบกวนพี่ๆ Pssix.blogspot.com แห่งนี้ช่วยแนะนำหน่อยครับ มีค่าเนื่อยให้
ขอแบบเต็มๆไม่เกรียน Thaihack_2012@admin.in.th ช่วยหน่อยนะครับ