1 (изменено: Pogodin, 2013-10-15 23:52:00)

Тема: AHK: Карта памяти

Привет!
Нужно разобраться со структурой памяти приложения. Пробовал artmoney, но там и сохранить по человечески нельзя и вообще всё довольно неудобно.  Хочу написать программу, которая будет как artmoney читать память процесса, но  сохранять в файл результаты, чтобы потом легче было разбираться что, где  и на что ссылается. Чтобы можно было вставить в Excel и обрабатывать дальше.
   Как я понял AHK умеет читать память, надо это делать как-то не побайтно, а как artmoney, находить и текст и числовые значения.
   Прошу помочь советом.

2 (изменено: Pogodin, 2013-10-17 03:47:27)

Re: AHK: Карта памяти

Я что-то не то спросил? Или не так как надо? Правила читал и соблюдаю.

3

Re: AHK: Карта памяти

Думаю, причина в том, что ни у кого нет подобного опыта. Поэтому и советов нет.

4

Re: AHK: Карта памяти

На англоязычном форуме есть похожая тема.

5

Re: AHK: Карта памяти

Уф, тут на русском бы разобраться.  Попробуем поэтапно.
Как средствами AHK узнать адреса в памяти, которые занимает конкретный процесс?

6

Re: AHK: Карта памяти

Средствами АНК никак. Это надо искать подходящие функции Windows API и вызывать через DllCall.

7

Re: AHK: Карта памяти

А не известны ли уже опробованные для аналогичных целей функции Windows API?

8

Re: AHK: Карта памяти

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

9

Re: AHK: Карта памяти

Боюсь, что не справлюсь.
Может проще написать программу, которая будет извлекать нужные данные из Artmoney и удобно их сохранять?
  Может у кого-то ещё другие идеи есть?

10

Re: AHK: Карта памяти

Попытался разобраться в коде с английского форума. Пока безуспешно.  Может кто-нибудь вкратце объяснить что делает этот код и как его применять?


; wont correctly handle 8 bytes with extreme values
ReadMemory(MADDRESS=0,PROGRAM="",BYTES=4)
{
   Static OLDPROC, ProcessHandle
   VarSetCapacity(MVALUE, BYTES,0)
   If (PROGRAM != OLDPROC || !ProcessHandle)
   {
      WinGet, pid, pid, % OLDPROC := PROGRAM
      ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
      ,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
      ,"Int",16,"Int",0,"UInt",pid) : 0)
   }
   
   If !(ProcessHandle && DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",BYTES,"UInt *",0))
      return !ProcessHandle ? "Handle Closed: " closed : "Fail"
   else if (BYTES = 1)
      Type := "UChar"
   else if (BYTES = 2)
      Type := "UShort"
   else if (BYTES = 4)
      Type := "UInt"
   else 
   {
      loop % BYTES 
          result += numget(MVALUE, A_index-1, "Uchar") << 8 *(A_Index-1)
      return result
   }

   return numget(MVALUE, 0, Type)
}

;__________________________________
; Automatically closes handle when a new (or null) program is indicated
; Otherwise, keeps the process handle open between calls that specify the
; same program. When finished reading memory, call this function with no
; parameters to close the process handle i.e: "Closed := ReadMemory_Str()"

; the lengths probably depend on the encoding style, but for my needs they are always 1

;//function ReadMemory_Str 
ReadMemory_Str(MADDRESS=0, PROGRAM = "", length = 0 , terminator = "")  ; "" = Null
{ 
    Static OLDPROC, ProcessHandle

    If (PROGRAM != OLDPROC || !ProcessHandle)
    {
        WinGet, pid, pid, % OLDPROC := PROGRAM
        ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
        ,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
        ,"Int",16,"Int",0,"UInt",pid) : 0) ;PID is stored in value pid
    }
    ; length depends on the encoding too
    VarSetCapacity(Output, length ? length : 1, 0)
    If !length ; read until terminator found or something goes wrong/error
    {
        Loop
        { 
            success := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS++, "str", Output, "Uint", 1, "Uint *", 0) 
            if (ErrorLevel || !success || Output = terminator) 
                break
            teststr .= Output 
        } 
    }        
    Else ; will read X length
    {
        DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS, "str", Output, "Uint", length, "Uint *", 0) 
        ;  Loop % length
        ;     teststr .= chr(NumGet(Output, A_Index-1, "Char"))      
        teststr := StrGet(&Output, length, "UTF-8")
    }
    return teststr
}

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

11

Re: AHK: Карта памяти

Про окно там вроде нет ничего. Просто чтение заданного количества байтов из памяти другого процесса по заданному адресу.

12

Re: AHK: Карта памяти

Как задать нужный процесс? Я считал что его через WinGet находят.

13

Re: AHK: Карта памяти

В этих функциях, как я понял, считается, что идентификатор процесса уже лежит в переменной pid. Можно его получить командой Process или WinGet. Вообще тут на форуме были более внятные функции для чтения памяти процесса. Но только что они вам дадут? Где вы адреса возьмёте, откуда читать? Какие диапазоны адресов заняты данными процесса, вы же не знаете.

14

Re: AHK: Карта памяти

Буду пытаться составить "карту" из данных которые мне известны, а потом попробую вывести закономерности и найти фиксированные адреса указателей. Если я правильно понимаю как это всё устроено.

15 (изменено: Pogodin, 2013-11-02 03:11:54)

Re: AHK: Карта памяти

Взял код из соседней ветки и пытаюсь его использовать для составления карты памяти процесса.


