Перейти к содержанию

Не получается найти инструкцию, выделяющую память.


Desmos

Рекомендуемые сообщения

Программа Cheat Engine. Название игры особо не важно.

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

Чтобы их найти вручную надо нажать на инструкции "Проверять инструкции на обращение к другим адресам" потом, Дополнительная информация, только тогда я найду эти адреса. Правда они существуют недолго (~30 сек), далее они как бы отчищаются (деструктором наверно). Потом через какой-то промежуток времени появляются новые адреса с нужной мне информацией и так далее. Всё это во вкладке дополнительная информация, там где адреса высвечиваются. Нужно мне эти адреса программно получать, чтобы можно было изменять в них значения быстро, в течение 30 секунд. Возможно ли это. А то вручную это делать бессмысленно.

Ещё как вариант можно найти инструкцию, выделяющую эти адреса в памяти, но я не знаю как это сделать.  Вот первостепенно, если можно её найти, хотелось бы это сделать, а  то с этими адресами морочиться не хочется. Если подскажите, буду благодарен. Если нужна подробная информация, готов предоставить. Инструкции или дизассемблер, например.

Изменено пользователем Desmos
Ссылка на комментарий
Поделиться на другие сайты

  • Desmos изменил название на Не получается найти инструкцию, выделяющую память.
5 часов назад, Xipho сказал:

LUA SetBreakPoint или что-то в этом духе.

Привет. Я тут немного продвинулся, нашёл инструкцию, обращающуюся ко всем нужным адресам, подробнее, что мне нужно можете посмотреть на скринах 2 и 3, просто так удобнее.

 

Скрин 1 Сама инструкция, которая обращается к адресам

Скрин 2 Подтверждение того, что количество этих адресов растёт.

Скрин 3 Там написано, что я не могу сделать.

Вся информация, что мне надо сделать на скринах. Я только не пойму, ну я в edx+20 смогу через lua попасть, но это будет только 1 адресс. А как мне все получить, которые появляются? Причем я понимаю, что это можно через таймер сделать, но как мне именно сканировать каждый раз на обращение к новым адресам. Или в edx каждый раз разное значение будет? Не понятно. Помогите, пожалуйста, кодом или информацией, где можно прочитать.

Изменено пользователем Desmos
Ссылка на комментарий
Поделиться на другие сайты

Написать стандартный СЕ-ный скрипт (зачем тебе LUA?)

Судя по скрину - значение только первого адреса отличается, а остальные адреса отражают одну и туже игровую характеристику (ты об этом почему-то не говоришь, какую опцию ломаешь).

Так что отфильтровать первый адрес, а в остальные записывать то, что тебе нужно ( не нужно никакого таймера).

Ссылка на комментарий
Поделиться на другие сайты

41 минуту назад, Garik66 сказал:

Написать стандартный СЕ-ный скрипт (зачем тебе LUA?)

Судя по скрину - значение только первого адреса отличается, а остальные адреса отражают одну и туже игровую характеристику (ты об этом почему-то не говоришь, какую опцию ломаешь).

Так что отфильтровать первый адрес, а в остальные записывать то, что тебе нужно ( не нужно никакого таймера).

Это координата z выпадения припасов. Каждый припас создается через new (выделение динамической памяти). Вот поэтому и адреса разные. Мне нужно каждый раз получать адрес припаса, который появился и менять его координаты на свои, чтобы его взять. Характеристика то одна, только надо мне значение каждого менять. 

Просто все припасы выпали на одной высоте, так совпало)

Как думаешь вот в этой теме MasterGH говорит, что можно определять адреса на прерывающихся инструкциях больше одного. Это подходит к моей проблеме? https://gamehacklab.ru/topic/530-отладка-в-lua-снятие-показаний-регистров/

Как думаешь?

Изменено пользователем Desmos
Ссылка на комментарий
Поделиться на другие сайты

36 минут назад, Desmos сказал:

Это координата z выпадения припасов

Попробуй передать свою координату обычным СЕ-ным АА-скриптом

Ссылка на комментарий
Поделиться на другие сайты

Короче, у меня получилось сделать. Чит, который я сделал, собирает припасы по такому алгоритму:

