1 (изменено: kamaz, 2012-01-14 17:17:07)

Тема: AHK: Тип данных

Добрый день уважаемые форумчане. Столкнулся вот с какой проблемой. Есть бот, в нем есть функция по считыванию данных адреса. Все прекрасно работает, но недавно добави новый "Контроллер", значение этого адреса идет по типу Float, раньше все было по типу 4 bytes. Суть такова что идет считывание базового адреса и к нему прибавляется смещение, получается исходный адрес. Но к сожалению с адресом типа Float программа работать не хочет, заходит в цикл но не полностью, и выходит из него, если объект (в данном случае питомец) не используется (неактивен). Если же объект активен, то чтение не происходит и цикл вообще не используется.
Для примера выложу цикл с 4 bytes (рабочий) и с Float (нерабочий)
Это так называемый базовый адрес:

ReadSize = 4
VarSetCapacity(Buf, ReadSize, 0)
PROCESS_VM_READ = 0x10
Process, Exist, %ProcessName%
PID := ProcessPID
hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, base
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
DllCall("CloseHandle", UInt, hProcess)
pointer := NumGet(Buf)

Рабочий цикл (4 bytes)


if (a32<1)
 	{
	VarSetCapacity(Buf, ReadSize, 0)
	PROCESS_VM_READ = 0x10
	Process, Exist, %ProcessName%
	PID := ProcessPID
	hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
        	                        , Int, False
                	                 , UInt, PID)
	Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hpgom 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
	DllCall("CloseHandle", UInt, hProcess)
	gomoz := NumGet(Buf)

		If (gomoz < gomhp)
		{
		Sleep, 2000
		SetKeyDelay, 1
		ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,30
		ControlSend,, {2}, ahk_pid %ProcessPID%
		Sleep,30
		ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,300
		SetKeyDelay, 1
		ControlSend,, {F11}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		SetKeyDelay, 1
		ControlSend,, {F11}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		SetKeyDelay, 1
		ControlSend,, {F1}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		ControlSend,, {F1}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		ControlSend,, {Tab}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,30
		ControlSend,, {1}, ahk_pid %ProcessPID%
		Sleep,30
		ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,300
		}
		a32:=3
 	}
	a32:=a32-1

Нерабочий цикл (Float)

if (a35<1)
 	{
	VarSetCapacity(Buf, ReadSize, 0)
	PROCESS_VM_READ = 0x10
	Process, Exist, %ProcessName%
	PID := ProcessPID
	hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
        	                        , Int, False
                	                 , UInt, PID)
	Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hppet 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
	DllCall("CloseHandle", UInt, hProcess)
	petoz := NumGet(Buf)

		If (petoz < pethp)
		{
		Sleep, 2000
		SetKeyDelay, 1
		ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,30
		ControlSend,, {2}, ahk_pid %ProcessPID%
		Sleep,30
		ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,300
		SetKeyDelay, 1
		ControlSend,, {F12}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		SetKeyDelay, 1
		ControlSend,, {F12}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		SetKeyDelay, 1
		ControlSend,, {F4}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		ControlSend,, {F4}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep, 1000
		ControlSend,, {Tab}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,30
		ControlSend,, {1}, ahk_pid %ProcessPID%
		Sleep,30
		ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
		SetKeyDelay, 1
		Sleep,300
		}
		a35:=3
 	}
	a35:=a35-1

Первый цикл работает, и при неактивности объекта программа не пытается зайти в цикл. А вот второй цикл начинает чудить. Вроде ошибок в коде нет, синтаксис правильный. В чем проблема я не могу понять. Может кто знает в чем проблема, или я что то где то упустил.
Версия AHK - 1.0.48.05

2

Re: AHK: Тип данных

Ну, если float, то и читать надо как float.

NumGet(Buf, 0, "Float")

У дробных чисел есть ещё формат double, но он уже 8 байт, так что ReadSize нужно 8.

3 (изменено: kamaz, 2012-01-14 18:50:52)

Re: AHK: Тип данных

YMP Спасибо. Заработало правильное чтение при активном объекте. Исправил это место:

petoz := NumGet(Buf, 0, "Float")

Но осталась проблема с неактивностью объекта. В качестве обеъкта можно использовать и другой вид питомца (гомункла) - его контроль работает на активность и неактивность, то есть если гомункул не активен, то цикл не используется.

