поиск шедевроадреса

chromiusj

Стань той переменой, которую хочешь увидеть в мире
Автор темы
Модератор
5,732
4,033
Версия MoonLoader
.026-beta
всем ку, пытаюсь получить время, когда последний раз бибикнул, через адресы
использую так:
Lua:
local time = memory.getuint32(0xB6BC90+0x2A0+0x80) -- CAudioEngine + CAEScriptAudioEntity + m_dwLastTimeHornPlayed
но ничего не показывает...
помогите пожалуйста человеку, который при виде реверса теряет сознание, получить значение
1730922744139.png
 
  • Эм
  • Нравится
Реакции: Corenale и Fasz fiatal
Решение
Как понимаю, последний метод на скрине как раз относится к твоему варианту из последнего абзаца, как можно это сделать?
Lua:
local old_nHornCounter = 0
local last_horn = 0

while true do
    if isCharSittingInAnyCar(PLAYER_PED) then
        local vehicle = storeCarCharIsInNoSave(PLAYER_PED)
        local nHornCounter = ffi.cast("uint32_t*", getCarPointer(vehicle) + 0x514)[0]
        if nHornCounter ~= old_nHornCounter then
            old_nHornCounter = nHornCounter
            last_horn = os.time()
        end
        printStringNow(last_horn, 150)
    end
    wait(0)
end

chromiusj

Стань той переменой, которую хочешь увидеть в мире
Автор темы
Модератор
5,732
4,033
он мне и помогал адрес искать ( я в целом понял,как искать,но я не думал,что CAudioEngine не зависящая структура, поэтому консультировался с ним), функция либо не используется, либо хз
Screenshot_2024_1107_135524.jpg
 

wojciech?

Известный
Проверенный
386
283
В ida нет явных ссылок на это поле
1730970533078.png


В более подходящей структуре CAEVehicleAudioEntity только свойства horn (громкость, счетчики и т.п.). И в методах как-то завязанных на гудке тоже упоминаний этого поля нет)
1730970674157.png


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

chromiusj

Стань той переменой, которую хочешь увидеть в мире
Автор темы
Модератор
5,732
4,033
В ida нет явных ссылок на это поле
Посмотреть вложение 256506

В более подходящей структуре CAEVehicleAudioEntity только свойства horn (громкость, счетчики и т.п.). И в методах как-то завязанных на гудке тоже упоминаний этого поля нет)
Посмотреть вложение 256507

Как вариант, в ручную отслеживать состояние horn и держать свой таймер, который обновляется при изменении состояния
Как понимаю, последний метод на скрине как раз относится к твоему варианту из последнего абзаца, как можно это сделать?
 

wojciech?

Известный
Проверенный
386
283
Как понимаю, последний метод на скрине как раз относится к твоему варианту из последнего абзаца, как можно это сделать?
Lua:
local old_nHornCounter = 0
local last_horn = 0

while true do
    if isCharSittingInAnyCar(PLAYER_PED) then
        local vehicle = storeCarCharIsInNoSave(PLAYER_PED)
        local nHornCounter = ffi.cast("uint32_t*", getCarPointer(vehicle) + 0x514)[0]
        if nHornCounter ~= old_nHornCounter then
            old_nHornCounter = nHornCounter
            last_horn = os.time()
        end
        printStringNow(last_horn, 150)
    end
    wait(0)
end
 

chromiusj

Стань той переменой, которую хочешь увидеть в мире
Автор темы
Модератор
5,732
4,033
Lua:
local old_nHornCounter = 0
local last_horn = 0

while true do
    if isCharSittingInAnyCar(PLAYER_PED) then
        local vehicle = storeCarCharIsInNoSave(PLAYER_PED)
        local nHornCounter = ffi.cast("uint32_t*", getCarPointer(vehicle) + 0x514)[0]
        if nHornCounter ~= old_nHornCounter then
            old_nHornCounter = nHornCounter
            last_horn = os.time()
        end
        printStringNow(last_horn, 150)
    end
    wait(0)
end
то что надо,благодарю
 

Vintik

Через тернии к звёздам
Проверенный
1,563
1,036
Lua:
local time = memory.getuint32(0xB6BC90+0x2A0+0x80) -- CAudioEngine + CAEScriptAudioEntity + m_dwLastTimeHornPlayed
Кровь из глаз.
Тебе скинули другое решение, но всё же объясню тебе то, что ты хотел сделать.
У тебя тут, видимо, указатель 3 уровня.

Вкратце, в чём суть. У тебя есть память, покажем её табличкой:
Адрес памятиЗначение, которое там записано
0xB6BC9082
0xB6BC9454
0xB6BC9812
0xB6BC9С112
То есть, если совсем просто, память состоит из ячеек (битов), в которых записаны значения (0 или 1). Обращение к каждому биту невозможно в силу реализации чтения/записи в память, поэтому биты объединили по 8 соседних и получили байт — им и присвоили адреса (т. е. адрес 0xB1 и 0xB2 это два соседних байта, а не два соседних бита).
Тип int использует 4 байта (то, как именно число записывается, можно почитать тут). Поэтому давай смотреть таблицу, где слева указан адрес памяти, а справа — число int, которое записано в этих 4-х байтах, начиная с того, адрес которого указан слева.

