1 (изменено: [CM]White, 2012-10-26 18:00:42)

Тема: AHK: Работа с памятью

Нужно по нажатию клавиши F1 дать персонажу 99хп, где 0x00B7CD98 - указатель на актера,  float    hitpoints;   /* 1344 */ - хп актера (из С++)

F1::
ProcessName = gta_sa.exe       
Address =   
Data = 99             
Size = 1                   

VarSetCapacity(Buf, Size, 0)    

NumPut(Data, Buf, 0, "UInt")     

PROCESS_VM_WRITE = 0x20        
PROCESS_VM_OPERATION = 0x8

Process, Exist, %ProcessName%     

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel              

hProcess := DllCall("OpenProcess", "UInt", PROCESS_VM_WRITE | PROCESS_VM_OPERATION
                                 , "Int",  False
                                 , "UInt", PID)
If(!hProcess) {
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

Ret := DllCall("WriteProcessMemory", "UInt", hProcess
                                   , "UInt", Address
                                   , "UInt", &Buf
                                   , "UInt", Size
                                   , "UInt", 0)

DllCall("CloseHandle", "UInt", hProcess) 

If(!Ret) {
  MsgBox, Не удалось записать.
  ExitApp
}

2

Re: AHK: Работа с памятью

Что такое актёр?
Не понятно, что это означает:

float    hitpoints;   /* 1344 */ - хп актера (из С++)

3

Re: AHK: Работа с памятью

YMP пишет:

Что такое актёр?

Персонаж которым управляешь в игре.

YMP пишет:

float    hitpoints;   /* 1344 */ - хп актера (из С++)

Взято из структуры персонажа проги написанной в С++, разработчиком был дан следующий адрес для записи 0x00B7CD98+2E4

4

Re: AHK: Работа с памятью

Ну, если я всё правильно понял, тогда так, наверно:

F1::
ProcessName = gta_sa.exe       
Address := 0x00B7CD98 + 0x2E4
Data = 99             
Size = 4                  

VarSetCapacity(Buf, Size, 0)    

NumPut(Data, Buf, 0, "Float")     

PROCESS_VM_WRITE = 0x20        
PROCESS_VM_OPERATION = 0x8

Process, Exist, %ProcessName%     

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  Return
}

PID := ErrorLevel              

hProcess := DllCall("OpenProcess", "UInt", PROCESS_VM_WRITE | PROCESS_VM_OPERATION
                                 , "Int",  False
                                 , "UInt", PID)
If(!hProcess) {
  MsgBox, Не удалось открыть процесс.
  Return
}

Ret := DllCall("WriteProcessMemory", "UInt", hProcess
                                   , "UInt", Address
                                   , "UInt", &Buf
                                   , "UInt", Size
                                   , "UInt", 0)

DllCall("CloseHandle", "UInt", hProcess) 

If(!Ret) {
  MsgBox, Не удалось записать.
  Return
}
Return

5

Re: AHK: Работа с памятью

YMP, Прибегал ранее к этому способу, но увы результатов не получил Подобным способом с иным адресом удалось изменить только значения денег в игре

6

Re: AHK: Работа с памятью

Адрес, видимо, не тот. А у денег какой адрес, далеко от этого?

7 (изменено: creature.ws, 2013-04-16 23:21:53)

Re: AHK: Работа с памятью

Тот же код, но свёрнутый в функции:


processName  := "gta_sa.exe"
address := 0x00B7CD98 + 0x2E4
data := 99
type := "Float"

F1::
    Try {
        MsgBox % r := ProcessReadMemory(address, processName, type)
        MsgBox % ProcessWriteMemory(data, address, processName, type)
        MsgBox % ProcessReadMemory(address, processName, type)
        MsgBox % ProcessWriteMemory(r, address, processName, type)
        MsgBox % ProcessReadMemory(address, processName, type)
    }
    Catch e
        MsgBox,, Error, % e.Message
    return


ProcessReadMemory(address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 24, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "PtrP", numBytesRead, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to read process memory.`n`nError code:`t" . A_LastError)

    if !numBytesRead
        throw Exception("Read 0 bytes from the`n`nprocess:`t" . processIDorName . "`naddress:`t" . address)

    return (type = "Str")
        ? StrGet(&buf, numBytes)
        : NumGet(buf, type)
}

ProcessWriteMemory(data, address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)
    (type = "Str")
        ? StrPut(data, &buf, numBytes)
        : NumPut(data, buf, type)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 40, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("WriteProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "UInt", 0, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to write process memory.`n`nError code:`t" . A_LastError)

    return result
}

8

Re: AHK: Работа с памятью

Может адрес все таки [[0x00B7CD98] + 0x2E4]? Т.е. читаем указатель по адресу 0x00B7CD98, прибавляем к полученному значению 0x2E4...