VarSetCapacity(Buf, ReadSize, 0)
    PROCESS_VM_READ = 0x10
    Process, Exist, %ProcessName%
    PID := ProcessPID
    hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                    , Int, False
                                     , UInt, PID)
    Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hpgom 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
    DllCall("CloseHandle", UInt, hProcess)
    gomoz := NumGet(Buf)

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

4

Re: AHK: Тип данных

Что-то я не вижу у Вас циклов. Циклы задаются командами Loop или While, либо через GoTo. Так что не пойму, что Вы имеете в виду.

5 (изменено: kamaz, 2012-01-14 19:13:02)

Re: AHK: Тип данных

У меня они устроены через If. Но суть не в этом, а в том, что происходит чтение адресов и прочего, то есть активируется цикл:


if (a35<1)
     {
    VarSetCapacity(Buf, ReadSize, 0)
    PROCESS_VM_READ = 0x10
    Process, Exist, %ProcessName%
    PID := ProcessPID
    hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                    , Int, False
                                     , UInt, PID)
    Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hppet 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
    DllCall("CloseHandle", UInt, hProcess)
    petoz := NumGet(Buf, 0, "Float")
 
        If (petoz < pethp)
        {
        Sleep, 2000
        SetKeyDelay, 1
        ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,30
        ControlSend,, {2}, ahk_pid %ProcessPID%
        Sleep,30
        ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,300
        SetKeyDelay, 1
        ControlSend,, {F12}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        SetKeyDelay, 1
        ControlSend,, {F12}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        SetKeyDelay, 1
        ControlSend,, {F4}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        ControlSend,, {F4}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        ControlSend,, {Tab}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,30
        ControlSend,, {1}, ahk_pid %ProcessPID%
        Sleep,30
        ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,300
        }
        a35:=3
     }
    a35:=a35-1

6

Re: AHK: Тип данных

Так это не цикл. Поэтому я и не понимаю, о чём Вы говорите и в чём заключается проблема. Мне не понятно, что означает фраза "начинает заходить в цикл, но не до конца". Что такое зайти до конца? Где этот конец?

7 (изменено: kamaz, 2012-01-14 19:35:34)

Re: AHK: Тип данных

Ну не цикл, а условие. То есть это условие выполняется не доконца, при неактивности объекта. Конец условия -
        }
        a35:=3
     }
a35:=a35-1

Если говорить по русски, то это условие не должно работать когда объект не используется, условие выполняется если значение (флоат) здоровья объекта падает определенной отметки. Как здоровье становится выше этой отметки - то условие не выполняется. Но при неактивности объекта условие все равно пытается выполнится.

Вот это условие работает правильно (активно, неактивно)

if (a32<1)
     {
    VarSetCapacity(Buf, ReadSize, 0)
    PROCESS_VM_READ = 0x10
    Process, Exist, %ProcessName%
    PID := ProcessPID
    hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                    , Int, False
                                     , UInt, PID)
    Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hpgom 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
    DllCall("CloseHandle", UInt, hProcess)
    gomoz := NumGet(Buf)
 
        If (gomoz < gomhp)
        {
        Sleep, 2000
        SetKeyDelay, 1
        ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,30
        ControlSend,, {2}, ahk_pid %ProcessPID%
        Sleep,30
        ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,300
        SetKeyDelay, 1
        ControlSend,, {F11}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        SetKeyDelay, 1
        ControlSend,, {F11}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        SetKeyDelay, 1
        ControlSend,, {F1}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        ControlSend,, {F1}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep, 1000
        ControlSend,, {Tab}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        ControlSend,, {LAlt down}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,30
        ControlSend,, {1}, ahk_pid %ProcessPID%
        Sleep,30
        ControlSend,, {LAlt up}, ahk_pid %ProcessPID%
        SetKeyDelay, 1
        Sleep,300
        }
        a32:=3
     }
    a32:=a32-1

Но здесь тип данных 4 байта.
Возможно проблема в том, что pointer - это 4ех байтовое значение, а в условии я к нему прибавляю данные с float

8

Re: AHK: Тип данных

Комментарии ТС понял лишь частично.

Под объектом подразумевается элемент игры с которой работает бот?
Лучше не смешивать понятия.
Скрипт основывается на чтении памяти процесса, какие игровые действия приводят к изменению наблюдаемых ботом адресов - не имеет значения.

9

Re: AHK: Тип данных

