PDA

Просмотр полной версии : Как найти Базовый Адрес, Autoit


sumikot
26.10.2011, 13:51
Тема для новичков в программировании.
Вопрос, конечно, далеко не новый - каждый, кто пишет бота, хоть раз в жизни его искал. А потом заходил на форум zhyk.ru и оставлял сообщение - первыйна ) Можно, конечно, немного подождать, и взять BA на форуме (Это и есть первый способ нахождения BA), но бот в это время будет обиженно стоять и показывать в графе HP нули... Поэтому лучше сразу перейти ко второму способу. Вообще, поиск лучше встроить в бота - при загрузке сравнить GA из настроек со значением BA+1C из памяти клиента, если не совпадает - переход к процедуре поиска BA.
2.Ищем в клиенте последовательность значений 8B0DNNNN - это команда загрузки регистра mov ecx, dword ptr N. Используется клиентом для вычисления динамической адресации. Но так как в коде клиента может использоваться та же команда для загрузки не только BA, а других значений, делаем отсеивание по большему количеству одинакового значения - это и будет BA.
Func FindBA()
Local $BAArr[50][2], $i, $n, $BACnt = 0
For $i = 0 To 49; Обнуление массива
$BAArr[$i][0] = 0
$BAArr[$i][1] = 0
Next
For $n = 0x00401000 To 0x00403000 Step 1; Диапазон поиска
$Ram = _MemoryRead($n,$HendleDll, "ushort")
If $Ram == 0x0D8B Then; искать mov ecx, dword ptr BA
$Ram = _MemoryRead($n+2,$HendleDll)
For $i = 0 To 49
If $BAArr[$i][0] == 0 Then
$BAArr[$i][0] = $Ram
$BAArr[$i][1] = 1
ExitLoop
ElseIf $BAArr[$i][0] == $Ram Then
$BAArr[$i][1] += 1
ExitLoop
EndIf
Next
EndIf
Next
For $i = 0 To 49
If $BAArr[$i][1] > $BACnt Then
$BaseAdress = $BAArr[$i][0]
$BACnt = $BAArr[$i][1]
EndIf
Next
EndFunc
3. То же самое можно сделать, только последовательность 8B0DNNNN искать не в памяти запущенного клиента, а в файле elementclient.exe. Можно искать коды других команд, где используется BA, например 8B15, A1, 8B35, 8B2D, 8B1D, 8B3D, 8935, 892D.
4. Можно найти другим способом - увеличив количество байт искомой последовательности, например
$File=FileOpen("elementclient.exe",16)
$Data=FileRead($File,FileGetSize("elementclient.exe"))
FileClose($File)
$Search=StringRegExp($Data,"8B15(.{8})50518B4A2081C1.{8}E8.{8}",2)
,тогда не нужно будет отсеивать по количеству одинаково найденных значений. Но - этот кусок кода с обновлением может измениться, и программа не найдет ничего. Хотя пример выше работает начиная с версии 1.3.4 и заканчивая текущей.

На спасибо не настаиваю :) но и не откажусь

Это_Что_то
28.10.2011, 21:25
попробовал чет ниче не вышло.
вообще ниче не находит
что не такто?

AEBus
28.10.2011, 21:30
что пробовали, что не вышло, можно поподробнее? у нас телепатов нет
или вы так, пост набить?

Это_Что_то
28.10.2011, 21:42
да вот так и привязал

#include <NomadMemory.au3>
dim $Exe_Name='elementclient.exe'
FindBA()
Func FindBA()
Local $BAArr[50][2], $i, $n, $BACnt = 0
Local $LISTPROCEL = ProcessList($Exe_Name)
For $n = 0x00401000 To 0x00403000 Step 1; Диапазон поиска
$HendleDll=$LISTPROCEL[1][1]
$Ram = _MemoryRead($n,$HendleDll, "ushort")
If $Ram = 0x0D8B Then; искать mov ecx, dword ptr BA
$Ram = _MemoryRead($n+2,$HendleDll)
For $i = 0 To 49
If $BAArr[$i][0] == 0 Then
$BAArr[$i][0] = $Ram
$BAArr[$i][1] = 1
ExitLoop
ElseIf $BAArr[$i][0] == $Ram Then
$BAArr[$i][1] += 1
ExitLoop
EndIf
Next
EndIf
Next
For $i = 0 To 49
If $BAArr[$i][1] > $BACnt Then
$BaseAdress = $BAArr[$i][0]
$BACnt = $BAArr[$i][1]
msgbox(0,"",$BaseAdress)
EndIf
Next
EndFunc