ProcessName := "SpiderSolitaire.exe"
Size :=1
base := 0x000D1144
Process, Exist, %ProcessName%
PID := ErrorLevel
VarSetCapacity(Buf,Size, 0)
PROCESS_VM_READ = 0x10

ssss =0x58

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)

Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, base
                                  , UInt, &Buf
                                  , UInt, Size
                                  , UInt, 0)

pointer := NumGet(Buf)


Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, pointer + ssss
                                  , UInt, &Buf
                                  , UInt, Size
                                  , UInt, 0)
MsgBox, % NumGet(Buf)

  Прошу посмотреть насколько хорошо он подходит для этих целей.
И ещё вопросы.
1. Пробовал вставить в loop, работает довольно медленно. Можно как-то ускорить?
2. Как читать не по 1 байту, а по 2,4? Пробовал увеличить переменную Size, результаты получаются не те, которые я ожидал.
3. Какие функции выполняют тут числа в PROCESS_VM_READ и ssss?

16 (изменено: YMP, 2013-11-02 08:24:22)

Re: AHK: Карта памяти

Pogodin пишет:

1. Пробовал вставить в loop, работает довольно медленно. Можно как-то ускорить?

Читать сразу в буфер большой кусок памяти, а не по паре байт.

2. Как читать не по 1 байту, а по 2,4? Пробовал увеличить переменную Size, результаты получаются не те, которые я ожидал.

А что вы получили и что ожидали? Знаете, как работает функция NumGet и какие у неё параметры?

3. Какие функции выполняют тут числа в PROCESS_VM_READ и ssss?

PROCESS_VM_READ — права на открываемый процесс. ssss — сдвиг от полученного указателя к адресу нужного числа, видимо.

17

Re: AHK: Карта памяти

YMP пишет:
Pogodin пишет:

1. Пробовал вставить в loop, работает довольно медленно. Можно как-то ускорить?

Читать сразу в буфер большой кусок памяти, а не по паре байт.

   Как это правильно отрегулировать? Простое увеличение Size что-то нарушает в работе программы. Наверное надо как-то менять типы переменных?





2. Как читать не по 1 байту, а по 2,4? Пробовал увеличить переменную Size, результаты получаются не те, которые я ожидал.

А что вы получили и что ожидали? Знаете, как работает функция NumGet и какие у неё параметры?

   Ждал получить содержимое ячеек порциями по 4 байта с шагом в 4 байта, а получились какие-то наложения.  Наверное надо применить тип переменной Char?





3. Какие функции выполняют тут числа в PROCESS_VM_READ и ssss?

PROCESS_VM_READ — права на открываемый процесс. ssss — сдвиг от полученного указателя к адресу нужного числа, видимо.

   Значит при чтении всех адресов подряд для составления "карты памяти", смещение вообще нужно убрать?

18

Re: AHK: Карта памяти

Pogodin пишет:

   Как это правильно отрегулировать? Простое увеличение Size что-то нарушает в работе программы. Наверное надо как-то менять типы переменных?

Создать буфер нужного размера, считать туда из процесса нужное количество байт одним вызовом ReadProcessMemory, а дальше можно читать числа из буфера с помощью NumGet. 4 байта — это тип Int или UInt. Прочитали число, увеличили смещение на 4, прочитали следующее и т.д.

19

Re: AHK: Карта памяти

Побайтно смог прочитать. И по 2, и по 8. А больше не получается. Всё равно выдаёт 8 байт в сообщение. Формат не тот, или переменную не так надо задать?

SetFormat IntegerFast, H
ProcessName := "SpiderSolitaire.exe"
Process, Exist, %ProcessName%
PID := ErrorLevel
PROCESS_VM_READ = 0x10


adr_start := 0x0036F7D0
Size := 16
loop, 0x100
{
adr := adr_start  + A_index * Size
hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)

VarSetCapacity(Buf,Size, 0)
Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, adr
                                  , UInt, &Buf
                                  , UInt, Size
                                  , UInt, 0)
volume := NumGet(Buf)
MsgBox, %adr% : %volume%
}

По сколько надо считывать для максимальной скорости? Если учитывать что объём памяти около 200 Mb. Явно же не по 8 байт.

20

Re: AHK: Карта памяти

Самое длинное число, которое читает NumGet — это int64, т.е. 8 байт.
Открывать процесс 0x100 раз не надо, достаточно одного. То же касается создания буфера. В конце всего процесс желательно закрыть функцией CloseHandle(hProcess).

Для максимальной скорости функцию ReadProcessMemory желательно вызвать 1 раз, считав сразу всё нужное (суммарно) количество байт в буфер. Потом уже из буфера можно читать в цикле с помощью NumGet.

21

Re: AHK: Карта памяти

Для максимальной скорости функцию ReadProcessMemory желательно вызвать 1 раз, считав сразу всё нужное (суммарно) количество байт в буфер.

  А как это лучше сделать?

22

Re: AHK: Карта памяти

Так же, как вы уже делаете, только указав суммарно нужное количество байт. Либо я не понял вопрос?

23

Re: AHK: Карта памяти

YMP пишет:

считав сразу всё нужное (суммарно) количество байт в буфер.

   Именно вот это как осуществить?  Не представляю. И сколько за раз читать посоветуете?

24

Re: AHK: Карта памяти

Просто указать нужное значение Size. Сколько памяти не жалко, столько и выделяйте под буфер. Столько и считайте в него.

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

25

Re: AHK: Карта памяти

Как внести в буфер содержимое ячеек памяти?

26

Re: AHK: Карта памяти

У вас в коде ReadProcessMemory как раз это и делает. Буфер — это переменная Buf.

27

Re: AHK: Карта памяти

Почему-то не получилось вывести Buf через MsgBox. Я подумал, что нужно ещё какое-то действие.

