C++ Считывание начала и конца функции в памяти. C++

Начинающий
Статус
Оффлайн
Регистрация
29 Июл 2022
Сообщения
101
Реакции[?]
28
Поинты[?]
29K
Привет. Появилась проблемка, и только югеймеры смогут с ней справится. Есть адрес моей функции, который я получаю через "&". Помогите мне найти конец функции пожалуйста, чтобы я все байты инструкций мог всунуть в массив byte[] в виде int чисел?


Условно: У меня есть адрес 7FF71FAB9A80. Это начало моей функции. Как мне дойти до конца этой функции и все полученные байты скопировать массив? Это если говорить коротко.
 
Эксперт
Статус
Оффлайн
Регистрация
29 Мар 2021
Сообщения
1,605
Реакции[?]
607
Поинты[?]
48K
да никак нахуй

можешь бежать по схеме

int size = 0;
while (*p != INSTRUCTION_RET) {
++p;
++size;
}

и в тупую искать инструкцию ret
 
На самом деле я Zodiak
Участник
Статус
Оффлайн
Регистрация
22 Дек 2020
Сообщения
1,052
Реакции[?]
183
Поинты[?]
72K
берешь после этой функции ставишь еще одну, с произвольным уникальным кодом, и &вторая - &первая
 
Начинающий
Статус
Оффлайн
Регистрация
29 Июл 2022
Сообщения
101
Реакции[?]
28
Поинты[?]
29K
да никак нахуй

можешь бежать по схеме

int size = 0;
while (*p != INSTRUCTION_RET) {
++p;
++size;
}

и в тупую искать инструкцию ret
В конце каждой функции 100% стоит ret? Просто я по памяти не очень сильно шарю и за плюсы тоже.
 
Эксперт
Статус
Оффлайн
Регистрация
29 Мар 2021
Сообщения
1,605
Реакции[?]
607
Поинты[?]
48K
В конце каждой функции 100% стоит ret? Просто я по памяти не очень сильно шарю и за плюсы тоже.
нет, не стоит, но это самый простой способ.

позволь спросить - тебе это нахуя надо?
 
Начинающий
Статус
Оффлайн
Регистрация
23 Фев 2021
Сообщения
7
Реакции[?]
0
Поинты[?]
0
Используй либо дизассемблер, проходясь по телу функции (нужно учитывать, что функции могут кончаться и на jmp и на ret), либо конструкцию подобного рода.
C++:
static void function_begin()
{
    // code
}
static void function_end() { };
auto function_size = reinterpret_cast<PBYTE>(&function_end) - reinterpret_cast<PBYTE>(&function_begin);
 
На самом деле я Zodiak
Участник
Статус
Оффлайн
Регистрация
22 Дек 2020
Сообщения
1,052
Реакции[?]
183
Поинты[?]
72K
Используй либо дизассемблер, проходясь по телу функции (нужно учитывать, что функции могут кончаться и на jmp и на ret), либо конструкцию подобного рода.
C++:
static void function_begin()
{
    // code
}
static void function_end() { };
auto function_size = reinterpret_cast<PBYTE>(&function_end) - reinterpret_cast<PBYTE>(&function_begin);
спасибо что передал мою идею кодом
 
На самом деле я Zodiak
Участник
Статус
Оффлайн
Регистрация
22 Дек 2020
Сообщения
1,052
Реакции[?]
183
Поинты[?]
72K
Не заметил твоего сообщения, но все-же пользователю будет проще.
че правда? Ты буквально сделал то что я написал блять, там не обязательно было указывать ссылку на функцию, тут ты и обосрался, потому что делал бы сам - не поставил бы. Тем более если бы сам думал ты бы не оставил вторую функцию пустой, потому что это важно, короче пиздабол.
 
Пользователь
Статус
Оффлайн
Регистрация
8 Апр 2022
Сообщения
674
Реакции[?]
106
Поинты[?]
69K
берешь после этой функции ставишь еще одну, с произвольным уникальным кодом, и &вторая - &первая
А что если они скомпилируются в разных местах? Надо наверное ещё оптимизацию отключить
 