9 (изменено: creature.ws, 2013-04-16 23:22:12)

Re: AHK: Работа с памятью

Упреждая вопрос

F1::
    Try
        SetActorHP(99)
    Catch e
        MsgBox,, Error, % e.Message
    return

SetActorHP(value)
{
    baseAddress := ProcessReadMemory(0xB7CD98, "gta_sa.exe", "Ptr", A_PtrSize)
    ProcessWriteMemory(value, baseAddress + 0x2E4, "gta_sa.exe", "Float")
}


ProcessReadMemory(address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 24, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "PtrP", numBytesRead, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to read process memory.`n`nError code:`t" . A_LastError)

    if !numBytesRead
        throw Exception("Read 0 bytes from the`n`nprocess:`t" . processIDorName . "`naddress:`t" . address)

    return (type = "Str")
        ? StrGet(&buf, numBytes)
        : NumGet(buf, type)
}

ProcessWriteMemory(data, address, processIDorName, type := "Int", numBytes := 4) {
    VarSetCapacity(buf, numBytes, 0)
    (type = "Str")
        ? StrPut(data, &buf, numBytes)
        : NumPut(data, buf, type)

    Process Exist, %processIDorName%
    if !processID := ErrorLevel
        throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 40, "UInt", 0, "UInt", processID, "Ptr")
        throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    result := DllCall("WriteProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "Ptr", numBytes, "UInt", 0, "UInt")

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt") && !result
        throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !result
        throw Exception("Failed to write process memory.`n`nError code:`t" . A_LastError)

    return result
}

10

Re: AHK: Работа с памятью

http://s2.ipicture.ru/uploads/20121027/qzwTufh8.jpg
Ходячая катастрофа

11 (изменено: creature.ws, 2012-10-27 00:50:56)

Re: AHK: Работа с памятью

Всякий AHK-код, мной размещенный на форуме, подразумевает использование AHK_L Unicode и тестируется на AHK_L Unicode x64.
Кстати, оф.сайт обновился, ссылки на скачивание ведут к дистрибутиву AHK_L, ссылки на дистрибутив и сопутствующие  AHK_Basic программы собраны с одну тему форума.

12

Re: AHK: Работа с памятью

creature.ws пишет:

ссылки на скачивание ведут к дистрибутиву AHK_L

Если ты имеешь в виду кнопку "Download AutoHotkey", то она, как и раньше, ведёт к дистрибутиву AHK-basic.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13 (изменено: creature.ws, 2012-10-27 01:13:10)

Re: AHK: Работа с памятью

Не поверив строке состояния, заглянул в код:

<div id="download-container"><a class="download" href="//l.autohotkey.net/AutoHotkey_L_Install.exe" title="Download and install in seconds" onclick="javascript:_gaq.push(['_trackPageview','/download/AutoHotkey_L_Install.exe']);">Download AutoHotkey</a></div>

Скачивающийся дистрибутив -ahk_l 1.1.08.01

14

Re: AHK: Работа с памятью

Чудеса! Оранжевая кнопка "Download AutoHotkey" справа вверху. Код:

<div id="download-container"><a class="download" href="/download/AutoHotkeyInstall.exe" title="Download and install in seconds" onclick="javascript:_gaq.push(['_trackPageview','/download/AutoHotkeyInstall.exe']);">Download AutoHotkey</a></div>
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Работа с памятью

Исключив вероятность нахождения в разных измерениях, предположу — у тебя что-то закешировалось
http://savepic.ru/3247852m.png

16

Re: AHK: Работа с памятью

Точно, очистка кэша помогла!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Работа с памятью

creature.ws пишет:

Упреждая вопрос

F1::
    Try
        SetActorHP(99)
    Catch e
        MsgBox,, Error, % e.Message
    return

SetActorHP(value)
{
    baseAddress := ReadMemory(0xB7CD98, "gta_sa.exe", "Ptr", A_PtrSize)
    WriteMemory(data, baseAddress + 0x2E4, "gta_sa.exe", "Float")
}

ReadMemory(address, processIDorName = "", type = "Int", numBytes = 4)
{
    VarSetCapacity(MVALUE, numBytes, 0)
    VarSetCapacity(numBytesRead, A_PtrSize, 0)

    Process, Exist, %processIDorName%
    if !processID := ErrorLevel
        Throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 24, "UInt", 0, "UInt", processID, "Ptr")
        Throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    if !DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &MVALUE, "UInt", numBytes, "UIntP", numBytesRead, "UInt")
        Throw Exception("Failed to read process memory.`n`nError code:`t" . A_LastError)

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt")
        Throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    if !numBytesRead
        Throw Exception("Read 0 bytes from the`n`nprocess:`t" processIDorName "`naddress:`t" address)

    return NumGet(MVALUE, 0, type)
}

