diff --git a/CMakeLists.txt b/CMakeLists.txt index 0774430e..2e4df14d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ set_target_properties(keystone PROPERTIES IMPORTED_LOCATION ${KEYSTONE_IMPORT_DI set(LIBMEM_DIR "${PROJECT_SOURCE_DIR}") set(LIBMEM_INC "${LIBMEM_DIR}/include") set(INTERNAL_DIR "${LIBMEM_DIR}/internal") +set(COMMON_DIR "${LIBMEM_DIR}/src/common") if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN) file(GLOB_RECURSE LIBMEM_SRC "${LIBMEM_DIR}/src/win/*.c" "${LIBMEM_DIR}/src/common/*.c" "${INTERNAL_DIR}/winutils/*.c" "${INTERNAL_DIR}/demangler/*.cpp") @@ -94,7 +95,7 @@ if (LIBMEM_BUILD_STATIC) else() add_library(libmem SHARED ${LIBMEM_SRC}) endif() -target_include_directories(libmem PRIVATE "${LIBMEM_DIR}/src" "${INTERNAL_DIR}") +target_include_directories(libmem PRIVATE "${LIBMEM_DIR}/src" "${INTERNAL_DIR}" "${COMMON_DIR}") include_directories(${PROJECT_SOURCE_DIR} ${LIBMEM_INC} diff --git a/include/libmem/libmem.h b/include/libmem/libmem.h index 864dad90..4f41fe4d 100644 --- a/include/libmem/libmem.h +++ b/include/libmem/libmem.h @@ -114,49 +114,6 @@ enum { }; typedef uint32_t lm_prot_t; -typedef struct { - lm_pid_t pid; - lm_pid_t ppid; - lm_size_t bits; - lm_time_t start_time; /* Process start timestamp, in milliseconds since last boot */ - lm_char_t path[LM_PATH_MAX]; - lm_char_t name[LM_PATH_MAX]; -} lm_process_t; - -typedef struct { - lm_tid_t tid; - lm_pid_t owner_pid; -} lm_thread_t; - -typedef struct { - lm_address_t base; - lm_address_t end; - lm_size_t size; - lm_char_t path[LM_PATH_MAX]; - lm_char_t name[LM_PATH_MAX]; -} lm_module_t; - -/* An allocated segment of memory */ -typedef struct { - lm_address_t base; - lm_address_t end; - lm_size_t size; - lm_prot_t prot; -} lm_segment_t; - -typedef struct { - lm_string_t name; - lm_address_t address; -} lm_symbol_t; - -typedef struct { - lm_address_t address; - lm_size_t size; - lm_byte_t bytes[LM_INST_MAX]; - lm_char_t mnemonic[32]; - lm_char_t op_str[160]; -} lm_inst_t; - /* Supported asm/disasm architectures */ /* * NOTE: The architectures listed here are the ones @@ -202,6 +159,50 @@ enum { }; typedef uint32_t lm_arch_t; +typedef struct { + lm_pid_t pid; + lm_pid_t ppid; + lm_arch_t arch; + lm_size_t bits; + lm_time_t start_time; /* Process start timestamp, in milliseconds since last boot */ + lm_char_t path[LM_PATH_MAX]; + lm_char_t name[LM_PATH_MAX]; +} lm_process_t; + +typedef struct { + lm_tid_t tid; + lm_pid_t owner_pid; +} lm_thread_t; + +typedef struct { + lm_address_t base; + lm_address_t end; + lm_size_t size; + lm_char_t path[LM_PATH_MAX]; + lm_char_t name[LM_PATH_MAX]; +} lm_module_t; + +/* An allocated segment of memory */ +typedef struct { + lm_address_t base; + lm_address_t end; + lm_size_t size; + lm_prot_t prot; +} lm_segment_t; + +typedef struct { + lm_string_t name; + lm_address_t address; +} lm_symbol_t; + +typedef struct { + lm_address_t address; + lm_size_t size; + lm_byte_t bytes[LM_INST_MAX]; + lm_char_t mnemonic[32]; + lm_char_t op_str[160]; +} lm_inst_t; + /* Virtual method table (VMT) */ typedef struct lm_vmt_entry_t { lm_address_t orig_func; diff --git a/src/common/arch/arch.h b/src/common/arch/arch.h index bb6b5461..271d0ab3 100644 --- a/src/common/arch/arch.h +++ b/src/common/arch/arch.h @@ -34,4 +34,71 @@ generate_hook_payload(lm_address_t from, lm_address_t to, lm_size_t bits, lm_byt lm_size_t generate_no_ops(lm_byte_t *buf, lm_size_t size); +/* NOTE: This function does heavy assuptions about processes running in a different + * bitsize than the current process. More testing should be done to check if + * it actually holds. */ +static inline lm_arch_t +get_architecture_from_bits(lm_size_t bits) +{ + lm_arch_t arch; + lm_arch_t target_arch; + + arch = get_architecture(); + switch (arch) { + case LM_ARCH_ARMV7: + case LM_ARCH_AARCH64: + if (bits == 64) + target_arch = LM_ARCH_AARCH64; + else + target_arch = LM_ARCH_ARMV7; + break; + case LM_ARCH_ARMV7EB: + if (bits == 64) + target_arch = LM_ARCH_AARCH64; + else + target_arch = LM_ARCH_ARMV7EB; + break; + case LM_ARCH_X86_16: + case LM_ARCH_X86: + case LM_ARCH_X64: + if (bits == 64) + target_arch = LM_ARCH_X64; + else + target_arch = LM_ARCH_X86; + break; + case LM_ARCH_MIPS: + case LM_ARCH_MIPS64: + if (bits == 64) + target_arch = LM_ARCH_MIPS64; + else + target_arch = LM_ARCH_MIPS; + break; + case LM_ARCH_MIPSEL: + case LM_ARCH_MIPSEL64: + if (bits == 64) + target_arch = LM_ARCH_MIPSEL64; + else + target_arch = LM_ARCH_MIPSEL; + break; + case LM_ARCH_PPC32: + case LM_ARCH_PPC64: + if (bits == 64) + target_arch = LM_ARCH_PPC32; + else + target_arch = LM_ARCH_PPC64; + case LM_ARCH_SPARC: + case LM_ARCH_SPARC64: + if (bits == 64) + target_arch = LM_ARCH_SPARC; + else + target_arch = LM_ARCH_SPARC64; + break; + default: + target_arch = arch; + break; + } + + return target_arch; +} + #endif diff --git a/src/linux/process.c b/src/linux/process.c index cf79cf29..145b8bd7 100644 --- a/src/linux/process.c +++ b/src/linux/process.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include "consts.h" @@ -69,6 +70,7 @@ LM_EnumProcesses(lm_bool_t (LM_CALL *callback)(lm_process_t *process, } process.bits = get_elf_bits(process.path); + process.arch = get_architecture_from_bits(process.bits); if (callback(&process, arg) == LM_FALSE) break; @@ -109,6 +111,7 @@ LM_GetProcess(lm_process_t *process_out) } process_out->bits = LM_GetBits(); + process_out->arch = get_architecture_from_bits(process_out->bits); return LM_TRUE; } @@ -137,6 +140,7 @@ LM_GetProcessEx(lm_pid_t pid, } process_out->bits = get_elf_bits(process_out->path); + process_out->arch = get_architecture_from_bits(process_out->bits); return LM_TRUE; } diff --git a/src/win/process.c b/src/win/process.c index 4dd671e0..4bca75d0 100644 --- a/src/win/process.c +++ b/src/win/process.c @@ -63,6 +63,7 @@ enum_processes_callback(PROCESSENTRY32W *entry, void *arg) goto CLOSE_CONTINUE; process.bits = get_process_bits(hproc); + process.arch = get_architecture_from_bits(process.bits); if (!parg->callback(&process, parg->arg)) return FALSE; @@ -155,6 +156,7 @@ LM_GetProcess(lm_process_t *process_out) return LM_FALSE; process_out->bits = LM_GetBits(); /* Assume process bits == size of pointer */ + process_out->arch = get_architecture_from_bits(process_out->bits); return LM_TRUE; } @@ -198,6 +200,7 @@ LM_GetProcessEx(lm_pid_t pid, goto CLEAN_EXIT; process_out->bits = get_process_bits(hproc); + process_out->arch = get_architecture_from_bits(process_out->bits); result = LM_TRUE; CLEAN_EXIT: diff --git a/tests/unit/unit.c b/tests/unit/unit.c index eba21fce..3bbe1720 100644 --- a/tests/unit/unit.c +++ b/tests/unit/unit.c @@ -181,6 +181,18 @@ main() printf("[*] Unit Tests\n"); printf("[*] NOTE: Some operations may require root access (or Administrator)\n"); + /* + lm_byte_t *payload; + lm_size_t size = LM_AssembleEx("bx r0", LM_ARCH_ARMV7, 0xdeadbeef, &payload); + printf("payload (size: %zu): \"", size); + for (size_t i = 0; i < size; ++i) { + printf("\\x%hhx", payload[i]); + } + printf("\"\n"); + + exit(0); + */ + test_asm(); test_process(¤t_process, &target_process); test_thread(¤t_process, &target_process, ¤t_thread, &target_thread);