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

Как скопировать участок памяти.


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

При написании скрипта возникла необходимость скопировать довольно большой участок памяти (точнее 364 байта) из одного адреса в другой (Вручную это получалось и в игре получаю то что хотел).

Помогите написать скрипт на Ассемблере.

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

[ENABLE]

...

alloc(newmem,2048)

...

label(loop)

newmem:

...

push eax // Заталкиваем в стек

push esi // регистры

push ecx // чтобы восстановить потом

push ebx // оригинальные значения

mov ecx,364 // Записываем количество проходов в цикле

loop:

lea esi,[oldaddress] // Поместить в ESI адрес старого участка памяти

lea ebx,[newaddress] // поместить в ebx адрес-приемник

lodsb // загрузить в al байт из [ESI]

mov byte ptr [ebx],al // записать в новый адрес

dec ecx // Уменьшить счетчик цикла

inc ebx // Увеличить адрес-приемник

cmp ecx,0 // Достигли ли конца цикла?

je @F // Если да, выходим из цикла

jmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла

@@: // Безымянная метка для указания местоположения выхода из цикла

pop ebx // Восстановление

pop ecx // задействованных

pop esi // в цикле

pop eax // регистров

...

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

Если это надо сделать на CE Autoassembler, то пример из справки с записью 16 байт из адреса 00410000.

ReadMem examplealloc(x,16)alloc(script,2048)script:mov eax,[x]mov edx,[x+c]retx:readmem(00410000,16) //place the contents of address 00410000 at the address of X

Если на Ассемблере, то укажи какой именно Ассемблер: fasm, masm, tasm и прочие... Хотя ты мог поискать как работать с память на WinAPI на интересующем Ассемблере.

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

Если это надо сделать на CE Autoassembler, то пример из справки с записью 16 байт из адреса 00410000.

ReadMem examplealloc(x,16)alloc(script,2048)script:mov eax,[x]mov edx,[x+c]retx:readmem(00410000,16) //place the contents of address 00410000 at the address of X

Если на Ассемблере, то укажи какой именно Ассемблер: fasm, masm, tasm и прочие... Хотя ты мог поискать как работать с память на WinAPI на интересующем Ассемблере.

Это надо сделать на CE Autoassembler. В программировании 0, пользуюсь только CE. В следующий раз буду обязательно писать CE Autoassembler.

 

Попытался вставить скрипт в код, возникли вопросы:

 

alloc(newMem, 2048)

alloc(x,364)
label(returnHere)
 
 
newMem:
 
....................................
 
push ebx
push edx
mov ebx,[x+4]
mov edx,[x+dbc]
ret
 
x:
readmem(?????????,364)
pop edx
pop ebx
 
jmp returnHere
 
..............................
jmp newMem
..............................
returnHere:
 
[DISABLE]
.................................
 
1. alloc(x,364) - у Вас 16 у меня 364. Я правильно понял, что это в десят. системе, т.к. 16c (364 в десят.) CE не приняла?
2. Все регистры используются, поэтому правильно ли я использую push и pop?
3. Допустим мне нужно  скопировать 364 байта начинающихся с адреса [eax+4] в   [eax+dbc], что поставить вместо ????????? или как получить ????????? значение.
4. Перепишите пожалуйста мой код правильно.
Ссылка на комментарий
Поделиться на другие сайты

[ENABLE]...alloc(newmem,2048)...label(loop)newmem:...push eax // Заталкиваем в стекpush esi // регистрыpush ecx // чтобы восстановить потомpush ebx // оригинальные значенияmov ecx,364 // Записываем количество проходов в циклеloop:lea esi,[oldaddress] // Поместить в ESI адрес старого участка памятиlea ebx,[newaddress] // поместить в ebx адрес-приемникlodsb // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ebx // Восстановлениеpop ecx // задействованных pop esi // в циклеpop eax // регистров...
Как-то так. Где многоточия - там какой-то другой код.

 

 

что за бред....

push ecx

push esi

push edi

mov ecx,size

mov esi,oldaddress

mov edi,newaddress

rep movsb

pop edi

pop esi

pop ecx

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

что за бред....

push ecx

push esi

push edi

mov ecx,size

mov esi,oldaddress

mov edi,newaddress

rep movsb