28

Re: AHK: Карта памяти

Так я вам сказал про него: чтение из буфера с помощью NumGet.

29

Re: AHK: Карта памяти

    loop,Parse, Buf,
        {
        var := NumGet(A_LoopField)
        MsgBox, %var%
        }

  Так не получается.

30

Re: AHK: Карта памяти

А зачем так? У вас же всё есть в коде:

MsgBox, % NumGet(Buf)

Второй параметр у NumGet — смещение, третий — тип числа.

31 (изменено: Pogodin, 2013-11-04 14:12:49)

Re: AHK: Карта памяти

Всё равно не получается. Вот такой вариант везде выдаёт "0x0", даже там где совсем другие значения.

SetFormat,IntegerFast, H
Size := 0x100
adres_start := 0x0048f810 - Size
Sdvig := 0x0
hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
loop, 0x100
    {
    adr := adres_start  + A_index * Size
    
    Process, Exist, %ProcessName%
    PID := ErrorLevel    
    VarSetCapacity(Buf,0x100,0)
    PROCESS_VM_READ = 0x10

    Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                      , UInt, adr
                                      , UInt, &Buf
                                      , UInt, Size
                                      , UInt, 0)
                                      
                                      
    loop, 0x20
        {
        var8 := NumGet(Buf,Sdvig,Uint)
        MsgBox, %var8%
        Sdvig := A_index * 0x4
        }
    }





Мне этот сериал, с выяснением правильности написания 5-10 строк кода, уже почти начинает нравится.

32

Re: AHK: Карта памяти

Смотрите, что возвращают функции. Если hProcess или Ret = 0, это ошибка. Советую читать описания используемых функций и делать такие проверки самостоятельно. ErrorLevel после команды Process также надо бы проверять на 0, на случай необнаружения процесса.

Тип для NumGet должен быть в кавычках. В справке об этом написано. Почему вы их не поставили?

Мне этот сериал, с выяснением правильности написания 5-10 строк кода, уже почти начинает нравится.

Что же вы хотите, если взялись составлять карту памяти процесса, обладая нулевыми знаниями и нежеланием читать документацию? Вот отсюда и сериал.

33 (изменено: Pogodin, 2013-11-04 16:58:48)

Re: AHK: Карта памяти

Всё что касается DllCall написано удивительно непонятно. Либо объект сам по себе настолько сложен, либо сам описывающий слишком далёк от умения что-либо объяснить пользователю со знаниями не равными его собственным.

Ошибку нашёл, разбираюсь дальше. Спасибо!

34

Re: AHK: Карта памяти

Неравенство знаний бывает разного размера. На какой нужно расчитывать? 2+2=4?

35 (изменено: Alectric, 2013-11-04 19:32:14)

Re: AHK: Карта памяти

OFF:Да хватит уже спорить!

Источник: http://forum.script-coding.com/viewtopic.php?id=2734

#SingleInstance,Force
#NoEnv
SetFormat, Integer, H

ProcessName = notepad.exe         ; Имя процесса.
ReadAddress = 0x76d5B2D0          ; Адрес, откуда читать.
ReadSize = 512                      ; Сколько байт читать.
VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, ReadAddress
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)

DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.

If(!Ret)
{
  MsgBox, Не удалось прочитать.
  ExitApp
}




map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

loop
{
  if (a_index>ReadSize)
  {
    msgbox,Все.`nНачальный адрес: %ReadAddress%`nСколько читать: %ReadSize% байт`nКарта:`n%map%`nМожете сравнить с редактором памяти в ArtMoney.
    break
  }
  char:=  NumGet(Buf, a_index-1, "UChar")
tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
  stringtrimleft,char,char,2
  StringLen,len,char
  if len<2
    char=0%char%
  if r<16
    map.=" "char
  else
  {
    map.="`n" ReadAddress+a_index-1 " | " char
    r=
  }
  r+=1
}
exitapp
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

36

Re: AHK: Карта памяти

Alectric
Это вы со второго байта буфер читаете.

37 (изменено: Alectric, 2013-11-04 19:41:17)

Re: AHK: Карта памяти

YMP пишет:

Alectric
Это вы со второго байта буфер читаете.

Так правильно:

NumGet(Buf, a_index-1, "UChar")

Исправил наверху.

Почему-то после перезапуска блокнота - "Не удалось прочитать"...



Later:
А-а! понял - адреса поменялись.

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

38 (изменено: Pogodin, 2013-11-04 22:20:33)

Re: AHK: Карта памяти

Alectric, вот где Вы раньше были?  
Я уже добрался примерно до этой же стадии, правда ещё долбался  с минусами и удобной записью. У Вас, конечно, всё красивей и с отличной демонстрацией. Спасибо!


Вопросы ко всем.

По сколько байт лучше читать в буфер за раз, чтобы максимально ускорить процесс?
Как быть с !Ret?  Могут такие области быть между заполненными областями? Тогда надо будет идти дальше.

39

Re: AHK: Карта памяти

Pogodin пишет:

Alectric, вот где Вы раньше были?  
Я уже добрался примерно до этой же стадии, правда ещё долбался  с минусами и удобной записью. У Вас, конечно, всё красивей и с отличной демонстрацией. Спасибо!


Вопросы ко всем.

По сколько байт лучше читать в буфер за раз, чтобы максимально ускорить процесс?
Как быть с !Ret?  Могут такие области быть между заполненными областями? Тогда надо будет идти дальше.

Незачто.

А сколько у вас всего нужно прочитать?

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

40

Re: AHK: Карта памяти

До 200МБ

41

Re: AHK: Карта памяти