creature.ws вы совершенно правы. Производится чтение памяти процесса. Объект - элемент игры. питомец, бот следит за его здоровьем. Если оно уменьшается, то используется условие как, показано выше в постах. Значение здоровья данного элемента игры - находится под типом Float. Чтение при активном элементе - проходит нормально, а вот когда я не использую питомца - то возникает проблема.
Где используются данные 4 bytes такой проблемы нет.

10 (изменено: kamaz, 2012-01-14 20:07:09)

Re: AHK: Тип данных

Здесь используется чтение 4 байтового значения:

ReadSize = 4
VarSetCapacity(Buf, ReadSize, 0)
PROCESS_VM_READ = 0x10
Process, Exist, %ProcessName%
PID := ProcessPID
hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, base
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
DllCall("CloseHandle", UInt, hProcess)
pointer := NumGet(Buf)

Здесь тоже 4 байтовое, работает как при активном так и не активном объекте (то есть все как должно):

VarSetCapacity(Buf, ReadSize, 0)
	PROCESS_VM_READ = 0x10
	Process, Exist, %ProcessName%
	PID := ProcessPID
	hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
        	                        , Int, False
                	                 , UInt, PID)
	Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hpgom 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
	DllCall("CloseHandle", UInt, hProcess)
	gomoz := NumGet(Buf)

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

VarSetCapacity(Buf, ReadSize, 0)
	PROCESS_VM_READ = 0x10
	Process, Exist, %ProcessName%
	PID := ProcessPID
	hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
        	                        , Int, False
                	                 , UInt, PID)
	Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + hppet 
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)
	DllCall("CloseHandle", UInt, hProcess)
	petoz := NumGet(Buf, 0, "Float")

Подскажите, что же я упустил. с типом float раньше не работал в ahk поэтому не знаю че к чему в чтении данных адресов с таким типом.

11

Re: AHK: Тип данных

Я о том и говорю, бот следит не за «здоровьем питомца», а за соответствующим ему значением в памяти. Ладно, оставим

Но при неактивности объекта условие все равно пытается выполнится.

Значит (petoz < pethp) истинно и при «неактивности объекта».

12

Re: AHK: Тип данных

creature.ws пишет:

Значит (petoz < pethp) истинно и при «неактивности объекта».

Да. Питомец находится в рюкзаке, и можно посмотреть его текущее состояние не "активируя" его. с другим видом питомца - такое не возможно.

13 (изменено: creature.ws, 2012-01-14 20:23:16)

Re: AHK: Тип данных

Замечательно

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

«Лезет куда не надо» - выполняет действия по условию If (petoz < pethp)?

Если выполняются эти действия, значит условие истинно,
Если условие истинно, то причина этого в том, что «при помещении Питомца в рюкзак» изменяется petoz или pethp.

«При помещении Питомца в рюкзак» значения этих пременных изменяются?

14 (изменено: kamaz, 2012-01-14 20:26:59)

Re: AHK: Тип данных

creature.ws пишет:

«Лезет куда не надо» - выполняет действия по условию If (petoz < pethp)?

Да вы совершенно правы.
Разговаривал с другом, который у себя такой контроль сделал с помощью проверки - использую объект или не использую. То есть у него стоит выбор какой вид питомца использовать. Вот сейчас задумываюсь о том, что сделать такое же? или как то можно обойти мою проблему без такого решения? Просто возможно такое, что при работе бота нужно менять вид питомца, я хочу это сделать так, чтобы не приходилось перезапускать бот.


Нет, значения не изменяются. Я мог бы понять этот глюк, если значение здоровья petoz было бы меньше pethp при неактивности, но проблема в том, что начинаются "глюки" даже если значение petoz больше pethp и условие недолжно срабатывать.

15

Re: AHK: Тип данных

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

16

Re: AHK: Тип данных

Ну значит, нужно ввести проверку - использую/не использую. Будет не удобно конечно, но похоже другого решения данной проблемы нет.

17

Re: AHK: Тип данных

А что это "base" означает? Откуда оно берётся?  Это что, какая-то системная переменная?

18

Re: AHK: Тип данных

kamaz, или кто-нибудь, ау!

19 (изменено: Alectric, 2013-11-26 19:42:49)

Re: AHK: Тип данных

Next пишет:

А что это "base" означает? Откуда оно берётся?  Это что, какая-то системная переменная?