sumikot
29.10.2011, 22:41
Это_Что_то, а хендл процесса узнать? А память для чтения открыть?
И желательно это сделать вне цикла for next.
#include <NomadMemory.au3>
Global $NameWinClient = "Element Client"
Global $HendleProc = WinGetProcess($NameWinClient)
Global $HendleDll = _MemoryOpen($HendleProc)
FindBA()

Func FindBA()
Local $BAArr[50][2], $i, $n, $BACnt = 0
For $i = 0 To 49; Обнуление массива
$BAArr[$i][0] = 0
$BAArr[$i][1] = 0
Next
For $n = 0x00401000 To 0x00403000 Step 1; Диапазон поиска
$Ram = _MemoryRead($n,$HendleDll, "ushort")
If $Ram == 0x0D8B Then; искать mov ecx, dword ptr BA
$Ram = _MemoryRead($n+2,$HendleDll)
For $i = 0 To 49
If $BAArr[$i][0] == 0 Then
$BAArr[$i][0] = $Ram
$BAArr[$i][1] = 1
ExitLoop
ElseIf $BAArr[$i][0] == $Ram Then
$BAArr[$i][1] += 1
ExitLoop
EndIf
Next
EndIf
Next
For $i = 0 To 49
If $BAArr[$i][1] > $BACnt Then
$BaseAdress = $BAArr[$i][0]
$BACnt = $BAArr[$i][1]
EndIf
Next
MsgBox(0,"",Hex($BaseAdress))
EndFunc

Добавлено через 23 минуты
Кстати, добавлю еще, имя окна на оффе сейчас Perfect World, а не Element Client. Будьте внимательны

Это_Что_то
02.11.2011, 00:27
я так и делал, только$LISTPROCEL = ProcessList($Exe_Name)
это список процессов с PID по нему и открываю 1-й процесс

ну да упустил OPENMEMORY

а твой код тоже не работает, 000000 выводит

А вот по PID'ам процесса находит))) спасибо

sumikot
02.11.2011, 01:00
А мой код и не найдет :) Абсолютно ничего )))))
Такое впечатление, как будто не я писал, а не ты читал: "Кстати, добавлю еще, имя окна на оффе сейчас Perfect World, а не Element Client. Будьте внимательны". А первый процесс - по статистике, обычно это процесс с фокусом на данный момент) Извини, я падсталом)))) Знаю, что нехорошо, но нимогу ничего с собой поделать))))) Наберу 10 сообщений, обязательно тебе спасибку поставлю) Будь внимателен, удачи!

Все, абсолютно серьезен. Немного слов для начинающих писать. На любом языке. Пример выше - $LISTPROCEL = ProcessList($Exe_Name) - и, соответственно, открытие памяти для чтения и записи первого попавшегося процесса. Попадет такая программа в паблик - и половина людей напишет, что она не работает. Потому что кто то фильм открыл до этого, кто то паралельно еще на форуме сидит. А у меня таким способом память интерпретатора Autoit почему то открывает... Как то попался троян, который при заражении собой просил установить необходимые библиотеки для его работы ) Нужно продумывать все варианты запуска своей программы. Чтобы проверить, что именно это процесс именно игры, именно от файла elementclient, что если запущено под win7 или wista, запросить админские полномочия, и т д
Опять многа букафф... Занесло...

Спасибку поставил, как и обещал. Это не накрутка спасибок друг другу! Реально - 2 часа ночи, жена спит, а я патсталом. Жена проснулась, понять ничего не может. Вот так смех продлевает жизнь - вместо того, чтобы спать, она минут 15 бодрствовала ))))

Это_Что_то
02.11.2011, 10:54
Чтобы разобраться попробуй выведи массив
#include <Array.au3>
Run(@SystemDir & "\calc.exe")
Run(@SystemDir & "\calc.exe")
Run(@SystemDir & "\calc.exe")
$Process=ProcessList("calc.exe")
_ArrayDisplay($Process)
ProcessClose($Process[1][1])
ProcessClose($Process[2][1])
ProcessClose($Process[3][1])

в общем то с этого момента сен стало понятно ка это работает
Единственное "НО" это то, что еще иногда приходится искать хендл окна по процессу, но это уже моё извращение(