Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

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

ну а вообще и memchr мог бы заюзать

ага, читай прошлый коммент. https://yougame.biz/threads/315882/post-3068349

шарпер, дак сделал бы тему свою в разделе по шарпу. чего ты тут с плюсами забыл чтобы о своих правилах выписывать?
Покидай ещё стрелок пж, ведь про правила, сперва задал вопрос я тебе. Я даже не упоминал на каком языке я пишу ранее, а ты даже до этого доебался)
шарпер, дак сделал бы тему свою в разделе по шарпу. чего ты тут с плюсами забыл чтобы о своих правилах выписывать?

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

Это схуяли я должен создавать тему как шарп, если я не на шарпе пишу этот проект? Хули ты раскомандовался?
шарпер, дак сделал бы тему свою в разделе по шарпу.

Да даже если бы я этот проект хуярил на шарпе, то к твоёму сожалению там тоже доступна работа с указателями. Шах и мат
 
Последнее редактирование:
Да даже если бы я этот проект хуярил на шарпе, то к твоёму сожалению там тоже доступна работа с указателями. Шах и мат
а кто сказал что она не доступна на шарпе?
 
а кто сказал что она не доступна на шарпе?
Бро, извини меня, я себя как неадекват повел. Просто когда ты целый день сидишь за кодом, и в итоге твой код стайл засирает рандомный чел, то от этого оч подгарает
 
Бро, извини меня, я себя как неадекват повел. Просто когда ты целый день сидишь за кодом, и в итоге твой код стайл засирает рандомный чел, то от этого оч подгарает
рандомный тип это ты. и да шарп это дерьмо!
 
че правда? Ты буквально сделал то что я написал блять, там не обязательно было указывать ссылку на функцию, тут ты и обосрался, потому что делал бы сам - не поставил бы. Тем более если бы сам думал ты бы не оставил вторую функцию пустой, потому что это важно, короче пиздабол.
мы вертимся вокруг тебя, поверь мне. крутимся и кружимся...
 
Я лишь скажу пару моментов при получении длины функции при дизассемблировании(это относится больше при компиляции 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 парсер, ибо с ним меньше геморроя(моё мнение и не вижу смысл создавать велосипед, но не всем понравится).
Теперь моё не совсем удачное решение(снизу опишу почему) и примеры:

Example:
Expand Collapse Copy
    auto ntdll_base = GetModuleHandleW(L"ntdll.dll");
    auto kernel32_base = GetModuleHandleW(L"kernelbase.dll");
    CHAR* addr_user_except = (CHAR*)GetProcAddress(ntdll_base, "KiUserExceptionDispatcher");
    CHAR* addr_add_table = (CHAR*)GetProcAddress(ntdll_base, "RtlAddFunctionTable");
    CHAR* addr_open_proc = (CHAR*)GetProcAddress(kernel32_base, "OpenProcess");
   
    printf("KiUserExceptionDispatcher size ->\t%p\n", get_len_fun(addr_user_except));
    printf("RtlAddFunctionTable size ->\t%p\n", get_len_fun(addr_add_table));
    printf("OpenProcess size ->\t%p\n", get_len_fun(addr_open_proc));
и сам код:
очень плохой код,но лучше предлагайте идеи,а не чешите своим языком:
Expand Collapse Copy
    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:
Screenshot_672.png
RtlAddFunctionTable:
Screenshot_670.png

OpenProcess:
Screenshot_671.png


Проблемы:
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: )
 
4)лучше по возможностей использовать pdb парсер, ибо с ним меньше геморроя(моё мнение и не вижу смысл создавать велосипед, но не всем понравится).

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