Skip to content

Commit

Permalink
added external hook functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rdbo committed Apr 6, 2024
1 parent 155e2f3 commit 00bd126
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/common/asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,20 @@ LM_CodeLengthEx(lm_process_t *process,
lm_size_t min_length)
{
lm_size_t length = 0;
lm_inst_t inst;
lm_inst_t *insts;
lm_byte_t codebuf[LM_INST_MAX];

if (!process || machine_code == LM_ADDRESS_BAD)
return 0;

for (; length < min_length; length += inst.size) {
for (; length < min_length; length += insts[0].size, LM_FreeInstructions(insts)) {
if (LM_ReadMemoryEx(process, machine_code, codebuf, sizeof(codebuf)) == 0)
return 0;

if (LM_Disassemble((lm_address_t)codebuf, &inst) == LM_FALSE)
if (LM_DisassembleEx((lm_address_t)codebuf, LM_GetArchitecture(), process->bits, LM_INST_MAX, 1, 0, &insts) == 0)
return 0;

machine_code += inst.size;
machine_code += insts[0].size;
}

return length;
Expand Down
102 changes: 95 additions & 7 deletions src/common/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include <libmem/libmem.h>
#include <libmem/libmem.h>
#include "arch/arch.h"
#include <alloca.h>

LM_API lm_size_t LM_CALL
LM_HookCode(lm_address_t from,
Expand Down Expand Up @@ -81,14 +82,15 @@ LM_HookCode(lm_address_t from,
trampsize = aligned_size;
goto PROT_EXIT;
TRAMP_EXIT:
LM_FreeMemory(tramp, aligned_size);
LM_FreeMemory(tramp, aligned_size + hooksize);
PROT_EXIT:
LM_ProtMemory(from, hooksize, old_prot, LM_NULLPTR);
FREE_EXIT:
LM_FreePayload(payload);

return trampsize; /* NOTE: Even if the trampoline was not generated,
* the function will still return what would've been its size */
* the function will still return what would've
* been its size (without the jump back) */
}

/********************************/
Expand All @@ -99,8 +101,74 @@ LM_HookCodeEx(const lm_process_t *process,
lm_address_t to,
lm_address_t *trampoline_out)
{
printf("LM_HookCodeEx NOT IMPLEMENTED\n");
exit(1);
lm_size_t trampsize = 0;
lm_byte_t *payload;
lm_size_t hooksize = 0;
lm_address_t tramp;
lm_size_t aligned_size;
lm_prot_t old_prot;

if (!process || from == LM_ADDRESS_BAD || to == LM_ADDRESS_BAD)
return trampsize;

hooksize = generate_hook_payload(from, to, process->bits, &payload);
if (hooksize == 0)
return trampsize;

aligned_size = LM_CodeLengthEx(process, from, hooksize);
if (aligned_size == 0)
goto FREE_EXIT;

if (!LM_ProtMemoryEx(process, from, hooksize, LM_PROT_XRW, &old_prot))
goto FREE_EXIT;

if (trampoline_out) {
lm_byte_t *from_buf;

from_buf = (lm_byte_t *)alloca(aligned_size);
if (!LM_ReadMemoryEx(process, from, from_buf, aligned_size))
goto PROT_EXIT;

/*
* NOTE: The trampoline jump back code is the same as the hook code, but
* with a different jump address.
*/
tramp = LM_AllocMemoryEx(process, aligned_size + hooksize, LM_PROT_XRW);
if (tramp == LM_ADDRESS_BAD)
goto PROT_EXIT;

if (LM_WriteMemoryEx(process, tramp, from_buf, aligned_size) == 0)
goto TRAMP_EXIT;

/*
* Write valid instructions at the end of the gateway to prevent 'LM_CodeLengthEx' malfunction.
* This is a hack that allows us to call 'LM_HookCodeEx' on the trampoline instead of re-doing
* the same functionality over here.
*/
if (LM_WriteMemoryEx(process, tramp + aligned_size, payload, hooksize) == 0)
goto TRAMP_EXIT;

if (LM_HookCodeEx(process, tramp + aligned_size, from + aligned_size, LM_NULLPTR) == 0)
goto TRAMP_EXIT;

*trampoline_out = tramp;
}

if (LM_WriteMemoryEx(process, from, payload, hooksize) == 0)
goto TRAMP_EXIT;

trampsize = aligned_size;
goto PROT_EXIT;
TRAMP_EXIT:
LM_FreeMemoryEx(process, tramp, aligned_size + hooksize);
PROT_EXIT:
LM_ProtMemoryEx(process, from, hooksize, old_prot, LM_NULLPTR);
FREE_EXIT:
LM_FreePayload(payload);

return trampsize; /* NOTE: Even if the trampoline was not generated,
* the function will still return what would've
* been its size (without the jump back) */
}

/********************************/
Expand All @@ -121,6 +189,10 @@ LM_UnhookCode(lm_address_t from,
LM_WriteMemory(from, trampoline, size);
LM_ProtMemory(from, size, old_prot, LM_NULLPTR);

/* WARN: This should be fine because 'LM_FreeMemory' works with page sizes,
* but it neglects the size of the jump back after the trampoline's
* original code! */
/* TODO: Fix the issue in the warn above */
LM_FreeMemory(trampoline, size);

return LM_TRUE;
Expand All @@ -134,6 +206,22 @@ LM_UnhookCodeEx(const lm_process_t *process,
lm_address_t trampoline,
lm_size_t size)
{
printf("LM_UnhookCodeEx NOT IMPLEMENTED\n");
exit(1);
lm_prot_t old_prot;

if (!process || from == LM_ADDRESS_BAD || trampoline == LM_ADDRESS_BAD || size == 0)
return LM_FALSE;

if (!LM_ProtMemoryEx(process, from, size, LM_PROT_XRW, &old_prot))
return LM_FALSE;

LM_WriteMemoryEx(process, from, trampoline, size);
LM_ProtMemoryEx(process, from, size, old_prot, LM_NULLPTR);

/* WARN: This should be fine because 'LM_FreeMemory' works with page sizes,
* but it neglects the size of the jump back after the trampoline's
* original code! */
/* TODO: Fix the issue in the warn above */
LM_FreeMemoryEx(process, trampoline, size);

return LM_TRUE;
}

0 comments on commit 00bd126

Please sign in to comment.