1) Когда появляются припасы, выделяется память под каждый экземпляр припаса и сразу идёт обращение к сигнатуре. Соответственно, сигнатура находится через AOBScan, далее, чтобы отлавливать адреса, я сделал таймер, так как припасы могут появляться неограниченное количество раз. Этот таймер каждый раз включает debugger_setBreakpoint(). 

2)Функция debugger_onBreakpoint() у меня циклична (рекурсивна), так как припасы могут появляться по несколько штук сразу, они будут "одновременно (если не учитывать аппарат прерывания)" обращаться к инструкции, поэтому, чтобы мне все их адреса получить, нужно несколько раз включить debugger_onBreakpoint (я поставил 15). Так я получу все адреса. Далее, когда рекукрсия закончится, вызывается debug_removeBreakpoint и включается таймер, который в найденные адреса пишет значение.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Всё бы ничего, только когда припасы долгое время не падают (30  - 60 сек), а потом появляются, и как только включается debugger_onBreakpoint() происходит зависание игры. Я заметил, что когда они долго не падают, количество выполнений debugger_onBreakpoint() увеличивается и эта функция не выполняется, а потом, когда они появляются она срабатывает раз 45-60 (учитывая рекурсию) и всё. То есть пока припасы не падали функция не работала, а накапливала работу, а потом всё выполняла как положено. Это я заментил, что когда происходит зависание вылазит много сообщений, которые я написал в этой функции.

Прочитал статью от MasterGH про снятие показаний регистров в lua, там был способ писать debug_removeBreakpoint() не в теле debugger_onBreakpoint(), но тогда у меня даже не заходит в debugger_onBreakpoint() и она не выполняется.

Вот весь код на lua:

Спойлер

CELabel2 = component_findComponentByName(UDF1, "CELabel2")
--CELabel3 = component_findComponentByName(UDF1, "CELabel3")
--CELabel4 = component_findComponentByName(UDF1, "CELabel4")
--CELabel5 = component_findComponentByName(UDF1, "CELabel5")
--CELabel6 = component_findComponentByName(UDF1, "CELabel6")
CETimer1 = component_findComponentByName(UDF1, "CETimer1")
CETimer2 = component_findComponentByName(UDF1, "CETimer2")
pmAddressCoords = nil
countCoord = 0
debugState = 0
x = nil
y = nil
z = nil
coordx = 0
coordy = 0
coordz = 0
dropx = 0
dropy = 0
dropz = 0
info1 = nil
info2 = nil
info3 = nil
info4 = nil
info5 = nil
info6 = nil
info7 = nil
info8 = nil
info9 = nil
info10 = nil
info11 = nil
info12 = nil
info13 = nil
info14 = nil
info15 = nil
counterInfo = 0
timer2Enabled = 0
count = 0
pmAddress = nil
countDrop = 0
function Process_Check()
  local ProcessName = "TankiPlayer.exe"
  local bIsAttached = getOpenedProcessID()
  local dwPID = getProcessIDFromProcessName(ProcessName)
  if (bIsAttached == 0 and dwPID ~= nil) then
    OpenProcess(ProcessName)
    showMessage("The process TankiPlayer.exe is opened!")
    --control_setCaption(CELabel1, "The process TankiPlayer.exe is opened!")
  else
    if (dwPID == nil) then
      showMessage("The process TankiPlayer.exe is't found!")
    end
    if (bIsAttached ~= 0) then
      showMessage("The process TankiPlayer.exe already opened!")
    end
  end
end

function CEButton2Click(sender)
  Process_Check()
end