Это адрес по которому происходит чтение, который был указан заранее. Например base=0x36c124cd.
Просто ТС выкладывает не полный скрипт а кусками.

Win 10 x64
AHK
                       Справка AHK v1 тебе в помощь.

20

Re: AHK: Тип данных

А я думал, что это вроде как "базовый адрес процесса". Почему-то же  это "base" в редакторе выделяется синим?  А как определить адрес с которого процесс загружен в память?

21

Re: AHK: Тип данных

Next пишет:

А как определить адрес с которого процесс загружен в память?

Непонял вопроса...

Win 10 x64
AHK
                       Справка AHK v1 тебе в помощь.

22

Re: AHK: Тип данных

У меня есть адрес ячейки памяти, но на самом  деле это не абсолютный адрес, а относительный  "имя_процесса + 0x0002000".  Мне нужно получить значение из этого адреса, для этого нужно узнать начальный или "базовый" адрес.  Это адрес с которого этот процесс загружен в память.  Если он 0x00F00000, то нужный мне будет 0x00F20000.   В первом сообщении как раз и говорится о "базовом адресе".  Как узнать этот "базовый" адрес?

23

Re: AHK: Тип данных

Стандартный адрес 0x400000. Если подозреваете, что у процесса он нестандартный, попробуйте посмотреть вот этой функцией. В качестве DllName укажите имя самого процесса. Т.е., например:


addr := ProcGetDllBase("notepad.exe", "notepad.exe")

Если процесс 64-битный, скрипт нужно запускать в АНК 64. Если вернёт 0, значит, какая-то ошибка.


ProcGetDllBase(Process, DllName)    ; Process = PID or Name.
{
    static StructSize, AddrOffset, NameOffset, MODULEENTRY32
    static FLAGS := 0x18        ; TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32
    static INVALID_HANDLE_VALUE := -1
    If (!StructSize) {
        If (A_PtrSize = 8)
            StructSize := 1080, AddrOffset := 24, NameOffset := 48
        Else
            StructSize := 1064, AddrOffset := 20, NameOffset := 32
        VarSetCapacity(MODULEENTRY32, StructSize, 0)
        NumPut(StructSize, MODULEENTRY32, 0, "uint")
    }
    Process, Exist, %Process%
    If (ErrorLevel = 0)
        Return 0

    snapMod := DllCall("CreateToolhelp32Snapshot", "uint", FLAGS
                                                 , "uint", ErrorLevel
                                                 , "ptr")
    If (snapMod = INVALID_HANDLE_VALUE) {
        Return 0
    }

    If DllCall("Module32FirstW", "ptr", snapMod, "ptr", &MODULEENTRY32)
    {
        pszModule := &MODULEENTRY32 + NameOffset
        If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
        {
            DllCall("CloseHandle", "ptr", snapMod)
            Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
        }

        While DllCall("Module32NextW", "ptr", snapMod, "ptr", &MODULEENTRY32)
        {
            If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
            {
                DllCall("CloseHandle", "ptr", snapMod)
                Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
            }
        }
    }
    DllCall("CloseHandle", "ptr", snapMod)
    Return 0
}

24

Re: AHK: Тип данных

YMP пишет:

Стандартный адрес 0x400000.

   Не понимаю. Приложений много, все грузятся на свободные места в памяти. Как может быть один адрес для нескольких при приложений?

Если подозреваете, что у процесса он нестандартный

   Всегда разный базовый адрес.


Попробовал с броузером Opera х32. Базовый получился 0x00DF0000

ProcessName := "opera.exe"
Process, Exist, %ProcessName%
PID := ErrorLevel