WriteMemory(data, address, processIDorName = "", type = "Int", numBytes = 4)
{
    VarSetCapacity(buf, numBytes, 0)
    NumPut(data, buf, 0, type)

    Process, Exist, %processIDorName%
    if !processID := ErrorLevel
        Throw Exception("Invalid process name or process ID:`n`n""" . processIDorName . """")

    if !processHandle := DllCall("OpenProcess", "Int", 40, "UInt", 0, "UInt", processID, "Ptr")
        Throw Exception("Failed to open process.`n`nError code:`t" . A_LastError)

    if !result := DllCall("WriteProcessMemory", "Ptr", processHandle, "Ptr", address, "Ptr", &buf, "UInt", numBytes, "UInt", 0, "UInt")
        Throw Exception("Failed to write process memory.`n`nError code:`t" . A_LastError)

    if !DllCall("CloseHandle", "Ptr", processHandle, "UInt")
        Throw Exception("Failed to close process handle.`n`nError code:`t" . A_LastError)

    return result
}

http://s1.ipicture.ru/uploads/20121027/FRIdpZIq.jpg

18

Re: AHK: Работа с памятью

Поставьте себе ArtMoney. У них на сайте есть уже готовые таблицы для gta-sa. Попробуйте, возможно одна из них к вашей версии подойдёт. Там сможете устанавливать значения или возмёте адреса для скрипта.

19

Re: AHK: Работа с памятью

Вероятно дело в том, что хп игрока имеют тип float, то есть тип с плавающей запятой (англ. точкой). У этого типа совсем другое представление в памяти, нежели у uint. Указывается тип с плавающей точкой для помещения в память.

20 (изменено: Vicoriyan, 2018-01-28 01:24:22)

Re: AHK: Работа с памятью

YMP в этом посте пробовал Ваш код http://forum.script-coding.com/viewtopi … 144#p65144. Когда я прописываю конечный адрес, значение меняется, но когда я начинаю плюсовать смещение - никакого реагирования.

Работает и меняет значение:

ProcessName = Process.exe       
Address := 0x02EDDB74  ; конечный адрес
Data = 0             
Size = 4

не работает:

ProcessName = Process.exe       
Address := 0x03AA102C + 0xD0 + 0x13C + 0x100 + 0x24 + 0x388 ; базовый адрес + смещение
Data = 0             
Size = 4

21 (изменено: slavik26092001, 2018-08-01 18:25:39)

Re: AHK: Работа с памятью

все что вам нужно есть на фото

Post's attachments

Images.png 112.82 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

22 (изменено: slavik26092001, 2018-08-01 18:27:37)

Re: AHK: Работа с памятью

Vicoriyan

Post's attachments

Images.png 112.82 kb, 1 downloads since 2018-08-01 

You don't have the permssions to download the attachments of this post.

23 (изменено: IIoToII, 2024-05-21 12:31:29)

Re: AHK: Работа с памятью

slavik26092001

Если не возражаете то я воскрешу тему с указателем. Найти его удалось: "Client.exe"+02BBEDEC -> 0776DE28,  [0776DE28+0] ->0375E1A0,    [0375E1A0+28] ->2EAAB070,  [2EAAB070+DF8] ->2EAABE68
Cтолкнулся с той же проблемой что и Vicoriyan и попробовал применить код из вашего скриншота.

ProcessName = Client.exe                        
Process, Exist, %ProcessName%
If(!Errorlevel) {
   MsgBox, Процесс не найден.
      ExitApp
}
P_1 = 0x0008
P_2 = 0x0010
P_3 = 0x0020
PID := Errorlevel
hProcess := DllCall("OpenProcess", UInt, P_1 | P_2 | P_3
                                 , UInt, False
                                 , UInt, PID)
If (!hProcess) {
MsgBox, Не удалось открыть процесс.
ExitApp
}



ReadAddress = 0x02BBEDEC                        
ReadSize = 4                                      
offsets := Array("0x0", "0x28", "0xDF8")            
VarSetCapacity(Buf_1, ReadSize, 0) 
for i in offsets
{
Ret_1 := DllCall("ReadProcessMemory", UInt, hProcess
                                    , UInt, ReadAdress
                                    , UInt, &Buf_1
                                    , UInt, ReadSize
                                    , UInt, 0)
If(!Ret_1) {
      MsgBox, Не удалось прочитать адрес!!!
      ExitApp
}

При запуске упорно выдает сообщение "Не удалось прочитать адрес!!!"
Может кто объяснить что я делаю не так и как правильно вписывать указатели?

24 (изменено: IIoToII, 2024-05-21 12:39:09)

Re: AHK: Работа с памятью

Если ввожу просто:

Address := 0x02BBEDEC + 0x0 + 0x28 + 0xDF8

то считывается адрес 0x02BBEDEC, без смещения.

25 (изменено: Вася_01, 2024-05-21 13:06:51)

Re: AHK: Работа с памятью

Попробуй читать каждое смещение по отдельности, типо так:

auto off = hv::read< uint64_t >( base + 0x608F64 );
auto idk = hv::read< uint64_t >( off + 0x60 );
auto idk2 = hv::read< uint64_t >( idk + 0x80 );
auto idk3 = hv::read< uint64_t >( idk2 + 0x4 );
auto idk4 = hv::read< uint64_t >( idk3 + 0x1B8 );
auto idk5 = hv::read< uint64_t >( idk4 + 0x194 );
auto idk6 = hv::read< uint64_t >( idk5 + 0x8 );
hv::write< float >( idk7, 999 );

вроде ответ был похожий, но там я не увидел куда читается оффсет из массива.

26

Re: AHK: Работа с памятью

Это под 2.0? Просто у меня старая версия 1.1 и на нем вообще не запускается данный код.

27 (изменено: Вася_01, 2024-05-21 16:49:53)

Re: AHK: Работа с памятью

Просто есть вариант читать каждый оффсет отдельно, сам не пробовал.

28

Re: AHK: Работа с памятью

Вася_01
Вас спрашивают, как использовать то, что вы выложили.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

29

Re: AHK: Работа с памятью

teadrinker, хмм а мне кажется, что тс хочет полностью написанный пример для своей задачи.

30

Re: AHK: Работа с памятью

Это вам мешает объяснить свой пост?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

Re: AHK: Работа с памятью

А что там объяснять, сначала читается базовый адрес + 1 оффсет
затем результат + 2 оффсет и т.д. Вроде все.

32

Re: AHK: Работа с памятью

В смысле, что там объяснять? Вы приводите на AHK-форуме код на C++ (да ещё и с ошибками) человеку, который, скорее всего, и AHK плохо знает. В чём фишка?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33 (изменено: Вася_01, 2024-05-21 19:35:06)

Re: AHK: Работа с памятью

Так все вроде так отвечают. К тому же я сомневаюсь, что человек не понимает ничего, кроме ahk.

34

Re: AHK: Работа с памятью

Вася_01 пишет:

Так все вроде так отвечают.

Кто — все? Явки, пароли?

Вася_01 пишет:

К тому же я сомневаюсь, что человек не понимает ничего, кроме ahk.

Я разве так сказал?
Если знаете ответ на вопрос, просто приведите код на AHK, если не знаете, то нечего выпендриваться, типа вы такой крутой программист.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

35 (изменено: Вася_01, 2024-05-21 20:31:13)

Re: AHK: Работа с памятью

teadrinker пишет:

такой крутой программист

М-да уж, никак не считаю себя крутым программистом, хотел помочь просто.

teadrinker пишет:

приведите код на AHK

О не, только не за просто так.

36 (изменено: IIoToII, 2024-05-23 14:44:25)

Re: AHK: Работа с памятью

Похоже разобрался в чем проблема, нужна библиотека MemoryModule. Может кто дать рабочую ссылку на нее, а то та что есть на гитхаб битая.

37 (изменено: Вася_01, 2024-05-23 17:44:18)

Re: AHK: Работа с памятью

IIoToII пишет:

нужна библиотека MemoryModule

Вообще ничего не понимаю, зачем эту библиотеку использовать, понимаю classMemory еще. А так может вот ответ на вопрос: https://www.autohotkey.com/boards/viewtopic.php?t=44241, если нужно пользоваться библиотеками.

38 (изменено: IIoToII, 2024-05-23 20:14:27)

Re: AHK: Работа с памятью

Вася_01

Затем что простое сложение офсетов не работает, пробовал я уже так считывать и получаемое значение не имеет ничего общего с реальным.

addr0 := 0x02BBEDEC
offset0 := 0x0
offset1 := 0x28
offset2 := 0xDF8

value0 := ReadMemory(addr0)
addr1 := value0 + offset0


value1 := ReadMemory(addr1)
addr2 := value1 + offset1


value2 := ReadMemory(addr2)
addr3 := value2 + offset2


StaticAddr := ReadMemory(addr3)
msgbox %staticaddr%

К примеру в данном случае  значение  StaticAddr считывается как 0, что очевидно неверно "здесь должна быть тчк, но она потерялася"

PS А вот за ссылку на classMemory спасибо, именно то что нужно.

39

Re: AHK: Работа с памятью

IIoToII, а когда у нас точки в конце предложений отменили?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40 (изменено: Вася_01, 2024-05-23 21:11:23)

Re: AHK: Работа с памятью

Так, наверное, неправильно считываете, вот тут ссылка, показано как правильно: https://www.autohotkey.com/boards/viewt … 13#p126100.

41

Re: AHK: Работа с памятью

IIoToII пишет:

"здесь должна быть тчк, но она потерялася"

У нас и участники иногда "теряются".

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder