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

Вызвать функцию в Cheat Engine, разбор CrackMe


Trix

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

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

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

Думаю, что мне удалось найти ту функцию(подкорректируйте меня, пожалуйста) выбрал на адресе моей  подопытной переменной "Показать что читает из данного адреса", при нажатии кнопки, которая отнимает единицу у переменной в CE появляется функция, на сколько я понял, это она, я ее занопил, не работает, выключил, стало быть то, что мне надо?

Выглядит оно примерно так

[URL=http://hostingkartinok.com/show-image.php?id=3f7b02d0b762f8818c990828658537b8][IMG]http://s8.hostingkartinok.com/uploads/images/2016/10/3f7b02d0b762f8818c990828658537b8.png[/IMG][/URL]
[URL=http://hostingkartinok.com/show-image.php?id=bff9fcc3f55e97b3afba0f4be5064aad][IMG]http://s8.hostingkartinok.com/uploads/images/2016/10/bff9fcc3f55e97b3afba0f4be5064aad.png[/IMG][/URL]

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

На данном форуме была тема, что можно вызвать функцию в Ассемблерной вставке CE, автор написал кож так

Скрытый текст

[ENABLE]

alloc(newmem,1024)
createthread(newmem)

newmem:
mov eax, 199CD788
call game_x86_rwdi.dll+4CB1E0
ret


[DISABLE]
dealloc(newmem)

 

Хорошо, как мне сделать аналогичное? Моя функция не принимает никаких аргументов, по крайней мере не указывал никаких, следовательно mov мне не нужен?)

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

Было бы очень интересно узнать. как мне вызвать мою функцию хотя бы из CE для начала)

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

7 часов назад, Dejavu сказал:

От простого call крашится? 

Да, просто крашится от call

Думаю, это не та функция, которую надо было вызвать, однако, когда я ее занопил, число не отнималось

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

Перед вызовом call нужно в стек поместить все парамеры, которые ей нужны, а ты этого не делаешь, так как не знаешь, какие именно параметры ей передавать. Отсюда и краш.

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

5 минут назад, Xipho сказал:

Перед вызовом call нужно в стек поместить все парамеры, которые ей нужны, а ты этого не делаешь, так как не знаешь, какие именно параметры ей передавать. Отсюда и краш.

Хорошо, думаю, так оно и есть... правда функцию записывал без требований аргументов просто void func1()

я прикладывал картинки к теме, посмотрел, их, кажется, удалили. однако прикреплю их второй раз, можете ли вы что-то подсказать по ним?
Можно ли здесь увидеть нужные для вызова функции параметры?

3f7b02d0b762f8818c990828658537b8.png

 

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

14 minutes ago, Trix said:

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

Аргументы пихаются в стек при помощи команды PUSH, так что в твоей функции как минимум один параметр. Можно так же посмотреть изнутри самой функции, поставив брейкпоинт на самое ее начало. В этом случае на стеке будут лежать все аргументы + адрес возврата, так как функции нужно знать, куда потом вернуть управление. Каждый аргумент занимает по 4 байта (или по 8, если ОС 64-разрядная).

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

В 17.10.2016в13:36, keng сказал:

Аргументы пихаются в стек при помощи команды PUSH, так что в твоей функции как минимум один параметр. Можно так же посмотреть изнутри самой функции, поставив брейкпоинт на самое ее начало. В этом случае на стеке будут лежать все аргументы + адрес возврата, так как функции нужно знать, куда потом вернуть управление. Каждый аргумент занимает по 4 байта (или по 8, если ОС 64-разрядная).

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

Скрытый текст

[ENABLE]

alloc(newmem,1024)
createthread(newmem)

newmem:
push Аргумент
call Адрес функции
ret


[DISABLE]
dealloc(newmem)

 

Так будет выглядеть сам код или я что-то не понимаю?

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

судя по скринам там нету функции изза оптимиза..
закачай fasm, собери это:

Скрытый текст