Дальше нужно осознать, что есть необходимость указывать на другие адреса (то есть значением одних адресов является другой адрес). Например, у тебя есть структура игрока (где хранится вся информация о нём). Она БОЛЬШАЯ (т. е. занимает много сотен байтов), и если у нас большое количество игроков в зоне стрима — все их структуры надо хранить. Если их хранить «одна за другой», то так много свободного места подряд может тупо не найтись в памяти. Поэтому решили хранить в массиве только адреса начала структур, а сами структуры создавать в произвольном пустом месте, совсем необязательно подряд.
Туда же можно отнести и передачу больших массивов данных в функции (например, в рекурсии). Если каждый раз копировать весь массив и передавать целиком массив при рекурсии — память закончится почти сразу в реальных программах. Намного эффективнее создать его 1 раз, а передавать лишь указатель на его начало (адрес памяти начала массива). Понятно, да?
Адрес памятиЗначение, которое там записано
0xB6BC900xC834EC
......
0xC834ECнужное нам значение
В таком примере, чтобы получил нужное нам значение, зная только адрес указателя, мы должны прочитать то, что записано там, а потом перейти по этому адресу — и прочитать уже его значение. А если это структура?
Адрес памятиЗначение, которое там записано
0xB6BC900xC834EC (к примеру, указатель на начало структуры игрока)
......
0xC834EC (начало структуры)...
0xC834EC + 0x4 (к примеру, здоровье игрока)...
0xC834EC + 0x8 (к примеру, броня игрока)...
0xC834EC + 0xC (к примеру, скин игрока)нужное нам значение
Тогда тебе к адресу нужно прибавить смещение +0xC, это называется оффсет.

У тебя такой процесс нужно провернуть 3 раза: указатель на указатель на указатель на числовое значение.
В коде это будет вот так:
Lua:
local CAudioEngine = memory.getint32(0xB6BC90)
local CAEScriptAudioEntity = memory.getint32(CAudioEngine + 0x2A0)
local m_dwLastTimeHornPlayed = memory.getuint32(CAEScriptAudioEntity + 0x80)

local time = m_dwLastTimeHornPlayed -- то, что тебе нужно
 

wojciech?

Известный
Проверенный
386
283
Кровь из глаз.
Тебе скинули другое решение, но всё же объясню тебе то, что ты хотел сделать.
У тебя тут, видимо, указатель 3 уровня.

Вкратце, в чём суть. У тебя есть память, покажем её табличкой:
Адрес памятиЗначение, которое там записано
0xB6BC9082
0xB6BC9454
0xB6BC9812
0xB6BC9С112
То есть, если совсем просто, память состоит из ячеек (битов), в которых записаны значения (0 или 1). Обращение к каждому биту невозможно в силу реализации чтения/записи в память, поэтому биты объединили по 8 соседних и получили байт — им и присвоили адреса (т. е. адрес 0xB1 и 0xB2 это два соседних байта, а не два соседних бита).
Тип int использует 4 байта (то, как именно число записывается, можно почитать тут). Поэтому давай смотреть таблицу, где слева указан адрес памяти, а справа — число int, которое записано в этих 4-х байтах, начиная с того, адрес которого указан слева.

Дальше нужно осознать, что есть необходимость указывать на другие адреса (то есть значением одних адресов является другой адрес). Например, у тебя есть структура игрока (где хранится вся информация о нём). Она БОЛЬШАЯ (т. е. занимает много сотен байтов), и если у нас большое количество игроков в зоне стрима — все их структуры надо хранить. Если их хранить «одна за другой», то так много свободного места подряд может тупо не найтись в памяти. Поэтому решили хранить в массиве только адреса начала структур, а сами структуры создавать в произвольном пустом месте, совсем необязательно подряд.
Туда же можно отнести и передачу больших массивов данных в функции (например, в рекурсии). Если каждый раз копировать весь массив и передавать целиком массив при рекурсии — память закончится почти сразу в реальных программах. Намного эффективнее создать его 1 раз, а передавать лишь указатель на его начало (адрес памяти начала массива). Понятно, да?
Адрес памятиЗначение, которое там записано
0xB6BC900xC834EC
......
0xC834ECнужное нам значение
В таком примере, чтобы получил нужное нам значение, зная только адрес указателя, мы должны прочитать то, что записано там, а потом перейти по этому адресу — и прочитать уже его значение. А если это структура?
Адрес памятиЗначение, которое там записано
0xB6BC900xC834EC (к примеру, указатель на начало структуры игрока)
......
0xC834EC (начало структуры)...
0xC834EC + 0x4 (к примеру, здоровье игрока)...
0xC834EC + 0x8 (к примеру, броня игрока)...
0xC834EC + 0xC (к примеру, скин игрока)нужное нам значение
Тогда тебе к адресу нужно прибавить смещение +0xC, это называется оффсет.

У тебя такой процесс нужно провернуть 3 раза: указатель на указатель на указатель на числовое значение.
В коде это будет вот так:
Lua:
local CAudioEngine = memory.getint32(0xB6BC90)
local CAEScriptAudioEntity = memory.getint32(CAudioEngine + 0x2A0)
local m_dwLastTimeHornPlayed = memory.getuint32(CAEScriptAudioEntity + 0x80)

local time = m_dwLastTimeHornPlayed -- то, что тебе нужно

смотрим на структуру CAudioEngine и видим единственную ссылку в .data (также заметим смещение 2A0 с m_scriptAudio, по-моему там не указатель, а сама структура):
1730986441616.png


по ссылке на CAudioEngine лежит структура целиком:
1730986335652.png


и в CAEScriptAudioEntity лежит само значение:
1730986645763.png


по сути, твой способ берет значение из какого-то левого адреса и выводит его (в оригинале хотя бы 0 был, похоже на правду)
 
  • Нравится
Реакции: Vintik