Начинающий
Статус
Оффлайн
Регистрация
23 Фев 2021
Сообщения
7
Реакции[?]
0
Поинты[?]
0
че правда? Ты буквально сделал то что я написал блять, там не обязательно было указывать ссылку на функцию, тут ты и обосрался, потому что делал бы сам - не поставил бы. Тем более если бы сам думал ты бы не оставил вторую функцию пустой, потому что это важно, короче пиздабол.
Уверен?) Про какую ссылку ты говоришь? Может ты про взятие указателя? Спешу тебя расстроить, в нормальных компиляторах (!=MSVC) взятие адреса на функцию происходит только через &. Вторую функцию можно спокойно оставлять пустой и это прекрасно работает на различных компиляторах.
А что если они скомпилируются в разных местах? Надо наверное ещё оптимизацию отключить
Они будут друг за другом в любом случае, оптимизации отключать не стоит.
 
На самом деле я Zodiak
Участник
Статус
Оффлайн
Регистрация
22 Дек 2020
Сообщения
1,052
Реакции[?]
183
Поинты[?]
72K
А что если они скомпилируются в разных местах? Надо наверное ещё оптимизацию отключить
я ни слова не сказал о том что определенные параметры не требуются)
 
Начинающий
Статус
Онлайн
Регистрация
2 Фев 2022
Сообщения
69
Реакции[?]
14
Поинты[?]
19K
Пожалуйста, авторизуйтесь для просмотра ссылки.


C++:
const size_t get_instruction_size(uintptr_t addr)
{
    hde64_t instr = { 0 };
    size_t size = 0;

    for (;; addr += instr.len)
    {
        disasm64(reinterpret_cast<void*>(addr), &instr);

        size += instr.len;

        if (instr.flags & F_ERROR || size >= 5)
            break;
    }

    return size;
}
 
Femboy Access
Эксперт
Статус
Оффлайн
Регистрация
11 Ноя 2020
Сообщения
1,335
Реакции[?]
428
Поинты[?]
96K
Тем более если бы сам думал ты бы не оставил вторую функцию пустой, потому что это важно
линкер не стрипнет функу если она где-то используется, а если даже и стрипнет (хотя такого быть не может т.к. компилер и линкер не должны ломать код) можно просто заюзать volatile

по теме: а вообще, мне кажется это XY вопрос, скажи для чего тебе надо сохранять функу в байты?
 
Начинающий
Статус
Оффлайн
Регистрация
22 Дек 2023
Сообщения
264
Реакции[?]
16
Поинты[?]
17K
да никак нахуй

можешь бежать по схеме

int size = 0;
while (*p != INSTRUCTION_RET) {
++p;
++size;
}

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

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


C++:
const size_t get_instruction_size(uintptr_t addr)
{
    hde64_t instr = { 0 };
    size_t size = 0;

    for (;; addr += instr.len)
    {
        disasm64(reinterpret_cast<void*>(addr), &instr);

        size += instr.len;

        if (instr.flags & F_ERROR || size >= 5)
            break;
    }

    return size;
}
вам надо еще учитывать условные переходы jnz/jmp/je и тд. также как и не обязательно что ret будет в самом конце из-за тех же переходов.

Используй либо дизассемблер, проходясь по телу функции (нужно учитывать, что функции могут кончаться и на jmp и на ret), либо конструкцию подобного рода.
C++:
static void function_begin()
{
    // code
}
static void function_end() { };
auto function_size = reinterpret_cast<PBYTE>(&function_end) - reinterpret_cast<PBYTE>(&function_begin);
компилятор может твой бегин воткнуть после твоей end функции так что вариант может пройти, но не на 100%.

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

вот вам одно из действительно верных ответов по данной теме:
вы можете читать дебаг заголовки в них вы можете найти начало и конец практически любой функции.
 
Последнее редактирование:
Femboy Access
Эксперт
Статус
Оффлайн
Регистрация
11 Ноя 2020
Сообщения
1,335
Реакции[?]
428
Поинты[?]
96K
Сверху Снизу