format pe nx console 6.0 on 'nul'
entry Main
include	'..\fasm\include\win32wx.inc'
include '..\fasm\include\encoding\utf8.inc'

section '.code' code readable executable
proc Main
stdcall test1,100500
invoke Sleep,1000000
invoke ExitProcess,eax
ret
endp

proc test1 Num
cinvoke wprintf,Decimal,[Num]
ret
endp

section '.data' data readable writable
Decimal du '%d',10,0

data import
library kernel32,'kernel32.dll',msvcrt,'msvcrt.dll'
import kernel32,\
Sleep,'Sleep',\
ExitProcess,'ExitProcess'
import msvcrt,\
wprintf,'wprintf'
end data

 

как видишь функция test1 принимает 1 параметр.

запусти, попробуй вызвать ее через СЕ. при удачном вызове увидишь свое число в консоле..

ps когда юзаешь createthread, нужно еще CloseHandle сделать, например перед dealloc(newmem)

 

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

18 час назад, Trix сказал:

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

 

11 час назад, Dejavu сказал:

От простого call крашится? 

 

1 час назад, gmz сказал:

ps когда юзаешь createthread, нужно еще CloseHandle сделать, например перед dealloc(newmem)

Некоторые ответы, а также вопросы в видео:

 

 

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

50 минут назад, keng сказал:

Кто писал? Где?

*Скорее всего не относится к теме*

Писал Сергей Терехов, вроде школа программистов, просто там были более менее свежие уроки Ассемблера.

Даже пришлось качать win32 на виртуальную машину, может быть я что-то не догоняю но fasm у меня на 64 просто отказывался работать)

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

17 минуту назад, Dino сказал:

Из всего прочитанного возникает 1 вопрос : как ты ищешь адрес своей функции в CE? :mellow:

 

Моя программа CrackMe выполняет команду, как во втором уроке туториала CE(отбивает одну единицу от числа, под которым подразумевается ХП)
я ищу через поиск сначала самого числа, потом смотрю "Что читает данный адрес" там нахожу адрес функции))

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

2 hours ago, Trix said:

*Скорее всего не относится к теме*

Писал Сергей Терехов, вроде школа программистов, просто там были более менее свежие уроки Ассемблера.

Даже пришлось качать win32 на виртуальную машину, может быть я что-то не догоняю но fasm у меня на 64 просто отказывался работать)

Очень советую читать официальную документацию в таких случаях. Fasm - не то, что многоразрядный (32/64), он еще и кросс-платформенный. И все прекрасно работает.

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

35 минуты назад, Trix сказал:

Моя программа CrackMe выполняет команду, как во втором уроке туториала CE(отбивает одну единицу от числа, под которым подразумевается ХП)
я ищу через поиск сначала самого числа, потом смотрю "Что читает данный адрес" там нахожу адрес функции))

покажи асм код функции (скрин)

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

6 минут назад, Dino сказал:

но даже по этим огрызкам я вижу что метод принадлежит классу, следовательно он __thiscall

Опыта мало, данную тему не понимаю, хоть и несколько раз к ней подходил с разных ракурсов

Быть может, это оно?

f941b639dc77e21e647d6228fd384fa9.png

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

3 минуты назад, Trix сказал:

Опыта мало, данную тему не понимаю, хоть и несколько раз к ней подходил с разных ракурсов

Быть может, это оно?

f941b639dc77e21e647d6228fd384fa9.png

Смотри, начало функции это там где начинается код пролога, он выглядит примерно так 

push ebp

mov ebp,esp

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

Поток можно создать следующим способом:

Для 32 битный систем

Скрытый текст

[Enable]
alloc(PLACEpotok,1000) // Место для скрипта
createthread(PLACEpotok) // Поток на место для скрипта

alloc(Potoc_Control,8) // Адрес для контроля дейсвтиями скрипта
registersymbol(Potoc_Control)

alloc(Timer,8) // Таймер
registersymbol(Timer)

alloc(Value,8) // Значение которое будет или уменьшаться или увеличиваться
registersymbol(Value)