pop edi

pop esi

pop ecx

Если работает, то красиво! (Код короче, нету лишней метки и использует 3 регистра). Попозже тоже попробую. Но у MasterGH 2 регистра. Хочется попробовать и этот скрипт.

Как новичку - что делает инструкция rep movsb?

И правильно я понимаю что в "mov ecx,size" size в шестнадцатитер. системе, т.е. в моём случае 16c?

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

что за бред....

push ecx

push esi

push edi

mov ecx,size

mov esi,oldaddress

mov edi,newaddress

rep movsb

pop edi

pop esi

pop ecx

rep movsb, для тех кто в танке, будет повторять запись одного и того же байта, запусти и проверь. А нужно скопировать весь участок.

Если разжевать - мой код это memcpy по сишному, а твой - memset

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

[ENABLE]...alloc(newmem,2048)...label(loop)newmem:...push eax // Заталкиваем в стекpush esi // регистрыpush ecx // чтобы восстановить потомpush ebx // оригинальные значенияmov ecx,364 // Записываем количество проходов в циклеloop:lea esi,[oldaddress] // Поместить в ESI адрес старого участка памятиlea ebx,[newaddress] // поместить в ebx адрес-приемникlodsb // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ebx // Восстановлениеpop ecx // задействованных pop esi // в циклеpop eax // регистров...
Как-то так. Где многоточия - там какой-то другой код.

 

Мне кажется что в скрипте ошибка, Нужно сюда :

 

dec ecx // Уменьшить счетчик цикла

inc ebx // Увеличить адрес-приемник

 

добавить ещё одну строку, т.е. так:

 

dec ecx // Уменьшить счетчик цикла

inc esi // Увеличить адрес старого участка памяти

inc ebx // Увеличить адрес-приемник

 

Попробую это проверить. (а то пока код не работает).

Нет так тоже не работает. Где то ещё ошибка. Проверьте скрипт пожалуйста.

А то писать 364 раза 

push ebx

mov byte ptr ebx,[eax+4]

move byte ptr [eax+dbc],ebx

pop ebx

push ebx

mov byte ptr ebx,[eax+5]

move byte ptr [eax+dbd],ebx

pop ebx

.............................

и так далее, не хочется

 

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

rep movsb, для тех кто в танке, будет повторять запись одного и того же байта, запусти и проверь. А нужно скопировать весь участок.

Если разжевать - мой код это memcpy по сишному, а твой - memset

это stosb так делает через еах. memcpy использует movsd когда блок большой.

его еще можно ускорить если код часто юзается. будет dword'ами копир...

mov ecx,size

mov edx,ecx

shr ecx,2

and edx,3

rep movsd

mov ecx,edx

rep movsb

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

ТОВАРИЩИ HELP!!!!!!!!!!!!!!!!

Пока игрался с проверкой скриптов, случайно сохранил поверх своей таблицы нулевую таблицу.

Неужели вся 2-х недельная работа на смарку (там 10 рабочих скриптов и куча адресов была)?

Или есть возможность как то восстановить?


что за бред....

push ecx

push esi

push edi

mov ecx,size
mov esi,oldaddress
mov edi,newaddress
rep movsb

pop edi

pop esi

pop ecx

Проверил скрипт: при запуске кода - игра вылетела.

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

[ENABLE]...alloc(newmem,2048)...label(loop)newmem:...push eax // Заталкиваем в стекpush esi // регистрыpush ecx // чтобы восстановить потомpush ebx // оригинальные значенияmov ecx,364 // Записываем количество проходов в циклеloop:lea esi,[oldaddress] // Поместить в ESI адрес старого участка памятиlea ebx,[newaddress] // поместить в ebx адрес-приемникmov al,[esi] // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникinc esi // увеличить адрес-источникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ebx // Восстановлениеpop ecx // задействованных pop esi // в циклеpop eax // регистров...

Попробуй так.

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

mov al,[esi] // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникinc esi // увеличить адрес-источник

Попробуй так.

Хорошо попробую. Но теперь, пока не восстановлю. :unsure:

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

