Code:#include <stdlib.h>#include <assert.h> #include <stdbool.h> #include <Windows.h> #include "udis86.h" #include "funclen.h" /** \brief jmp +X == +X + sizeof(jump type) + eip */ static size_t get_jump_offset(ud_t* ud, size_t offsetOfInstr); /** \todo add loop & jecx (and possibly more) - though both are probably only used to jump back and currently is_jump is only called to from functions that don't care about that */ static bool is_jump(enum ud_mneomic_code op); static size_t get_jump_offset(ud_t* ud, size_t offsetOfInstr) { const struct ud_operand* op = NULL; for(int i = 0; op = ud_insn_opr(ud, i); i++) { if(op->type == UD_OP_JIMM) { return op->lval.sdword + offsetOfInstr + ud_insn_len(ud); } // all other types are weird jumps, like jumps to a register or to [] } return 0; } static bool is_jump(enum ud_mneomic_code op) { return op >= UD_Ijo && op <= UD_Ijmp; } static bool is_end_of_function(enum ud_mneomic_code opc, ud_t* ud, size_t furthestJump, size_t instrOffset) { if(opc == UD_Iret && furthestJump <= instrOffset) return true; else if(opc == UD_Ijmp) { const struct ud_operand* op = ud_insn_opr(ud, 0); if(op->type == UD_OP_MEM || op->type == UD_OP_REG) return true; } // todo: 0xCC ? return false; } size_t estimate_function_length(void* function) { size_t furthestJump = 0; //! Functions can have multiple return points. The library assumes that if a RET is hit and a jmp/jcc went over it, this RET isn't the last unsigned char* p = function; size_t funcLen = 0; ud_t ud; ud_init(&ud); ud_set_input_buffer(&ud, function, (size_t)function | (PAGE_BOUNDARY - 1)); // Can't read further than page boundary - there be dragons ud_set_pc(&ud, (uint64_t)function); ud_set_mode(&ud, 64); ud_set_syntax(&ud, UD_SYN_INTEL); while(funcLen < MINIMUM_REQUIRED_FUNCTION_LENGTH_LONG_HOOK && !ud_input_end(&ud)) { size_t instrLen = 0, offsetOfInstr = funcLen; if(!(instrLen = ud_disassemble(&ud)) || ud.error) return 0; p += instrLen; funcLen += instrLen; printf("%p %s", ud_insn_off(&ud), ud_insn_asm(&ud)); enum ud_mneomic_code op = ud_insn_mnemonic(&ud); if(is_jump(op)) { size_t off = get_jump_offset(&ud, offsetOfInstr); if(off > furthestJump) furthestJump = off; } if(is_end_of_function(op, &ud, furthestJump, offsetOfInstr)) { printf("end of function\n"); break; } printf("\n"); } return funcLen; }Wie man hoffentlich an den includes merkt braucht es die libudis86.Code:#ifndef FUN_LEN_H #define FUN_LEN_H #define MINIMUM_REQUIRED_FUNCTION_LENGTH_LONG_HOOK 16 /** \brief Estimates the function size by checking opcodes until * an instruction that signifies the end of the function or * MINIMUM_REQUIRED_FUNCTION_LENGTH_LONG_HOOK bytes were found If the function has multiple return points estimate_function_length() tries to find the farthest by keeping track of jumps forward \return 0 on error */ static size_t estimate_function_length(void* function); #endif