Чесно говоря не знаю, можете попробовать указать данный размер и посмотреть что будет.
Только не выводить все на экран, иначе точно ошибка будет.

А что будет происходить с картой? Сохранение в файл или что-то еще?

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

42

Re: AHK: Карта памяти

Думаю попробовать читать кусками по 2МБ и сохранять в файл. Только нужно переделать ваш код, организовать пропуски вместо сообщений где "Не удалось прочитать". И надстроить цикл, который будет задавать автоматическое смещение в зависимости от выбранного размера буфера.

43

Re: AHK: Карта памяти

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

44

Re: AHK: Карта памяти

Надо смотреть, на что именно уходит время, а не гадать на кофейной гуще. В АНК есть встроенная переменная A_TickCount, можно её использовать для измерения, сколько времени занимает кусок кода.

45

Re: AHK: Карта памяти

Я мерил. Но не в этом дело. Я проверяю адреса от 0x0 до 0xFFFFFFFF - это около 4GB. А память программы занимает до 200MB.  Это около 5%.  Прежде чем что-то ускорять неплохо хотя бы вчерне отсеять явно лишнее из пустых 95%.

46

Re: AHK: Карта памяти

Четвёртый гигабайт явно лишний. Третий скорее всего тоже. Это системная память. Пользовательским процессам обычно отданы два нижних.

On 32-bit editions of Windows, applications have 4 gigabyte (GB) of virtual address space available. The virtual address space is divided so that 2 GB is available to the application and the other 2 GB is available only to the system.

The 4-gigabyte tuning (4GT) feature, formerly called 4GT RAM Tuning, increases the virtual address space that is available to the application up to 3 GB, and reduces the amount available to the system to between 1 and 2 GB.

Вообще, наверно, можно использовать VirtualQueryEx, чтобы отсортировать реально выделенные процессу страницы памяти, и уже только их читать. Правда, это только идея, я этим не занимался.

47 (изменено: Alectric, 2013-11-06 18:02:43)

Re: AHK: Карта памяти

Быстрее чем нижеприведенный код врядли получится.

#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
onexit,exit
SetBatchLines,-1
savefile=map1.txt

loop,100
{
  ifnotexist,map%A_index%.txt
    savefile=map%A_index%.txt
}

ProcessName = notepad.exe         ; Имя процесса.
StartAdres:=ReadAddress:= 0x000308D0             ; Адрес, откуда читать.
ReadSizeL = 548576             ; Сколько байт читать.
ReadSize = 1
EndAdres:=ReadAddress+ReadSizeL

map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

loop,%ReadSizeL%  ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
  c++
  if c>50000
  {
    c=
    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%
  }

Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, ReadAddress
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)

If(Ret)
{
  char:=  NumGet(Buf, 0, "UChar")
;tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
  stringtrimleft,char,char,2
  StringLen,len,char
  if len<2
    char:=" 0"char
  else
    char:=" "char
}
else
  char=

if r<16
{
  map.=char
}
else
{
  map.="`n" ReadAddress " | " char
  r=
  d++
  if d>10
  {
    fileappend,%map%,%savefile%
    d=
    map=

  }
}
r+=1
ReadAddress++
}
map.="`n`n"
fileappend,%map%,%savefile%
return

exit:
DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.
exitapp

"ReadSizeL" можно указать хоть все 4 GB.

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

48

Re: AHK: Карта памяти

По чтению регионов удалось найти приемлемое решение.  Но всё равно процесс идёт медленнее чем хотелось бы.  Самое узкое место вот здесь:


loop
{
  if (a_index>ReadSize)
  {
   FileAppend,%map%,map.txt
  }
  char:=  NumGet(Buf, a_index-1, "UChar")
  stringtrimleft,char,char,2
  StringLen,len,char
  if len<2
    char=0%char%
  if r<16
    map.=" "char
  else
  {
    map.="`n" ReadAddress+a_index-1 " | " char
    r=
  }
  r+=1
}

  Можно тут что-нибудь оптимизировать?  Можно как-то читать не по одному байту, а по 8 или 16?

49 (изменено: Alectric, 2013-11-06 18:01:25)

Re: AHK: Карта памяти

Pogodin пишет:

Можно тут что-нибудь оптимизировать?  Можно как-то читать не по одному байту, а по 8 или 16?

Чем больше данных будет хранится в переменной, тем медленнее будет процесс.

Вы опробовали код постом раньше, что я написал? (47-й пост)

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

50

Re: AHK: Карта памяти

Да я именно его и использую.  Я ограничил объём map

        if (Strlen(map) > 0xFFFFF)
            {
            FileAppend,%map%,имя.txt
            map = 
            }

Это чуть больше 1Mb. Считаете, что стоит ещё уменьшить?

51 (изменено: Alectric, 2013-11-06 20:33:26)

Re: AHK: Карта памяти

Alectric пишет:

Быстрее чем нижеприведенный код врядли получится.

#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
onexit,exit
SetBatchLines,-1

ProcessName = notepad.exe         ; Имя процесса.
StartAdres:=ReadAddress:= 0x0             ; Адрес, откуда читать.
ReadSizeL = 20971520             ; Сколько байт читать.
ReadSize = 1
EndAdres:=ReadAddress+ReadSizeL
new:=1
savefile=map_%ProcessName%_%new%.txt

map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

loop,%ReadSizeL%  ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
  c++
  if c>50000
  {
    c=
    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%`nEsc - для отмены.
  }

Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, ReadAddress
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)

If(Ret)
{
  char:=  NumGet(Buf, 0, "UChar")
;tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
  stringtrimleft,char,char,2
  StringLen,len,char
  if len<2
    char:=" 0"char
  else
    char:=" "char
}
else
  char=

if r<16
{
  map.=char
}
else
{
  If(Ret)
    map.="`n" ReadAddress " | " char
  r=
  d++
  if d>10
  {
    fileappend,%map%,%savefile%
    d=
    map=
    n++
    if n>6553          ; в 1 файл запишется 65 530 строк по 16 байт данных, или 1 048 480 байт данных, или 1023 kB, или 1 MB
    {
      new++
      savefile=map_%ProcessName%_%new%.txt
      n=
    }
  }
}
r+=1
ReadAddress++
}
map.="`n`n"
fileappend,%map%,%savefile%
gosub,exit

~esc::
exit:
DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.
exitapp

"ReadSizeL" можно указать хоть все 4 GB.

\\\\\\\\\\\\\\\\

Pogodin пишет:

Я ограничил объём map

В моем коде этот объем уже ограничен 10-ю строками по 16 байт.


Или вам нужно разрезать текстовые файлы с данными на куски по 1 MB?
Если да, то нужно менять имя файла после заполнения определенными данными.
Для этого нужно добавить еще один счетчик.

n++
if n>6553          ; в 1 файл запишется 65 530 строк по 16 байт данных, или 1 048 480 байт данных, или 1023 kB, или 1 MB
{
  new++
  savefile=map%new%.txt
  n=
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

52 (изменено: Pogodin, 2013-11-11 12:39:51)

Re: AHK: Карта памяти

Всё равно слишком медленно. Даже после предварительного ограничения области чтения, весь процесс занимает до двух минут. В то время как та же Artmoney успевает прошерстить всё и найти нужное за 5-7 секунд.  Жаль только "карту" не может составить.
  Есть какие-то способы радикально ускорить темп чтения памяти средствами AHK?

53

Re: AHK: Карта памяти

Что имеется в виду под средствами АНК? NumGet?

54

Re: AHK: Карта памяти

Не имеет значения. Если есть в AHK другие функции, или есть возможность встроить в код AHK десяток простых известных строк на ассемблере, то подходит и то, и то.

55

Re: AHK: Карта памяти

На ассемблере нет, а машинный код встроить можно. В Коллекции есть мой пост "Ускорение скриптов машинным кодом".

56 (изменено: Alectric, 2013-11-11 19:07:56)

Re: AHK: Карта памяти

Pogodin пишет:

Всё равно слишком медленно. Даже после предварительного ограничения области чтения, весь процесс занимает до двух минут. В то время как та же Artmoney успевает прошерстить всё и найти нужное за 5-7 секунд.  Жаль только "карту" не может составить.
  Есть какие-то способы радикально ускорить темп чтения памяти средствами AHK?

Artmoney ищет только заданное число, и записывает в список результатов найденные варианты.
А при отображении карты процесса - читает только те, что видно на экране, если растянуть на весь экран около 1 kB.
Просто поиск значения будет быстрее чем запись в файл.

А вы пытаетесь создать карту памяти полностью, т.е. 2 GB или сколько там, да даже 2 mB это 2048 kB.


Разве что, есть вариант на AHK "открыть файл для записи" и записывать данные без лишних запросов ("открыть, найти последнюю строку, записать, закрыть, повторить" - так я представляю FileAppend).

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

57

Re: AHK: Карта памяти

Есть такой вариант — объект File. (Для кого разрабы справку пишут, один Бог ведает).

58 (изменено: Alectric, 2013-11-11 20:30:02)

Re: AHK: Карта памяти

OFF: Новую справку не изучал досканально, до сих пор русифицированной неполной пользуюсь.


Попробовал файловый объект:

Объем: 0x100000
Время работы с "Fileappend": 15210
Время работы с "File Object": 16380

Объем: 0x500000
Время работы с "Fileappend": 56004
Время работы с "File Object.Write": 74179
Время работы с "File Object.WriteLine": 74007

Объем: 0x500000
Время работы с "Fileappend" без форматирования: xxxxx - Очень долго.
Время работы с "Fileappend" с форматом по 16 байт: 74241
Время работы с "File Object" без форматирования: 46816

Без форматирования значит: не удалять "0x"; не добавлять пробел ко всем и 0 к однозначным числам; не дописывать текущий адрес; не переводить строку после 16-и прочитанных байт.

Может я как-то не так его применил?

+ открыть спойлер
#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
onexit,exit
SetBatchLines,-1

starttime:=a_tickcount

ProcessName = notepad.exe         ; Имя процесса.
StartAdres:=ReadAddress:= 0x0             ; Адрес, откуда читать.
ReadSizeL = 0x500000             ; Сколько байт читать.
ReadSize = 1
EndAdres:=ReadAddress+ReadSizeL
new:=1
savefile=map_%ProcessName%_%new%.txt

file := FileOpen(savefile, "w")
if !IsObject(file)
{
  MsgBox Can't open "%FileName%" for writing.
  exitapp
}


map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

loop,%ReadSizeL%  ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
  c++
  if c>25000
  {
    c=
    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%`nEsc - для отмены.
  }

  Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                    , UInt, ReadAddress
                                    , UInt, &Buf
                                    , UInt, ReadSize
                                    , UInt, 0)

  If(Ret)
  {
    char:=  NumGet(Buf, 0, "UChar")
  ;tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
    stringtrimleft,char,char,2
    StringLen,len,char
    if len<2
      char:=" 0"char
    else
      char:=" "char
  }
  else
    char=

  if r<16
  {
    map.=char
  }
  else
  {
    file.Write(map)
    map=
    r=
    If(Ret)
      map.="`n" ReadAddress " | " char
  }
  r+=1
  ReadAddress++
}
map.="`n`n"
fileappend,%map%,%savefile%
gosub,exit

~esc::
exitapp
return



exit:
file.Close()
DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.
SetFormat, Integer, D
end:=a_tickcount-starttime
Msgbox,Время работы: %end%
exitapp

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

59

Re: AHK: Карта памяти

Pogodin пишет:

В то время как та же Artmoney успевает прошерстить всё и найти нужное за 5-7 секунд.  Жаль только "карту" не может составить.

Как это не может? У меня может.

60 (изменено: Alectric, 2013-11-11 20:03:56)

Re: AHK: Карта памяти

Насколько я понял ТС-у нужна не "карта процесса" а данные из "Редактора памяти" в Artmoney.
Это 2 разные вещи...

В редакторе памяти Artmoney есть функция сохранить в Excel, но там всего 512 байт сохраняет.

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

61

Re: AHK: Карта памяти

Alectric пишет:

Может я как-то не так его применил?

Как его можно не так применить?
Можно и через API файл открыть и писать туда.

62 (изменено: Alectric, 2013-11-11 20:57:04)

Re: AHK: Карта памяти

YMP пишет:

Как его можно не так применить?

Ну может я не там поставил открытие файла, или запись в файл...



Later:
Нашел метод ускорить процесс, читая по 16 байт в буфер.
Т.к. в основном если "нельзя прочитать", то "нельзя прочитать" все 16 байт, судя по Artmoney.

Объем: 0x500000            ; 5 mB
Время работы: 19375     ; 20 sec       0.25 mB/sec

+ открыть спойлер
#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
onexit,exit
SetBatchLines,-1

starttime:=a_tickcount

ProcessName = notepad.exe         ; Имя процесса.
StartAdres:=ReadAddress:= 0x0             ; Адрес, откуда читать.
ReadSizeL = 0x50000             ; Сколько байт читать.
ReadSize = 16
EndAdres:=ReadAddress+ReadSizeL*ReadSize
new:=1
savefile=map_%ProcessName%_%new%.txt

;file := FileOpen(savefile, "w")
;if !IsObject(file)
;{
;    MsgBox Can't open "%FileName%" for writing.
;    return
;}


map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

loop,%ReadSizeL%  ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
  c++
  if c>5000
  {
    c=
    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%`nEsc - для отмены.
  }

  Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                    , UInt, ReadAddress
                                    , UInt, &Buf
                                    , UInt, ReadSize
                                    , UInt, 0)

  If(Ret)
  {
loop,%ReadSize%
{
    char:=  NumGet(Buf, a_index-1, "UChar")
  ;tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
    stringtrimleft,char,char,2
    StringLen,len,char
    if len<2
      char:=" 0"char
    else
      char:=" "char
    map.=char
}
      map.="`n" ReadAddress " | " char
      fileappend,%map%,%savefile%
map=
  }

;  if r<16
;  {
;    map.=char
;  }
;  else
;  {
;    If(Ret)
;      map.="`n" ReadAddress " | " char
;    map.=char
;    r=
;    d++
;    if d>10
;    {
;      fileappend,%map%,%savefile%
;      d=
;      map=
;    }
;  }
;  r+=1
ReadAddress+=16
}
map.="`n`n"
fileappend,%map%,%savefile%
gosub,exit

~esc::
exitapp
return

exit:
DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.
SetFormat, Integer, D
end:=a_tickcount-starttime
Msgbox,Время работы: %end%
exitapp

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

63

Re: AHK: Карта памяти

Да, я вот как раз хотел удивиться, что у вас ReadProcessMemory читает по 1 байту. Из пушки по воробью, или даже по комару.
Вообще, память выделяется страницами. Типичный размер страницы 4 КБ. Так что имеет смысл и буфер таким сделать и считывать туда сразу страницу.

64 (изменено: Alectric, 2013-11-11 21:39:35)

Re: AHK: Карта памяти

Спасибо.
Сейчас попробую.



Later:
Объем: 0x500000            ; 5 mB
Время работы: 2979     ; 3 sec       1,6 mB/sec

Только почему-то считало 4 mB вместо 5-и. (судя по адресу)
А-а, понял, просто у блокнота пусто после 4-х mB.

+ открыть спойлер
#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
onexit,exit
SetBatchLines,-1

starttime:=a_tickcount

ProcessName = notepad.exe         ; Имя процесса.
StartAdres:=ReadAddress:= 0x0             ; Адрес, откуда читать.
ReadSizeL = 1280             ; Сколько байт читать.
ReadSize = 4096
EndAdres:=ReadAddress+ReadSizeL*ReadSize
new:=1
savefile=map_%ProcessName%_%new%.txt

    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%`nEsc - для отмены.
;file := FileOpen(savefile, "w")
;if !IsObject(file)
;{
;    MsgBox Can't open "%FileName%" for writing.
;    return
;}


map=__________ | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F`n______________________________________________________`n%ReadAddress% |

VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать.

PROCESS_VM_READ = 0x10            ; Права на процесс.

Process, Exist, %ProcessName%     ; Поиск процесса.

If(!ErrorLevel) {
  MsgBox, Процесс не найден.
  ExitApp
}

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)
If(!hProcess)
{
  MsgBox, Не удалось открыть процесс.
  ExitApp
}

loop,%ReadSizeL%  ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
  c++
  if c>5000
  {
    c=
    tooltip,Начальный адрес: %StartAdres%`nТекущий адрес: "%ReadAddress%"`nКонечный адрес: %EndAdres%`nEsc - для отмены.
  }

  Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                    , UInt, ReadAddress
                                    , UInt, &Buf
                                    , UInt, ReadSize
                                    , UInt, 0)

  If(Ret)
  {
    loop,%ReadSize%
    {
      char:=  NumGet(Buf, a_index-1, "UChar")
;tooltip, % char "`n" a_index  ; Считывание из буфера в переменную.
      stringtrimleft,char,char,2
      StringLen,len,char
      if len<2
        char:=" 0"char
      else
        char:=" "char

      r++
      if r<17
        map.=char
      else
      {
        r=1
        map.="`n" ReadAddress+a_index-1 " | " char
      }
    }
    fileappend,%map%,%savefile%
    map=
  }