function debugger_onBreakpoint()
  if(debugState == 0) then
    x = getAddress(EDX+0x10)
    y = getAddress(EDX+0x18)
    z = getAddress(EDX+0x20)
    debug_removeBreakpoint(pmAddressCoords)
  --здесь я нахожу адрес координат игрока, а не припасов, как только debugState = 0 прыжок в условие происходит 1 раз.
  end
  if(debugState == 1) then
    debug_continueFromBreakpoint(co_run)
    if (countDrop == 0) then
      info1 = EDX+0x10
      --print("info1 = EDX+0x10") - эти сообщения я печатал для того, чтобы детектить когда вызывается функция debugger_onBreakpoint()
    end
    if (countDrop == 1) then
      info2 = EDX+0x10
      --print("info2 = EDX+0x10")
    end
    if (countDrop == 2) then
      info3 = EDX+0x10
      --print("info3 = EDX+0x10")
    end
    if (countDrop == 3) then
      info4 = EDX+0x10
      --print("info4 = EDX+0x10")
    end
    if (countDrop == 4) then
      info5 = EDX+0x10
      --print("info5 = EDX+0x10")
    end
    if (countDrop == 5) then
      info6 = EDX+0x10
      --print("info1 = EDX+0x10")
    end
    if (countDrop == 6) then
      info7 = EDX+0x10
      --print("info2 = EDX+0x10")
    end
    if (countDrop == 7) then
      info8 = EDX+0x10
      --print("info3 = EDX+0x10")
    end
    if (countDrop == 8) then
      info9 = EDX+0x10
      --print("info4 = EDX+0x10")
    end
    if (countDrop == 9) then
      info10 = EDX+0x10
      --print("info5 = EDX+0x10")
    end
    if (countDrop == 10) then
      info11 = EDX+0x10
      --print("info1 = EDX+0x10")
    end
    if (countDrop == 11) then
      info12 = EDX+0x10
      --print("info2 = EDX+0x10")
    end
    if (countDrop == 12) then
      info13 = EDX+0x10
      --print("info3 = EDX+0x10")
    end
    if (countDrop == 13) then
      info14 = EDX+0x10
      --print("info4 = EDX+0x10")
    end
    if (countDrop == 14) then
      info15 = EDX+0x10
      --print("info5 = EDX+0x10")
    end
        if (countDrop >= 15) then
      --print("if (count >= 15) then")
      debug_removeBreakpoint(pmAddress)
      counterInfo = 0
      if (timer2Enabled == 0) then
        --print("Ok 157")
        timer_setEnabled(CETimer2, true)
        timer2Enabled = 1
        --print("Ok 159")
      end
    end
    countDrop = countDrop + 1
  end
return 1
end



function CEButton1Click(sender)
  pause()
  results = AOBScan("F3 0F 7E 42 20 BA XX XX XX XX 81 F2 XX XX XX XX 66 0F 57 C9 F2 0F 2A CA F2 0F 5C C1", "+X-C*W")
  unpause()
  if (results == nil) then
    showMessage("The signature isn't found!")
  else
    count = stringlist_getCount(results)
    if (count == 1) then
      showMessage("The unique signature is found!")
      pmAddress = getAddress(stringlist_getString(results,0))
      object_destroy(results)
      results = nil
      debugProcess()
      debugState = 1
      timer_setEnabled(CETimer1, true)
    else
      showMessage("The signature is't unique!")
      object_destroy(results)
      results = nil
    end
  end
end



function CEButton4Click(sender)
  pause()
  resultCoords = AOBScan("F3 0F 7E 4A 20 BA", "+X-C*W")
  unpause()
  if (resultCoords == nil) then
    showMessage("The signature isn't found!")
  else
    countCoords = stringlist_getCount(resultCoords)
    if (countCoords == 1) then
      countCoords = 0
      showMessage("The unique signature is found!")
      pmAddressCoords = getAddress(stringlist_getString(resultCoords,0))
      --s = string.format("%08X", pmAddressCoords)
      --control_setCaption(CELabel6, s)
      object_destroy(resultCoords)
      resultCoords = nil
      debugState = 0
      debugProcess()
      debug_setBreakpoint(pmAddressCoords)
      --timer_setEnabled(CETimer2, true)
    else
      showMessage("The signature is't unique!")
      object_destroy(resultCoords)
      resultCoords = nil
    end
  end
end

function CETimer1Timer(sender)
  countDrop = 0
  debug_setBreakpoint(pmAddress)
end
function CEButton3Click(sender)
  timer_setEnabled(CETimer1, false)
  debugState = 0
end