[ENABLE]...alloc(newmem,2048)...label(loop)newmem:...push eax // Заталкиваем в стекpush esi // регистрыpush ecx // чтобы восстановить потомpush ebx // оригинальные значенияmov ecx,364 // Записываем количество проходов в циклеloop:lea esi,[oldaddress] // Поместить в ESI адрес старого участка памятиlea ebx,[newaddress] // поместить в ebx адрес-приемникmov al,[esi] // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникinc esi // увеличить адрес-источникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ebx // Восстановлениеpop ecx // задействованных pop esi // в циклеpop eax // регистров...

Попробуй так.

 

Попробовал, не пашет.

Нашёл ещё одну ошибку в коде, нужно так:

 

push edx // Заталкиваем в стекpush esi // регистрыpush ecx // чтобы восстановить потомpush ebx // оригинальные значенияmov ecx,16c // Записываем количество проходов в цикле{loop:} //МЕТКУ НУЖНО СТАВИТЬ НИЖЕ ПЕРВЫХ АДРЕСОВ!!!!!lea esi,[eax+dbc] // Поместить в ESI адрес старого участка памятиlea ebx,[eax+53a8] // поместить в ebx адрес-приемникloop:mov al,[esi] // загрузить в al байт из [ESI]mov byte ptr [ebx],al // записать в новый адресdec ecx // Уменьшить счетчик циклаinc ebx // Увеличить адрес-приемникinc esi // увеличить адрес-источникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp loop // Прыгаем на метку loop, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ebx // Восстановлениеpop ecx // задействованныхpop esi // в циклеpop edx // регистров

 

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

ТОВАРИЩИ HELP!!!!!!!!!!!!!!!!

Пока игрался с проверкой скриптов, случайно сохранил поверх своей таблицы нулевую таблицу.

Неужели вся 2-х недельная работа на смарку (там 10 рабочих скриптов и куча адресов была)?

Или есть возможность как то восстановить?

 

Уф восстановил. :-D  Получилось даже Красивше. 

Всё-таки идти по проторенной дороге гораздо быстрее - понадобилось двое суток вместо 2-х недель.

Осталось поиграться с координатами и можно делать трейнер.

Но вопрос "есть возможность как то восстановить?" оставлю открытым, вдруг кто-нибудь знает ответ.

Да и забыл: 

 

Для новичков, таких же как и я.

Столкнулся с проблемкой. И нашёл решение, может кому-то из новичков поможет.

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

Когда при восстановлении таблицы я дошёл до написания этого скрипта, у меня метка адреса оказалась другая. В результате, активация вроде бы рабочего скрипта, приводила к вылету игры.

Я вначале растерялся, перезагрузка не помогала, вручную вписать адрес в код нет возможности, я даже пару раз переустановил игру по глупости.

 

Короче, если поняли в чём была проблема, решение:

Создаём из инструкции, соответствующей нужному адресу игры, новый скрипт с использованием Аобскана. 

Оставляем в скрипте оригинальный код, главное метку адреса делаем как в начальном скрипте (перед вылетом).

Активируем скрипт, выключаем и всё адрес игры восстановлен.

 

Ну вроде бы так. Опытным пользователям просьба не смеяться, это я для нас неопытных написал.

 

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

  • 3 недели спустя...

Если это надо сделать на CE Autoassembler, то пример из справки с записью 16 байт из адреса 00410000.

ReadMem examplealloc(x,16)alloc(script,2048)script:mov eax,[x]mov edx,[x+c]retx:readmem(00410000,16) //place the contents of address 00410000 at the address of X

Если на Ассемблере, то укажи какой именно Ассемблер: fasm, masm, tasm и прочие... Хотя ты мог поискать как работать с память на WinAPI на интересующем Ассемблере.

У меня вопрос, этот пример только для статического адреса или можно скрипт как-то для динамического адреса написать.

Вот я попробовал несколько вариантов.

Пере пишите пожалуйста, если всё-таки пример возможен и для динамического адреса, мой скрипт:

Собственно вопрос, что здесь (readmem(Istochnik,364)) вместо Istochnik нужно поставить в моём случае, потому что ни константу, ни [eax+dbc], ни адрес с поинтерами СЕ не компилирует.

Вопрос задавал уже в самом начале обсуждения, но мне пока так никто и не ответил.