label(Potoc_Increase) // Метка где значение Value булет увеличиваться
label(Potoc_Decrease) // Метка где значение Value булет уменьшаться
label(Potoc_End) // Метка где поток полностью выключится

PLACEpotok:
push [Timer]
call sleep

cmp [Potoc_Control],#0 // Пауза потока
je PLACEpotok
cmp [Potoc_Control],#1
je Potoc_Increase
cmp [Potoc_Control],#2
je Potoc_Decrease
cmp [Potoc_Control],#3
je Potoc_End
jmp PLACEpotok


Potoc_Increase:
push eax
mov eax,[Value]
inc eax
mov [Value],eax
pop eax
jmp PLACEpotok

Potoc_Decrease:
push eax
mov eax,[Value]
dec eax
mov [Value],eax
pop eax
jmp PLACEpotok



Potoc_End:
call RtlExitUserThread

Timer: // Значение таймера можно изменять, - либо добавив в таблицу, либо напрямую в памяти
dd #1000  // Изначально 1 секунда

[Disable]
Potoc_Control: // Вообще я почти никогда не отключаю скрипты, так как быстрее поменять флаг, чем вновь аобсканить
dd #3
dealloc(PLACEpotok)

 

 

Для 64 битный систем

Скрытый текст

[Enable]
alloc(PLACEpotok,1000) // Место для скрипта
createthread(PLACEpotok) // Поток на место для скрипта

alloc(Potoc_Control,8) // Адрес для контроля дейсвтиями скрипта
registersymbol(Potoc_Control)

alloc(Timer,8) // Таймер
registersymbol(Timer)

alloc(Value,8) // Значение которое будет или уменьшаться или увеличиваться
registersymbol(Value)

label(Potoc_Increase) // Метка где значение Value булет увеличиваться
label(Potoc_Decrease) // Метка где значение Value булет уменьшаться
label(Potoc_End) // Метка где поток полностью выключится

PLACEpotok:
push rcx
mov rcx,[Timer]
call Sleep
pop rcx

cmp [Potoc_Control],#0 // Пауза потока
je PLACEpotok
cmp [Potoc_Control],#1
je Potoc_Increase
cmp [Potoc_Control],#2
je Potoc_Decrease
cmp [Potoc_Control],#3
je Potoc_End
jmp PLACEpotok


Potoc_Increase:
push eax
mov eax,[Value]
inc eax
mov [Value],eax
pop eax
jmp PLACEpotok

Potoc_Decrease:
push eax
mov eax,[Value]
dec eax
mov [Value],eax
pop eax
jmp PLACEpotok



Potoc_End:
call RtlExitUserThread

Timer: // Значение таймера можно изменять, - либо добавив в таблицу, либо напрямую в памяти
dd #1000  // Изначально 1 секунда

[Disable]
Potoc_Control: // Вообще я почти никогда не отключаю скрипты, так как быстрее поменять флаг, чем вновь аобсканить
dd #3
dealloc(PLACEpotok)

 

 

Останется разобраться с Call Ret.

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

16 минуту назад, Dino сказал:

Чем это создание потока отличается от того что упоминалось выше?

 

И куда ему поток вешать, если он даже начало функции не может найти

 

Создание потока ничем не отличается. Что там, что здесь, - везде одинаково и верно прописано CreateThread.

Но тот вариант, в отличии от этого, имеет в себе некоторые недоработки.

А именно:

 

Отключится сразу после активации.

Будет работать с максимальной частотой, на какую способен процессор (за  ~ две секунды наберет максимально допустимое число для 4_ёх байтного адреса, прибавляя всего единицу).

Не имеет паузы.

Не имеет контроля частотой

Не имеет разных условий

Прочая мелочь.

32/64 битные варианты.

 

По поводу начала функции, - найти её очень просто, достаточно кликнуть в диссасемблере правой кнопкой мыши по нужной инструкции и из выпавшего контекста выбрать - Select current function.

 

Перед вызовом, аргументы стоит помещать в стек в обратном порядке.

 

 

 

 

 

 

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

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

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

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