<progress id="yueoz"><code id="yueoz"><xmp id="yueoz">

      1. 吾愛破解 - LCG - LSG |安卓破解|病毒分析|www.13ee.cn

         找回密碼
         注冊[Register]

        QQ登錄

        只需一步,快速開始

        搜索
        查看: 3384|回復: 68
        上一主題 下一主題

        [游戲安全] Python64位游戲讀寫--GTA鎖血

          [復制鏈接]
        跳轉到指定樓層
        樓主
        我要學外掛 發表于 2020-6-23 09:43 回帖獎勵
        本帖最后由 我要學外掛 于 2020-6-23 11:05 編輯


        EPIC送了GTA5,最近考完試和朋友一起玩了下,由于剛開始,等級低,朋友帶我打任務的時候,完全就打不過,我的甲沒幾下就爆了,剛開始沒什么。

        但是今天去打末日3的時候,由于只有兩個人,玩過的都知道,末日3是需要一個人去玩小游戲,然后其他人保護玩小游戲那個隊友,末日3的NPC是會一直刷,怎么打都打不完,有一瞬間就變成了CSGO練爆頭模式,完全沒得打(打不過就充錢,沒得充錢就變強)。后面搜了搜,發現別人歪瓜的截圖,有鎖血功能,就想去了解一下。

        打開GTAV,進入故事模式。GTAV官方在故事模式中,有給出作弊代碼,其中有一個無敵五分鐘的命令。從這個命令入手,查找他的基址,沒準能用。

        作弊代碼:PAINKILLER

        搜索思路
        👇
        開啟無敵時候,可能會有數值增加,可能有一個數值或者開關,會變為1。這時搜索增加的數值
        關閉無敵時候,可能會有數值減少,可能有一個數值或者開關,會變為0。這時搜索減少的數值
        
        開啟無敵時候,可能會有數值減少,可能有一個數值或者開關,某個數值減少。這時搜索減少的數值
        關閉無敵時候,可能會有數值減少,可能有一個數值或者開關,某個數值增加。這時搜索增加的數值
        👆
        

        搜索基址


        CE加載GTA5,先通過常規思路,無敵搜增加,關閉搜減少。

        即使這游戲是64位的,但是依然掃4字節就夠了。首先先掃一次未知的初始值。


        進入GTA,按~鍵,輸入作弊代碼PAINKILLER

        輸入成功時候,右下角會有無敵時間,正常為五分鐘。

        這時候去CE搜索增加的數值

        由于游戲很大,所以第一次搜增加的時候,會很卡,而且會掃很久,我的電腦要掃大概兩分半鐘,而且內存會被吃滿

        而且掃的次數多了,會產生很多臨時文件

        像我這樣,C盤直接沒位置了,所以建議備一個清理C盤的軟件。時不時清理臨時文件

        看會小說或者刷會短視頻,等掃描結果出來以后,就再次輸入作弊代碼,就可以將無敵關閉(我一開始不知道,傻傻得等了五分鐘)。

        如何查看是否關閉,看右下角的倒計時是否存在。如果沒了,那就是關閉了。

        這時候搜索減少的數值。


        步驟循環,等結果少于5000的時候。就可以通過搜索未變動的數值,來開始查找最終的基址。



        快捷鍵,CTRL+D,可以快速查看該地址反匯編地址。

        因為我搜索過很多次,所以認得特征,當反匯編窗口的代碼,是以下這串時候,我就知道找到了

        or [rax],al


        為什么了,因為這個al在線上模式時候,他是0或者1,0就是關閉無敵,1就是開啟無敵。

        一開始我怎么找到這個的了,我當時掃了很多次,發現有一次,他的值不是al,而是0,然后當我開啟無敵時候,他就變為1了。我就把它認住了。發現有的時候在線下模式,他就是會這樣,抽風。

        關閉無敵的默認初始值是:4194316

        當你把他的數值改為這個初始值時,他這個al就會變為0


        但是即使你把它改了,他還是會變,有時候會變為12,有時候會變很大的數,但是你測試一下,將00改為01時候,在去做一些扣血的行為時候,是不會扣血的,達到了無敵的效果。

        基址找到了,那就開始找他的靜態基址。

        一開始嘗試過一步一步找,然后發現,掃出來的基址過多,比較麻煩,所以后面決定使用指針搜索


        我這里沒調參數,直接確定了。

        最后掃出來的結果,有9419539個,觀察他的值,值等于初始值4194316或等于基址目前的值的時候,就把它雙擊,添加到地址表中。


        一定要選多幾個,因為進入線上模式時候,值會變,有的會變成?號,有的是不知道啥值,所以要選多幾個加以觀察,或者不關閉指針掃描結果窗口。

        最終我找出來的基址

        "GTA5.exe"+02D06110 +28+298+c8+a8+188五層偏移。


        代碼編寫


        游戲是64位的,所以要用64位的函數。

        WOW64 函數

        [b]ZwWow64QueryInformationProcess64
        ZwWow64ReadVirtualMemory64
        ZwWow64WriteVirtualMemory64
        ZwWow64CallFunction64[/b]
        32位程序幾乎可以獲取64位程序的全部函數調用功能。

        首先導入函數

        基本操作都沒啥不同的。

        # -*- coding:utf-8 -*-
        """
        @author: 
        @file: GTA.py
        @time: 2020-06-21 13:49
        @desc: KeyboArd
        """
        import win32process#進程模塊
        import win32api#主要用來注冊熱鍵
        import ctypes#C語言類型
        from win32gui import FindWindow#界面
        from ctypes import c_long , c_int , c_void_p, windll, WinDLL, c_ulonglong, byref

        初始化

        ntdll = WinDLL("ntdll.dll")#調用ntdll庫
        kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")#調用kernel32庫
        GetLastError = kernel32.GetLastError#調用GetLastError函數
        GTA = 0x7FF79B5D0000#GTA.EXE的基址,原本是打算通過模塊名字獲取的,但是不知道為什么返回-1.可能是64位游戲,涉及到一些權限問題,后面在研究一下,目前主要是為了達到目的。
        STANDARD_RIGHTS_REQUIRED = 0x000F0000#這兩個的值,是在C++那里獲取過來的。
        SYNCHRONIZE = 0x00100000#看圖
        PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)#看圖
        
        class PROCESS_BASIC_INFORMATION(ctypes.Structure):
            _fields_ = [('ExitStatus', ctypes.c_ulonglong),     # 接收進程終止狀態
                        ('PebBaseAddress', ctypes.c_ulonglong),  # 接收進程環境塊地址
                        ('AffinityMask', ctypes.c_ulonglong),  # 接收進程關聯掩碼
                        ('BasePriority', ctypes.c_ulonglong),  # 接收進程的優先級類
                        ('UniqueProcessId', ctypes.c_ulonglong),  # 接收進程ID
                        ('InheritedFromUniqueProcessId', ctypes.c_ulonglong)]  # 接收父進程ID
        
        ## OpenProcess
        OpenProcess = windll.kernel32.OpenProcess
        OpenProcess.argtypes = [c_void_p, c_int, c_long]
        OpenProcess.rettype = c_long
        ## CloseHandle
        CloseHandle = windll.kernel32.CloseHandle
        CloseHandle.argtypes = [c_void_p]
        CloseHandle.rettype = c_int
        
        def _GetProcessId(className,windowName):
            hGameWindow = FindWindow(className, windowName)
            pid = win32process.GetWindowThreadProcessId(hGameWindow)[1]
            return pid
        
        def _GetPorcessHandle(pid):
            hGameHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
            return hGameHandle
        
        ProcessId = _GetProcessId("grcWindow", u"Gra***** A****V")
        _hGameHandle = _GetPorcessHandle(ProcessId)


        對64位內存讀操作

        def _ReadMemeryLong64(addr, bufflength):
            addr = c_ulonglong(addr)#64位游戲,我測試過,如果只寫c_ulong() 會報錯,說有沖突。
            ret = c_ulonglong()#所以這里也都保持同樣的長度把
            BufferLength = c_ulonglong(bufflength)
            ntdll.ZwWow64ReadVirtualMemory64(int(_hGameHandle), addr, byref(ret), BufferLength, 0)#ZwWow64ReadVirtualMemory64和ReadProcessInt 這個函數操作類似。
            return ret.value

        64位通過模塊名獲取基址

        def GetBaseAddr(ModuleName):  #這是論壇里一位大佬寫的,為了方便快捷,先復制粘貼過來,這代碼我也沒看懂,好像涉及到了pe知識,后面自己在 寫一個。
            # 傳入需要查找的模塊的名稱,就可以返回相應的模塊基址了
            NumberOfBytesRead = c_ulong()
            Buffer = PROCESS_BASIC_INFORMATION()
            Size = c_ulong(48)
            name_len = len(ModuleName)
        
            ntdll.NtWow64QueryInformationProcess64(int(_hGameHandle), 0, byref(Buffer), Size,
                                                        byref(NumberOfBytesRead))
            """
            這同樣是一個未公開的api,可以通過他獲取進程的信息,然后存入我們一開始定義的結構體中,他的五個參數分別是:
            進程句柄,信息類型,緩沖指針,以字節為單位的緩沖大小, 寫入緩沖的字節數
            而至于下面為什么要這么寫,其實涉及到了程序的PE結構,這里不做贅述,因為這個東西不是一會會說的清楚的,可以自行百度
            """
            ret = _ReadMemeryLong64(Buffer.PebBaseAddress + 24, 8)
            ret = _ReadMemeryLong64(ret + 24, 8)
        
            for i in range(100000):  # 這里用for循環其實是怕程序卡死,下面如果出了問題不能退出的話,循環結束一樣可以退出
                modulehandle = _ReadMemeryLong64(ret + 48, 8)
                if modulehandle == 0:
                    break
                nameaddr = _ReadMemeryLong64(ret + 96, 8)
                name = ReadProcessMemory64_Wchar(nameaddr, name_len * 2 + 1, name_len)
                if name == ModuleName:
                    return modulehandle
                ret = _ReadMemeryLong64(ret + 8, 8)
        

        對找到的基址進行讀取

        def get_invincible(hGameHandle):
            #"GTA5.exe"+02D06110 +28+298+c8+a8+188  這是找到的基址
            value = GTA+ 0x02D06110#GTA的基址等于0x7FF79B5D0000 ,如果重啟了電腦,這個基址會變,所以一定要寫64位通過模塊名讀取基址。
            value1 = _ReadMemeryLong64(value,8)#先讀取一下"GTA5.exe"+02D06110的基址?聪率欠裾_。
            value2 = _ReadMemeryLong64(value1+0x28,8)
            value3 = _ReadMemeryLong64(value2+0x298,8)
            value4 = _ReadMemeryLong64(value3+0xc8,8)
            value5 = _ReadMemeryLong64(value4+0xa8,8)
            value6 = _ReadMemeryLong64(value5+0x188,8)
            # #value1 = value++0x28+0x298+0xc8+0xa8+0x188
            print("0x%08X"%value2)
            print(value)
            return value5

        value:"GTA5.exe"+02D06110


        value1:GTA5.exe"+02D06110

        value2:GTA5.exe"+02D06110+0x28

        value3:GTA5.exe"+02D06110+0x28+0x298

        value4:GTA5.exe"+02D06110+0x28+0x298+0XC8

        value5:GTA5.exe"+02D06110+0x28+0x298+0XC8+0xa8

        value6:GTA5.exe"+02D06110+0x28+0x298+0XC8+0xa8+0x188

        成功讀取到該值,為什么這么寫,因為一開始我直接省略麻煩,寫一堆,發現讀的都是什么東西,太亂了。這樣子容易找到問題。

        64位寫操作

        def WriteMemeryLong64(addr, bufflength, n):  
            addr = c_ulonglong(addr)
            ret = c_ulonglong(bufflength)
            BufferLength = c_ulonglong(n)
            ntdll.ZwWow64WriteVirtualMemory64(int(_hGameHandle), addr, byref(ret), BufferLength, 0)##寫法也跟WriteProcessMemory這個函數相似

        無敵

        初始:4194316
        無敵:4194572

        def set_invincible(hGameHandle,address):
            while True:
                WriteMemeryLong64(hGameHandle,address+0x188,4194572,4)#開啟無敵
        
                if(win32api.GetAsyncKeyState(35)!=0):#當按下END鍵,就關閉無敵,將值寫回正常
                    WriteMemeryLong64(hGameHandle, address + 0x188, 4194316, 4)#關閉無敵
                    CloseHandle(hGameHandle)#關閉句柄
                    exit(0)#退出程序

        開啟:

        關閉:

        完整代碼

        # -*- coding:utf-8 -*-
        """
        @author: 
        @file: GTA.py
        @time: 2020-06-21 13:49
        @desc: KeyboArd
        """
        import win32process#進程模塊
        import win32api#主要用來注冊熱鍵
        import ctypes#C語言類型
        from win32gui import FindWindow#界面
        from ctypes import c_long , c_int , c_void_p, windll, WinDLL, c_ulonglong, byref,Structure,c_char,POINTER,sizeof,pointer,c_ulong,c_wchar_p
        
        ntdll = WinDLL("ntdll.dll")
        kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")
        GetLastError = kernel32.GetLastError
        #GTA = 0x7FF79B5D0000
        STANDARD_RIGHTS_REQUIRED = 0x000F0000
        SYNCHRONIZE = 0x00100000
        PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
        
        class PROCESS_BASIC_INFORMATION(ctypes.Structure):
            _fields_ = [('ExitStatus', ctypes.c_ulonglong),     # 接收進程終止狀態
                        ('PebBaseAddress', ctypes.c_ulonglong),  # 接收進程環境塊地址
                        ('AffinityMask', ctypes.c_ulonglong),  # 接收進程關聯掩碼
                        ('BasePriority', ctypes.c_ulonglong),  # 接收進程的優先級類
                        ('UniqueProcessId', ctypes.c_ulonglong),  # 接收進程ID
                        ('InheritedFromUniqueProcessId', ctypes.c_ulonglong)]  # 接收父進程ID
        
        ## OpenProcess
        OpenProcess = windll.kernel32.OpenProcess
        OpenProcess.argtypes = [c_void_p, c_int, c_long]
        OpenProcess.rettype = c_long
        ## CloseHandle
        CloseHandle = windll.kernel32.CloseHandle
        CloseHandle.argtypes = [c_void_p]
        CloseHandle.rettype = c_int
        
        def _GetProcessId(className,windowName):
            hGameWindow = FindWindow(className, windowName)
            pid = win32process.GetWindowThreadProcessId(hGameWindow)[1]
            return pid
        
        def _GetPorcessHandle(pid):
            hGameHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
            return hGameHandle
        
        ProcessId = _GetProcessId("grcWindow", u"G*********o V")
        _hGameHandle = _GetPorcessHandle(ProcessId)
        
        def _ReadMemeryLong64(addr, bufflength):
            addr = c_ulonglong(addr)
            ret = c_ulonglong()
            BufferLength = c_ulonglong(bufflength)
            ntdll.ZwWow64ReadVirtualMemory64(int(_hGameHandle), addr, byref(ret), BufferLength, 0)
            return ret.value
        
        def WriteMemeryLong64(addr, bufflength, n):  #
            addr = c_ulonglong(addr)
            ret = c_ulonglong(bufflength)
            BufferLength = c_ulonglong(n)
            ntdll.ZwWow64WriteVirtualMemory64(int(_hGameHandle), addr, byref(ret), BufferLength, 0)
        
        def ReadProcessMemory64_Wchar(addr, n,length):#這個函數用以讀取模塊名稱,與ReadVirtualMemory64不同的點還有一個是我們會傳入一個緩沖區的長度length,用于定義一個c_wchar_p的緩沖區
            addr = c_ulonglong(addr)
            ret = c_wchar_p("0" * length)#這里選用wchar其實與編碼有關,感興趣的同學自行百度wchar,寬字符等關鍵字學習
            BufferLength = c_ulonglong(n)
            ntdll.NtWow64ReadVirtualMemory64(int(_hGameHandle), addr, ret, BufferLength, 0)
            return ret.value
        
        def GetBaseAddr(ModuleName):  #
            # 傳入需要查找的模塊的名稱,就可以返回相應的模塊基址了
            NumberOfBytesRead = c_ulong()
            Buffer = PROCESS_BASIC_INFORMATION()
            Size = c_ulong(48)
            name_len = len(ModuleName)
        
            ntdll.NtWow64QueryInformationProcess64(int(_hGameHandle), 0, byref(Buffer), Size,
                                                        byref(NumberOfBytesRead))
            """
            這同樣是一個未公開的api,可以通過他獲取進程的信息,然后存入我們一開始定義的結構體中,他的五個參數分別是:
            進程句柄,信息類型,緩沖指針,以字節為單位的緩沖大小, 寫入緩沖的字節數
            而至于下面為什么要這么寫,其實涉及到了程序的PE結構,這里不做贅述,因為這個東西不是一會會說的清楚的,可以自行百度
            """
            ret = _ReadMemeryLong64(Buffer.PebBaseAddress + 24, 8)
            ret = _ReadMemeryLong64(ret + 24, 8)
        
            for i in range(100000):  # 這里用for循環其實是怕程序卡死,下面如果出了問題不能退出的話,循環結束一樣可以退出
                modulehandle = _ReadMemeryLong64(ret + 48, 8)
                if modulehandle == 0:
                    break
                nameaddr = _ReadMemeryLong64(ret + 96, 8)
                name = ReadProcessMemory64_Wchar(nameaddr, name_len * 2 + 1, name_len)
                if name == ModuleName:
                    return modulehandle
                ret = _ReadMemeryLong64(ret + 8, 8)
        
        def get_invincible(hGameHandle,GTA):
            #"GTA5.exe"+02D06110 +28+298+c8+a8+188
            value = GTA+ 0x02D06110
            value1 = _ReadMemeryLong64(value,8)#先讀取一下"GTA5.exe"+02D06110的基址?聪率欠裾_。
            value2 = _ReadMemeryLong64(value1+0x28,8)
            value3 = _ReadMemeryLong64(value2+0x298,8)
            value4 = _ReadMemeryLong64(value3+0xc8,8)
            value5 = _ReadMemeryLong64(value4+0xa8,8)
            value6 = _ReadMemeryLong64(value5+0x188,8)
            #value1 = value++0x28+0x298+0xc8+0xa8+0x188
           # print("0x%08X"%value6)
            print(value6)
            return value5
        
        def set_invincible(hGameHandle,address):
            while True:
                WriteMemeryLong64(address+0x188,4194572,4)#開啟無敵
        
                if(win32api.GetAsyncKeyState(35)!=0):
                    WriteMemeryLong64(address + 0x188, 4194316, 4)#關閉無敵
                    CloseHandle(hGameHandle)
                    exit(0)
        
        def main():
            moudle = GetBaseAddr("****5.exe")
            invincible = get_invincible(_hGameHandle, moudle)
            #print("0x%08X" % moudle)
            #print(moudle)
            #print("0x%08X" % modulename)
            set_invincible(_hGameHandle,invincible)
        
            CloseHandle(_hGameHandle)
        
        if __name__ == '__main__':
            main()



        11.png (19.08 KB, 下載次數: 0)

        11.png

        6.png (1.12 MB, 下載次數: 0)

        6.png

        免費評分

        參與人數 32威望 +1 吾愛幣 +54 熱心值 +28 收起 理由
        illyawolaopo + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!有點復雜慢慢消化一下
        EscapeUtopia + 1 + 1 謝謝@Thanks!
        Dmdmdms + 1 + 1 用心討論,共獲提升!
        jFae + 1 + 1 我很贊同!
        追夢de鵬 + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
        yourenzhang + 1 謝謝@Thanks!
        woyucheng + 1 + 1 謝謝@Thanks!
        夢古無疆 + 1 + 1 我很贊同!
        LZ01 + 1 我很贊同!
        nws0507 + 1 + 1 謝謝@Thanks!
        Games游戲迷 + 1 + 1 熱心回復!
        linso + 2 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
        kicebeauty + 1 + 1 用心討論,共獲提升!
        hj170520 + 1 + 1 謝謝@Thanks!
        hmxfj + 1 + 1 謝謝@Thanks!
        vethenc + 1 + 1 謝謝@Thanks!
        GYZ1028 + 1 用心討論,共獲提升!
        江南第一帥 + 1 + 1 我很贊同!
        Forf丶T + 1 + 1 熱心回復!
        wkfy + 2 + 1 熱心回復!
        Xjl955666 + 1 + 1 GTA5菜雞前來送分。
        Hmily + 1 + 20 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
        culprit + 1 + 1 我很贊同!
        laoxiaodiao + 1 + 1 用心討論,共獲提升!
        MaxMadcc + 1 謝謝@Thanks!
        風生·水起 + 2 + 1 問下,64位修改虛擬保護的是哪個api
        RyanEdward + 1 + 1 謝謝@Thanks!
        burning + 1 用心討論,共獲提升!
        yuehanoo + 1 + 1 謝謝@Thanks!
        xiaosuobjsd + 1 + 1 白嫖GTA5黨送分
        小朋友呢 + 2 + 1 用心討論,共獲提升!
        nirunyu + 1 + 1 用心討論,共獲提升!

        查看全部評分

        發帖前要善用論壇搜索功能,那里可能會有你要找的答案或者已經有人發布過相同內容了,請勿重復發帖。

        推薦
        mAsk° 發表于 2020-6-23 13:31
        無敵模式正確的基址應該是WorldPTR+0x8+0x189

        WorldPTR視游戲版本而定,Steam是GTA5.exe+0x24B0C50,Epic是GTA5.exe+0x24AECE0

        還有,無敵模式數據類型應該是BYTE,也就是1個字節,1是開,0是關。而不是樓主程序里寫的4字節

        更多GTAV外掛相關知識請看我的Github開源項目:https://github.com/AmazingPP/subVerison_GTAV_Hack

        免費評分

        參與人數 1吾愛幣 +1 熱心值 +1 收起 理由
        samvon + 1 + 1 謝謝@Thanks!

        查看全部評分

        推薦
        mAsk° 發表于 2020-6-23 21:18
        風生·水起 發表于 2020-6-23 10:42
        誰知道64位修改虛擬保護的是哪個api? 我試過32位里面的VirtualProtect,沒有效果。
        有些內存地址訪問權限 ...

        64位程序直接用VirtualProtectEx即可,32位可以LoadLibrary加載64位的ntdll.dll,然后用里面的NtProtectVirtualMemory

        具體實現可以看:https://github.com/rwfpl/rewolf-wow64ext
        沙發
        zucker 發表于 2020-6-23 09:54
        3#
        吾愛不解 發表于 2020-6-23 09:59
        樓主  我也領了游戲 但是R星服務器 總是登錄不上 怎么辦~~!
        4#
        YuerWang 發表于 2020-6-23 10:01
        樓主太強了!
        5#
        xiaosuobjsd 發表于 2020-6-23 10:02
        想當年我也參與幫助過一個網友整過這個,不知道他做出來沒有@-巫楓
        6#
        nirunyu 發表于 2020-6-23 10:04
        厲害,學到了
        7#
        羋羋羋 發表于 2020-6-23 10:07
        還有這種操作,大佬666啊
        8#
        yuehanoo 發表于 2020-6-23 10:07
        現在下載不了GTA5了,各大單機網站都關閉下載了,有也沒用,不過也要支持下。
        9#
        xiahhhr 發表于 2020-6-23 10:09
        python寫這類東西代碼量確實太多了,不過這名字是不是暴露了
        10#
        judgecx 發表于 2020-6-23 10:11
        樓主這就很六啊 不過名字我愛了哈哈
        您需要登錄后才可以回帖 登錄 | 注冊[Register]

        本版積分規則 警告:本版塊禁止灌水或回復與主題無關內容,違者重罰!

        快速回復 收藏帖子 返回列表 搜索

        RSS訂閱|小黑屋|聯系我們|吾愛破解 - LCG - LSG ( 京ICP備16042023號 | 京公網安備 11010502030087號 )

        GMT+8, 2020-6-28 20:28

        Powered by Discuz!

        Copyright © 2001-2020, Tencent Cloud.

        快速回復 返回頂部 返回列表
        快三开奖结果