ReadAddress+=ReadSize
}
map.="`n`n"
fileappend,%map%,%savefile%
gosub,exit

~esc::
exitapp
return

exit:
DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса.
SetFormat, Integer, D
end:=a_tickcount-starttime
Msgbox,Время работы: %end%
exitapp


Спасибо ТС-у за эту тему, давно хотел с памятью поработать.

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

65

Re: AHK: Карта памяти

Alectric пишет:

Насколько я понял ТС-у нужна не "карта процесса" а данные из "Редактора памяти" в Artmoney.
Это 2 разные вещи...

В редакторе памяти Artmoney есть функция сохранить в Excel, но там всего 512 байт сохраняет.

Artmoney позволяет сохранить процесс. Разве не это требуется?

66

Re: AHK: Карта памяти

Alectric пишет:

Спасибо.


Объем: 0x500000            ; 5 mB
Время работы: 2979     ; 3 sec       1,6 mB/sec

  Это примерно раза в три быстрее чем было.

67 (изменено: Alectric, 2013-11-11 21:41:40)

Re: AHK: Карта памяти

ypppu пишет:

Разве не это требуется?

Честно говоря я не знаю, что Pogodin собрался делать с этими данными...

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

68

Re: AHK: Карта памяти

ypppu пишет:

Artmoney позволяет сохранить процесс. Разве не это требуется?

  Это. Но "мой" процесс быстро меняется. И пока он будет весь сохраняться, содержимое станет другим. Поэтому важна скорость и приходится дробить на куски.

69

Re: AHK: Карта памяти

А остановить процесс перед сохранением нельзя?

70

Re: AHK: Карта памяти

К сожалению, нет.

71

Re: AHK: Карта памяти

Значит, нужна программа, которая сможет мгновенно считать из оперативной памяти весь процесс. А это физически возможно?

72

Re: AHK: Карта памяти

Ладно, пока откажусь от этой идеи. 
  Всем спасибо!

73

Re: AHK: Карта памяти

ypppu пишет:

Значит, нужна программа, которая сможет мгновенно считать из оперативной памяти весь процесс. А это физически возможно?

Мгновенных действий не бывает.

74

Re: AHK: Карта памяти

Pogodin пишет:

К сожалению, нет.

Он имел ввиду функцию "Остановить процесс" в Artmoney.
Все равно нельзя?

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

75

Re: AHK: Карта памяти

Alectric, да, я понял, о чём речь.

Сейчас попробовал использовать "Сохрнить файл дампа памяти" для процесса  из "Диспетчера задач".  Сохраняет быстро. В три раза быстрее кода из последнего варианта. Но как в этом файле рассовать всё по адресам?

76

Re: AHK: Карта памяти

Pogodin пишет:

Сохраняет быстро. В три раза быстрее кода из последнего варианта.

Так он в бинарном виде сохраняет, а у вас ещё преобразование в хекс отнимает кучу времени.

77

Re: AHK: Карта памяти

Понимаю. Но главное - быстро сохранить существующее состояние памяти, а обрабатывать потом можно не спеша.   

Средствами AHK, насколько я понимаю сохранить так невозможно?

А как обрабатывать уже готовый файл из Диспетчера? Как разобраться  что к каким адресам относится?

78

Re: AHK: Карта памяти

Почему невозможно? Для записи бинарных данных в файл есть метод RawWrite объекта File.

Про файл дампа не знаю, не в курсе его формата. Может, в интернете что-то есть об этом. Вряд ли там что-то сложное.

79 (изменено: Alectric, 2013-11-13 17:47:40)

Re: AHK: Карта памяти

Для этого "Дебаггер" нужен. http://msdn.microsoft.com/library/windo … s.85).aspx
http://www.networkworld.com/news/2005/0 … crash.html

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

80

Re: AHK: Карта памяти

YMP пишет:

Почему невозможно? Для записи бинарных данных в файл есть метод RawWrite объекта File.

  Это же великолепно! Правда примеров пока не нашёл.  Но не думаю, что будет значительно медленнее упомянутого способа создания дампа.
  А есть готовые решения по "расшифровке" файлов записанных с помощью RawWrite?

81

Re: AHK: Карта памяти

А что там расшифровывать? Вы сохраните в файл то, что вам прочитала в буфер ReadProcessMemory. Если имеется в виду перевести в хекс, то читайте потом файл методом RawRead опять же в буфер и переводите.

82

Re: AHK: Карта памяти

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

83

Re: AHK: Карта памяти

Пока ничего не получается. Как ведёт себя File.RawRead с участками памяти, которые не читаются?

84

Re: AHK: Карта памяти

А при чём здесь участки памяти? Этот метод читает файл.

85

Re: AHK: Карта памяти

Всё перепутал.  Где тут смайлик "Смущение"?

86

Re: AHK: Карта памяти

Что-то я увяз в этой ReadProcessMemory. Как это всё должно выглядеть?
Допустим я хочу прочитать блок памяти  от
StartAdres := 0x0001000

размером
ReadSize :=0x2000

в процессе mspaint.exe.

Что куда вписывать?

VarSetCapacity(buf,ReadSize, 0)
blok := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", StartAdres, "Ptr", &buf, "Ptr", ReadSize, "PtrP", ?????, "UInt")

  Помогите, пожалуйста!

87

Re: AHK: Карта памяти

Pogodin пишет:

Всё перепутал.  Где тут смайлик "Смущение"?

OFF: http://forum.script-coding.com/viewtopi … 372#p66372

88

Re: AHK: Карта памяти

VarSetCapacity(buf,ReadSize, 0)
blok := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", StartAdres, "Ptr", &buf, "Ptr", ReadSize, "PtrP", BytesRead, "UInt")

89

Re: AHK: Карта памяти

Что такое "BytesRead" я совершенно не понимаю. Имеем стартовое значение, имеем значение, сколько байт от него прочитать, а что даёт этот третий параметр?

90

Re: AHK: Карта памяти

BytesRead — это число реально прочитанных байт. Выходной параметр, т.е. функция сама туда поместит число.
Какой третий параметр? Если &buf, то это адрес буфера.

91

Re: AHK: Карта памяти

YMP пишет:

BytesRead — это число реально прочитанных байт. Выходной параметр, т.е. функция сама туда поместит число.

  Ах, так это только для контроля, типа ErrorLevel?

Какой третий параметр? Если &buf, то это адрес буфера.

   Я имел ввиду BytesRead.

92

Re: AHK: Карта памяти

Pogodin пишет:

Ах, так это только для контроля, типа ErrorLevel?

Вроде того.

93

Re: AHK: Карта памяти

Не получается. В сообщении неизменный 0x0.
Что не так?

#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
SetBatchLines,-1


ProcessName = mspaint.exe
StartAdres := 0x00010000
ReadSize = 0x2000



Process, Exist, %ProcessName% 
If(!ErrorLevel) {
MsgBox, Процесс не найден.
ExitApp
}

PROCESS_VM_READ = 0x10    
PID := ErrorLevel 

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                , Int, False
                                , UInt, PID)
If(!hProcess)
{
MsgBox, Не удалось открыть процесс.
ExitApp
}


VarSetCapacity(buf,ReadSize, 0)
blok := DllCall("ReadProcessMemory", "Ptr", processHandle, "Ptr", StartAdres, "Ptr", &buf, "Ptr", ReadSize, "PtrP", BytesRead, "UInt")
MsgBox, % BytesRead


DllCall("CloseHandle", UInt, hProcess)
exitapp

94

Re: AHK: Карта памяти

hProcess := 
processHandle

Разницы не замечаете?

95

Re: AHK: Карта памяти

Ещё как замечаю. Очень удивлялся, что это за волшебные слова. Вроде бы что-то общее, но как они друг друга "находят" никак понять не мог. ))))
   Спасибо!

96

Re: AHK: Карта памяти

Всё равно без знания английского сплошное шаманство получается. Надёргал строк c RawWrite отовсюду, но всё равно не значю что объявлять и когда, да и всё остальное.

#SingleInstance,Force
#NoEnv
SetFormat, Integer, H
SetBatchLines,-1


ProcessName = mspaint.exe
StartAdres := 0x00010000
ReadSize = 0x2000



Process, Exist, %ProcessName% 
If(!ErrorLevel) {
MsgBox, Процесс не найден.
ExitApp
}

PROCESS_VM_READ = 0x10    
PID := ErrorLevel 

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                , Int, False
                                , UInt, PID)
If(!hProcess)
{
MsgBox, Не удалось открыть процесс.
ExitApp
}


VarSetCapacity(buf,ReadSize, 0)
TargetFile = %StartAdres%.txt
blok := DllCall("ReadProcessMemory", "Ptr", hprocess, "Ptr", StartAdres, "Ptr", &buf, "Ptr", ReadSize, "PtrP", BytesRead, "UInt")
if (BytesRead)
    {
    File := FileOpen(TargetFile, "w"), File.Length := 0    
    File.RawWrite(blok, w_Bytes), File.Close()  
    MsgBox, %w_Bytes%
    }


DllCall("CloseHandle", UInt, hProcess)
exitapp

   Подскажите, пожалуйста, что с RawWrite не так.

97

Re: AHK: Карта памяти


File.RawWrite(buf, BytesRead), File.Close()  
MsgBox, %BytesRead%

98

Re: AHK: Карта памяти

Alectric, и другие, а можно как-то сразу быстро определить не читаемые разделы памяти, чтобы не трать время на их чтение?

99 (изменено: Next, 2014-01-03 17:13:21)

Re: AHK: Карта памяти

Раз на этот вопрос ответить некому, задам другие.

Есть ли возможность ускорить процесс поиска значения памяти в 10-20 раз относительно предложенного?
Есть ли такая возможность в AutoIt или других языках обсуждаемых здесь на форуме?
Если такой способ существует в каком-нибудь другом языке программирования, можно ли встроить его в AHK?

100

Re: AHK: Карта памяти

Next пишет:

Раз на этот вопрос ответить некому

Так я отвечал ведь уже выше. Предложил VirtualQueryEx использовать, чтобы отсеивать невыделенные процессу страницы, если вы это имеете в виду. Конечно, это только идея, реализации у меня нет.

Есть ли возможность ускорить процесс поиска значения памяти в 10-20 раз относительно предложенного?

А фиг его знает. Как я опять же уже писал, надо определить, где именно происходят потери времени, на каких операциях. И предложил идею использовать машинный код. Он может в десятки раз быстрее скриптового работать.