function CETimer2Timer(sender)
  coordx = readDouble(x)
  coordy = readDouble(y)
  coordz = readDouble(z)
  --strx = string.format("x = %f y = %f z = %f", coordx, coordy, coordz)
  --control_setCaption(CELabel2, strx)
  if (info15 ~= nil and counterInfo == 14) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info15, coordx)
    writeDouble(info15 + 0x8, coordy)
    writeDouble(info15 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info14 ~= nil and counterInfo == 13) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info14, coordx)
    writeDouble(info14 + 0x8, coordy)
    writeDouble(info14 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info13 ~= nil and counterInfo == 12) then
    --print("Ok writeDouble(info3, coordx)")
    writeDouble(info13, coordx)
    writeDouble(info13 + 0x8, coordy)
    writeDouble(info13 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info12 ~= nil and counterInfo == 11) then
    --print("Ok writeDouble(info2, coordx)")
    writeDouble(info12, coordx)
    writeDouble(info12 + 0x8, coordy)
    writeDouble(info12 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info11 ~= nil and counterInfo == 10) then
    --print("Ok writeDouble(info1, coordx)")
    writeDouble(info11, coordx)
    writeDouble(info11 + 0x8, coordy)
    writeDouble(info11 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info10 ~= nil and counterInfo == 9) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info10, coordx)
    writeDouble(info10 + 0x8, coordy)
    writeDouble(info10 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info9 ~= nil and counterInfo == 8) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info9, coordx)
    writeDouble(info9 + 0x8, coordy)
    writeDouble(info9 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info8 ~= nil and counterInfo == 7) then
    --print("Ok writeDouble(info3, coordx)")
    writeDouble(info8, coordx)
    writeDouble(info8 + 0x8, coordy)
    writeDouble(info8 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info7 ~= nil and counterInfo == 6) then
    --print("Ok writeDouble(info2, coordx)")
    writeDouble(info7, coordx)
    writeDouble(info7 + 0x8, coordy)
    writeDouble(info7 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info6 ~= nil and counterInfo == 5) then
    --print("Ok writeDouble(info1, coordx)")
    writeDouble(info6, coordx)
    writeDouble(info6 + 0x8, coordy)
    writeDouble(info6 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info5 ~= nil and counterInfo == 4) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info5, coordx)
    writeDouble(info5 + 0x8, coordy)
    writeDouble(info5 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info4 ~= nil and counterInfo == 3) then
    --print("Ok writeDouble(info4, coordx)")
    writeDouble(info4, coordx)
    writeDouble(info4 + 0x8, coordy)
    writeDouble(info4 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info3 ~= nil and counterInfo == 2) then
    --print("Ok writeDouble(info3, coordx)")
    writeDouble(info3, coordx)
    writeDouble(info3 + 0x8, coordy)
    writeDouble(info3 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info2 ~= nil and counterInfo == 1) then
    --print("Ok writeDouble(info2, coordx)")
    writeDouble(info2, coordx)
    writeDouble(info2 + 0x8, coordy)
    writeDouble(info2 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (info1 ~= nil and counterInfo == 0) then
    --print("Ok writeDouble(info1, coordx)")
    writeDouble(info1, coordx)
    writeDouble(info1 + 0x8, coordy)
    writeDouble(info1 + 0x10, coordz)
    counterInfo = counterInfo + 1
  end
  if (counterInfo >= 15) then
    timer_setEnabled(CETimer2, false)
    timer2Enabled = 0
  end
end

function CEButton5Click(sender)
  timer_setEnabled(CETimer2, false)
  timer2Enabled = 0
end

 

Подскажите, в чём дело. Вы на другие функции особо не смотрите. С флагами у меня всё верно. Меня интересует лишь то, когда выполняется функция debugger_onBreakpoint() и почему она не выполняется, когда к инструкции никто не обращается. Как тогда это отловить и поставить на паузу?

Ссылка на комментарий
Поделиться на другие сайты

Но можно же сделать проще, даже 3 способа есть. Перехватывать возвращающее значение VirtualAlloc фильтруя по размеру структуры, либо найти функцию выделяющую память под предметы, просто поставив бряк на обращение к классу предметов. Ну и последний, найти адрес контейнера в котором хранятся указатели на предметы.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.