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

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

Нужно по нажатию клавиши 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: Работа с памятью

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

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

3

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

YMP пишет:

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

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

YMP пишет:

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

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

4

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

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

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: Работа с памятью

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

6

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

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

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

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

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


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: Работа с памятью

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

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

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

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

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: Работа с памятью

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

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

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

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

12

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

creature.ws пишет:

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

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

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

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

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

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

<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: Работа с памятью

Чудеса! Оранжевая кнопка "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
Skype dmitry_fiveg

15

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

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

16

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

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

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

17

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

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: Работа с памятью

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

19

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

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

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

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

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