[ENABLE]aobscan(address23, 8D B4 10 B8 0D 00 00 F3 A5 E8 FD 82 2E 00)alloc(newMem23, 1024)alloc(x,364)label(Istochnik)label(returnHere23)registersymbol(address23)registersymbol(Istochnik)newMem23:lea esi,[eax+edx+00000DB8]repe movsdmov [eax+ea4],femov [eax+ea8],felea Istochnik,[eax+dbc]push ebx         // Сохраняемpush ecx         // регистрыmov ebx,[x]      // адрес источника [eax+dbc] -> xmov ecx,[x+45ec] // адрес приёмника [eax+53a8]-> x+(53a8-dbc)-> x+45ECret              // копируем памятьpop ecx          // Восстанавливаемpop ebx          // регистрыx:readmem(Istochnik,364)Istochnik:dd 0jmp returnHere23address23:jmp newMem23db 90 90 90 90returnHere23:[DISABLE]address23: {TH.exe+20CB5:}lea esi,[eax+edx+00000DB8]      // Собственно копируем полностьюrepe movsd                      // характеристики предметаunregistersymbol(Istochnik)     // положенного 1 в рюкзак поверхunregistersymbol(address23)     // характеристик взятого предметаdealloc(x,364)dealloc(newMem23) 
Ссылка на комментарий
Поделиться на другие сайты

  • 2 месяца спустя...
gmz

Впервые столкнулся с твоими сообщениями начиная с этой темы и читая их по сегодняшний день,  не заметил, чтобы хотя бы одно сообщение помогло пользователю задавшему вопрос. В основном все сообщения - ВЫПЕНДРЁЖ. Многие сообщения для меня не понятны (т.к. я нуль в программировании) и скорее всего ты разбираешься в вопросе о котором пишешь, но пока складывается впечатление (и Xipho по-моему прав) - ты ПУСТОЗВОН.

 

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

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

gmz

Впервые столкнулся с твоими сообщениями начиная с этой темы и читая их по сегодняшний день,  не заметил, чтобы хотя бы одно сообщение помогло пользователю задавшему вопрос. В основном все сообщения - ВЫПЕНДРЁЖ. Многие сообщения для меня не понятны (т.к. я нуль в программировании) и скорее всего ты разбираешься в вопросе о котором пишешь, но пока складывается впечатление (и Xipho по-моему прав) - ты ПУСТОЗВОН.

 

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

 

*facepalm* гуглить надо было. короче пробуй:

newMem23:lea esi,[eax+edx+0xDB8]rep movsdmov [eax+0xea4],femov [eax+0xea8],fepush ecxpush edxpush esipush edimov ecx,0x16clea esi,[eax+0xdbc]lea edi,[eax+0x53a8]shr ecx,2and edx,3rep movsdmov ecx,edxrep movsbpop edipop esipop edxpop ecxjmp returnHere23

не тестил. может вместо rep -> repe хз как это СЕ видит. будет по 4 байта копировать, если после and edx,3 останется что то - побайтово.

если крешанет - добавь перед rep movsd флаг направления cld

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

короче пробуй:

Лично мне - ты доказал всё.

Про​шу прощения за  сообщение # 20 (здесь) ]и беру все свои слова назад.

и я меняю о тебе своё отношение.

 

 

[ENABLE]aobscan(address23, 8D XX XX XX XX XX XX F3 A5 E8 XX XX XX XX FF XX XX XX XX XX XX 8D XX XX XX XX XX XX)alloc(newMem23, 512)label(returnHere23)registersymbol(address23)newMem23:lea esi,[eax+edx+0xDB8]rep movsdmov [eax+0xea4],femov [eax+0xea8],fepush ecxpush edxpush esipush edimov ecx,0x16clea esi,[eax+0xdbc]lea edi,[eax+0x53a8]shr ecx,2and edx,3rep movsdmov ecx,edxrep movsbpop edipop esipop edxpop ecxjmp returnHere23address23:jmp newMem23db 90 90 90 90returnHere23:[DISABLE]address23: {TH.exe+20CB5:}lea esi,[eax+edx+00000DB8]      // Собственно копируем полностьюrepe movsd                      // характеристики волшебного предмета                                // положенного 1 в рюкзак поверхunregistersymbol(address23)     // характеристик взятого предметаdealloc(newMem23) 
Ссылка на комментарий
Поделиться на другие сайты

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

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

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