Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
C++Считывание начала и конца функции в памяти. C++
линкер не стрипнет функу если она где-то используется, а если даже и стрипнет (хотя такого быть не может т.к. компилер и линкер не должны ломать код) можно просто заюзать volatile
по теме: а вообще, мне кажется это XY вопрос, скажи для чего тебе надо сохранять функу в байты?
Тебе не кажется, так и есть. Я хотел написать проверку хэша метода в одну игрушку, чтобы при изменении метода новый хэш сравнивался со старым и выводил true или false. В принципе я закончил то, что делал. Спасибо @ maksim dabstep за помощь. Я поменял while на for и получилось что-то вроде этого:
Тебе не кажется, так и есть. Я хотел написать проверку хэша метода в одну игрушку, чтобы при изменении метода новый хэш сравнивался со старым и выводил true или false. В принципе я закончил то, что делал. Спасибо @ maksim dabstep за помощь. Я поменял while на for и получилось что-то вроде этого:
Спасибо что показал истинные стандарты красоты кода которым ты придерживаешься, но я пишу на шарпе и у меня другие правила для себя. Если я так воспринимаю код, то почему это кринж?
Ей богу, меня всегда удивляло то, что когда ты задаешь вопрос на югейме, в ответах получаешь больше выебонов, чем решений. Сообщение выше даже не было адресовано тебе, хули ты на меня выебываешься?
А потом ещё удивляются почему вопросы не полные, а XY. Потому что тут половина на выебонах чисто поугарать с новичков приходят, не забывая, конечно же, о самоутверждении на счет нас, ведь это так круто.
Ей богу, меня всегда удивляло то, что когда ты задаешь вопрос на югейме, в ответах получаешь больше выебонов, чем решений. Сообщение выше даже не было адресовано тебе, хули ты на меня выебываешься?
Бро, извини меня, я себя как неадекват повел. Просто когда ты целый день сидишь за кодом, и в итоге твой код стайл засирает рандомный чел, то от этого оч подгарает
Бро, извини меня, я себя как неадекват повел. Просто когда ты целый день сидишь за кодом, и в итоге твой код стайл засирает рандомный чел, то от этого оч подгарает
че правда? Ты буквально сделал то что я написал блять, там не обязательно было указывать ссылку на функцию, тут ты и обосрался, потому что делал бы сам - не поставил бы. Тем более если бы сам думал ты бы не оставил вторую функцию пустой, потому что это важно, короче пиздабол.
Я лишь скажу пару моментов при получении длины функции при дизассемблировании(это относится больше при компиляции c++ Microsoft Visual Studio):
1)очень трудно определить длину функции, а если вы захотите перенести её в другой участок памяти, то вам нужно исправлять все команды, где есть относительные прыжки(эти примеры, чтобы было понятнее):
call 0xdeadc0de,jmp 0xdeadc0de, lea reg,qword[rip+...],jmp/call qword ptr[rip+offset_value] и другие.
2)можно использовать выравнивание функции, созданное компилятором, например( int3, nop qword [rax], eax(начало новой функции) и другие).
3)если в функции нет jcc и прыжков, то можно дизассемблировать до ret(дизассемблировать тупо до команды ret не совсем хорошая идея т.к компилятор может вставить несколько(очень редко происходит т.к делает обычно jmp)
(правда, нужно придумать определение тогда noreturn функций, но я отвечу: дом горел, а я руки грел).
4)лучше по возможностей использовать pdb парсер, ибо с ним меньше геморроя(моё мнение и не вижу смысл создавать велосипед, но не всем понравится).
Теперь моё не совсем удачное решение(снизу опишу почему) и примеры:
очень плохой код,но лучше предлагайте идеи,а не чешите своим языком:
auto get_len_fun(CHAR* runtime_address) -> uint32_t
{
uint8_t* mem = NULL;
uint8_t* mem_pos = NULL;
uint8_t* mem_max_pos = NULL;
dis_fun dis_fun = { NULL };
ZydisDisassembledInstruction info_instr = { NULL };
mem = (uint8_t*)(runtime_address);
while (ZYAN_SUCCESS(ZydisDisassembleIntel(
dis_mode,
reinterpret_cast<ZyanU64>(mem),
mem,
MAX_LENGHT_INSTR,
&info_instr
)))
{
switch (info_instr.info.mnemonic)
{
case ZYDIS_MNEMONIC_INT3:
{
if ((dis_fun.is_jcc || dis_fun.is_ret) && mem >= mem_max_pos)
{
return dis_fun.lenght_fun;
}
if (!dis_fun.aling_break)
{
dis_fun.aling_break++; // fist change
}
if (dis_fun.aling_break && dis_fun.is_last_bp)
{
dis_fun.aling_break++; //change
}
if (
dis_fun.is_last_bp &&
dis_fun.aling_break >= MAX_ALINGHT_BP &&
mem >= mem_max_pos
)
{
return dis_fun.lenght_fun - dis_fun.aling_break + 1;
}
dis_fun.is_last_bp = TRUE;
dis_fun.is_last_exit = FALSE;
dis_fun.is_jcc = FALSE;
dis_fun.is_ret = FALSE;
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
case ZYDIS_MNEMONIC_NOP:
{
if (
info_instr.info.length >= sizeof(uint16_t) || // 0x66 ... 0x90
info_instr.info.operand_count_visible >= sizeof(uint16_t) //nop qword [rax], eax
)
{
if (dis_fun.is_last_exit && mem >= mem_max_pos)
{
return dis_fun.lenght_fun - dis_fun.aling_break;
}
}
dis_fun.is_last_exit = FALSE;
dis_fun.is_last_bp = FALSE;
dis_fun.is_jcc = FALSE;
dis_fun.is_ret = FALSE;
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
case ZYDIS_MNEMONIC_SUB:
{
if (dis_fun.is_last_bp || dis_fun.is_last_exit)
{
if (info_instr.operands[0].mem.base == ZYDIS_REGISTER_RSP &&
info_instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY
)
{
return dis_fun.lenght_fun - dis_fun.aling_break + 1;
}
}
dis_fun.is_last_exit = FALSE;
dis_fun.is_last_bp = FALSE;
dis_fun.is_jcc = FALSE;
dis_fun.is_ret = FALSE;
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
case ZYDIS_MNEMONIC_RET:
{
dis_fun.is_last_exit = TRUE;
dis_fun.is_last_bp = FALSE;
dis_fun.is_jcc = FALSE;
dis_fun.is_ret = TRUE;
dis_fun.aling_break = NULL;
if (!dis_fun.jcc_count || (dis_fun.jcc_count && mem >= mem_max_pos)) //Functhion don't have jcc
{
return dis_fun.lenght_fun + info_instr.info.length;
}
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
case ZYDIS_MNEMONIC_JMP:
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
{
dis_fun.is_last_exit = FALSE;
dis_fun.is_last_bp = FALSE;
dis_fun.is_jcc = TRUE;
dis_fun.is_ret = FALSE;
if (info_instr.info.mnemonic == ZYDIS_MNEMONIC_JMP)
{
if (dis_fun.lenght_fun == NULL)
{
return info_instr.info.length;
}
dis_fun.is_last_exit = TRUE;
mem_pos = reinterpret_cast<uint8_t*>(get_absolute_address(&info_instr, reinterpret_cast<ZyanU64>(mem)));
if (mem_pos &&
mem >= mem_max_pos &&
mem >= mem_pos)
{
return dis_fun.lenght_fun + info_instr.info.length;
}
}
else
{
//Fix for DLL main
mem_pos = reinterpret_cast<uint8_t*>(get_absolute_address(&info_instr, reinterpret_cast<ZyanU64>(mem)));
if (mem_pos && mem_pos > mem)
{
if (mem_max_pos == NULL)
{
mem_max_pos = mem_pos;
}
else if (mem_pos > mem_max_pos)
{
mem_max_pos = max(mem_max_pos, mem_pos);
}
}
dis_fun.jcc_count++;
}
mem_pos = NULL;
dis_fun.aling_break = NULL;
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
default:
{
if (*mem == NULL)
{
return dis_fun.lenght_fun - dis_fun.aling_break;
}
dis_fun.is_last_bp = FALSE;
dis_fun.is_ret = FALSE;
dis_fun.is_last_exit = FALSE;
dis_fun.is_jcc = FALSE;
dis_fun.aling_break = NULL;
dis_fun.lenght_fun += info_instr.info.length;
mem += info_instr.info.length;
break;
}
}
}
return NULL;
}
KiUserExceptionDispatcher:
RtlAddFunctionTable:
OpenProcess:
Проблемы:
1)сделать определение функции, когда идёт прыжок к импорту аля:
_crt_atexit_0 proc near
jmp cs:__imp__crt_atexit
_crt_atexit_0 endp
у меня тут костыль, когда функция делает jmp(сделайте проверку ,что указатель в другой секции(т.е не текущая секция)
2)не совсем корректно берёт размер функции у Sleep в kernelbase.dll(хотя там прыжок в функцию SleepEx
3)есть другие моменты, но мне лень их вспоминать
P.S отправные моменты я уже сказал,но используйте свою голову.
Буду признателен, если скажите ошибки(помимо кода написанного явно под чем-то :grin: )