ProcGetDllBase(Process, PID)    ; Process = PID or Name.
{
    static StructSize, AddrOffset, NameOffset, MODULEENTRY32
    static FLAGS := 0x18        ; TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32
    static INVALID_HANDLE_VALUE := -1
    If (!StructSize) {
        If (A_PtrSize = 8)
            StructSize := 1080, AddrOffset := 24, NameOffset := 48
        Else
            StructSize := 1064, AddrOffset := 20, NameOffset := 32
        VarSetCapacity(MODULEENTRY32, StructSize, 0)
        NumPut(StructSize, MODULEENTRY32, 0, "uint")
    }
    Process, Exist, %Process%
    If (ErrorLevel = 0)
        Return 10

    snapMod := DllCall("CreateToolhelp32Snapshot", "uint", FLAGS
                                                 , "uint", ErrorLevel
                                                 , "ptr")
    If (snapMod = INVALID_HANDLE_VALUE) {
        Return 20
    }

    If DllCall("Module32FirstW", "ptr", snapMod, "ptr", &MODULEENTRY32)
    {
        pszModule := &MODULEENTRY32 + NameOffset
        If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
        {
            DllCall("CloseHandle", "ptr", snapMod)
            Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
        }

        While DllCall("Module32NextW", "ptr", snapMod, "ptr", &MODULEENTRY32)
        {
            If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
            {
                DllCall("CloseHandle", "ptr", snapMod)
                Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
            }
        }
    }
    DllCall("CloseHandle", "ptr", snapMod)
    Return 30
}
    
    
addr := ProcGetDllBase("opera.exe", "opera.exe")
MsgBox, %addr%  
    
Exit 

   Выдаёт "30". В чём может быть ошибка?

25

Re: AHK: Тип данных

Next пишет:

   Не понимаю. Приложений много, все грузятся на свободные места в памяти. Как может быть один адрес для нескольких при приложений?

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

Выдаёт "30". В чём может быть ошибка?

Наверно, в том, что вы меняете код, не понимая, что делаете. Второй параметр функции — имя, а не PID.

26 (изменено: Next, 2013-11-27 16:24:32)

Re: AHK: Тип данных

Изменил начало

ProcessName := "opera.exe"
ProcGetDllBase(Process, ProcessName)    ; Process = PID or Name.

  Результат тот же. Какое имя вы имеете ввиду? И что тогда говорит примечание?

27 (изменено: YMP, 2013-11-27 16:43:05)

Re: AHK: Тип данных

Не надо ничего менять в функции. Зачем вы это делаете? Имя второго параметра (DllName) используется в коде функции, а вы это имя меняете на что-то левое. Естественно, получается левый результат.

Примечание говорит о том, что параметр Process может быть именем процесса или его PID. Ко второму параметру это не относится. Там может быть только имя.

28

Re: AHK: Тип данных

Вот этот код (целиком и безо всяких изменений) у вас работает?

SetFormat, Integer, Hex
ProcessName := "opera.exe"
addr := ProcGetDllBase(ProcessName, ProcessName)
MsgBox, % addr

ProcGetDllBase(Process, DllName)    ; Process = PID or Name.
{
    static StructSize, AddrOffset, NameOffset, MODULEENTRY32
    static FLAGS := 0x18        ; TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32
    static INVALID_HANDLE_VALUE := -1
    If (!StructSize) {
        If (A_PtrSize = 8)
            StructSize := 1080, AddrOffset := 24, NameOffset := 48
        Else
            StructSize := 1064, AddrOffset := 20, NameOffset := 32
        VarSetCapacity(MODULEENTRY32, StructSize, 0)
        NumPut(StructSize, MODULEENTRY32, 0, "uint")
    }
    Process, Exist, %Process%
    If (ErrorLevel = 0)
        Return 0

    snapMod := DllCall("CreateToolhelp32Snapshot", "uint", FLAGS
                                                 , "uint", ErrorLevel
                                                 , "ptr")
    If (snapMod = INVALID_HANDLE_VALUE) {
        Return 0
    }

    If DllCall("Module32FirstW", "ptr", snapMod, "ptr", &MODULEENTRY32)
    {
        pszModule := &MODULEENTRY32 + NameOffset
        If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
        {
            DllCall("CloseHandle", "ptr", snapMod)
            Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
        }

        While DllCall("Module32NextW", "ptr", snapMod, "ptr", &MODULEENTRY32)
        {
            If DllCall("lstrcmpiW", "wstr", DllName, "ptr", pszModule) = 0
            {
                DllCall("CloseHandle", "ptr", snapMod)
                Return NumGet(MODULEENTRY32, AddrOffset, "ptr")
            }
        }
    }
    DllCall("CloseHandle", "ptr", snapMod)
    Return 0
}

29

Re: AHK: Тип данных

Меня сбило

В качестве DllName укажите имя самого процесса.

  Работает, спасибо.

30 (изменено: Next, 2013-12-29 11:46:36)

Re: AHK: Тип данных

YMP пишет:

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

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

31

Re: AHK: Тип данных

Так мало ли ему участков выделено. Тут один человек уже поднимал тему про карту памяти процесса. Я лично этим вопросом не занимался.