diff --git a/include/rtdisasm.h b/include/rtdisasm.h index 8244b2c..4c100b8 100644 --- a/include/rtdisasm.h +++ b/include/rtdisasm.h @@ -2,12 +2,20 @@ #define __RTDISASM_H #include +#include "rtdisasm_table.h" -// code should point to place with machine instructions, and size +// "code" should point to place with machine instructions, and "size" // limits the area of analyze, so no segfaults would be triggered on -// page boundaries. +// page boundaries. if "found" is non-zero, on instruction hit it +// would be set to found instruction table entry // returns 0 when no instruction was found, -1 when size limit reached // and non-negative-non-zero number of actual instruction size -int rtdisasm_analyze_single(const uint8_t* code, uint8_t size); +int rtdisasm_analyze_single(const uint8_t* code, unsigned size, const instruction_t** found); + +// analyze all instructions at "code" until "size" limit is reached or +// instruction of "rt_target" equal was found. returns -1 when size limit hit, +// 0 if rtdisasm encountered unknown instruction +// and non-zero integer is offset from "code" +int rtdisasm_find_target(const uint8_t* code, unsigned size, unsigned rt_target); #endif \ No newline at end of file diff --git a/src/rtdisasm.c b/src/rtdisasm.c index 05f6c49..4ddd792 100644 --- a/src/rtdisasm.c +++ b/src/rtdisasm.c @@ -231,7 +231,7 @@ static void print_opcodes(const instruction_t* ins) #define print_opcodes(ins) #endif -int rtdisasm_analyze_single(const uint8_t* code, uint8_t size) +int rtdisasm_analyze_single(const uint8_t* code, unsigned size, const instruction_t** found) { const uint8_t* cur = code; const uint8_t* const end = code + size; @@ -311,6 +311,35 @@ int rtdisasm_analyze_single(const uint8_t* code, uint8_t size) if (cur >= end) return -1; } + // set found + if (found) *found = ins; // return length of entire decoded instruction return (int)((uintptr_t)cur-(uintptr_t)code); } + +int rtdisasm_find_target(const uint8_t* code, unsigned size, unsigned rt_target) +{ + const uint8_t* cur = code; + const uint8_t* const end = code + size; + unsigned remaining = size; + if (cur == end) return -1; + + do { + const instruction_t* ins; + int len = rtdisasm_analyze_single(cur, remaining, &ins); + // NOTE: this is ret passthru from analyze single, + // so it must be follow same ret logic as this function + if (len < 1) return len; + + if (ins->rt_target == rt_target) + { + // we found target instruction! + return (int)((uintptr_t)cur-(uintptr_t)code); + } + + // otherwise, advance further + cur += len; + remaining -= len; + if (cur >= end) return -1; + } while (1); +} diff --git a/src/rtdisasm_test.c b/src/rtdisasm_test.c index 3f33939..e8d4c92 100644 --- a/src/rtdisasm_test.c +++ b/src/rtdisasm_test.c @@ -7,8 +7,10 @@ extern void test_1_end(); int main() { size_t size = (uintptr_t)test_1_end - (uintptr_t)test_1; - int len = rtdisasm_analyze_single((const uint8_t*)test_1, size); + int len = rtdisasm_analyze_single((const uint8_t*)test_1, size, NULL); + printf("rtdisasm_analyze_single: len %d\n", len); - printf("len %d\n", len); + int offset = rtdisasm_find_target((const uint8_t*)test_1, size, RT_TARGET_NOP); + printf("rtdisasm_find_target: offset %d\n", offset); return 0; } \ No newline at end of file