diff --git a/Include/CTRL/Arch.h b/Include/CTRL/Arch.h new file mode 100644 index 0000000..ff3d213 --- /dev/null +++ b/Include/CTRL/Arch.h @@ -0,0 +1,39 @@ +/** + * @file Arch.h + * @brief Arch utilities. + */ +#ifndef _CTRL_ARCH_H +#define _CTRL_ARCH_H + +#include "CTRL/Types.h" + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + +/** + * @brief Check if an address references thumb code. + * @param[in] addr Address. + * @result True if the address references thumb code, false otherwise. + */ +CTRL_INLINE bool ctrlIsThumb(u32 addr) { return addr & 1; } + +/** + * @brief Set thumb mode bit in address. + * @param[in] addr Address. + * @result Address with thumb mode bit set. + */ +CTRL_INLINE u32 ctrlSetThumb(u32 addr) { return addr | 1; } + +/** + * @brief Clear thumb mode bit in address. + * @param[in] addr Address. + * @result Address with thumb mode bit clear. + */ +CTRL_INLINE u32 ctrlClearThumb(u32 addr) { return addr & ~(1u); } + +#if defined(__cplusplus) +} +#endif // __cplusplus + +#endif /* _CTRL_ARCH_H */ \ No newline at end of file diff --git a/Source/Hook.c b/Source/Hook.c index d75acaa..c857ff3 100644 --- a/Source/Hook.c +++ b/Source/Hook.c @@ -1,23 +1,22 @@ #include "CTRL/Hook.h" #include "CTRL/Patch.h" #include "CTRL/Memory.h" +#include "CTRL/Arch.h" #include -#define IS_THUMB(addr) ((addr) & 1) -#define GET_REAL_ADDR(addr) ((addr) & ~(1u)) - const u8 ARM_OP[4] = { 0x04, 0xF0, 0x1F, 0xE5 }; // LDR PC, [PC, #-4] const u8 THUMB_OP[4] = { 0x00, 0x4F, 0x38, 0x47 }; // LDR R7, [PC, #0]; BX R7 Result ctrlPlaceHook(CTRLHook* hook) { u8 buffer[CTRL_HOOK_SIZE]; - memcpy(buffer, IS_THUMB(hook->addr) ? THUMB_OP : ARM_OP, 4); + const u32 realAddr = ctrlClearThumb(hook->addr); + memcpy(buffer, ctrlIsThumb(hook->addr) ? THUMB_OP : ARM_OP, 4); memcpy(&buffer[4], &hook->callback, sizeof(u32)); - memcpy(hook->ogBytes, (void*)GET_REAL_ADDR(hook->addr), CTRL_HOOK_SIZE); - return ctrlPatchMemory(GET_REAL_ADDR(hook->addr), buffer, CTRL_HOOK_SIZE); + memcpy(hook->ogBytes, (void*)realAddr, CTRL_HOOK_SIZE); + return ctrlPatchMemory(realAddr, buffer, CTRL_HOOK_SIZE); } Result ctrlRemoveHook(CTRLHook* hook) { - return ctrlPatchMemory(GET_REAL_ADDR(hook->addr), hook->ogBytes, CTRL_HOOK_SIZE); + return ctrlPatchMemory(ctrlClearThumb(hook->addr), hook->ogBytes, CTRL_HOOK_SIZE); } \ No newline at end of file diff --git a/Tests/Main.c b/Tests/Main.c index 9dd8912..f0e479f 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -3,6 +3,7 @@ #include "CTRL/Exception.h" #include "CTRL/App.h" #include "CTRL/CodeGen.h" +#include "CTRL/Arch.h" #include #include @@ -141,7 +142,7 @@ static bool codegenTest(void) { // Now we're ready to call the functions. typedef int(*Fn_t)(int, int); - Fn_t f = (Fn_t)(addCodeAddr | 1); // Set bit 0 for thumb code. + Fn_t f = (Fn_t)(ctrlSetThumb(addCodeAddr)); printf("Doing addition\n"); int val = f(FUNC_PARAM_1, FUNC_PARAM_2);