Skip to content

Commit

Permalink
Refactor x86_gen. It is still wrong.
Browse files Browse the repository at this point in the history
  • Loading branch information
ice799 committed Apr 4, 2010
1 parent 6abf4ca commit 228b884
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 70 deletions.
2 changes: 2 additions & 0 deletions ext/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#error "Unsupported architecture! Cannot continue compilation."
#endif

#include "x86_gen.h"

/*
* arch_get_st2_tramp - architecture specific stage 2 trampoline getter
*
Expand Down
73 changes: 73 additions & 0 deletions ext/x86_gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <assert.h>
#include <stdint.h>
#include "arch.h"
#include "x86_gen.h"

/*
* arch_insert_st1_tramp - architecture specific stage 1 trampoline insert
*
* Given:
* - a start address (start),
* - the absolute address of the function to intercept (trampee),
* - the absolute address of the code to execute instead (tramp),
*
* This function will:
* - interpret address start as a struct st1_base,
* - check that the instruction at call is actually a call
* - if so, check that the target of the call is trampee
* - and change the target to tramp
*
* Returns 0 on success, 1 otherwise.
*/
int
arch_insert_st1_tramp(void *start, void *trampee, void *tramp)
{
assert(start != NULL);
assert(trampee != NULL);
assert(tramp != NULL);

int32_t fn_addr = 0;
struct st1_base *check = start;

if (check->call == 0xe8) {
fn_addr = check->displacement;
if ((trampee - (void *)(check + 1)) == fn_addr) {
WRITE_INSTRUCTIONS(&check->displacement,
sizeof(*check),
(check->displacement = (tramp - (void *)(check + 1))));
return 0;
}
}

return 1;
}

/*
* arch_get_st2_tramp - architecture specific stage 2 tramp accessor. This
* function returns a pointer to the default stage 2 trampoline setting size
* if a non-NULL pointer was passed in.
*/
void *
arch_get_st2_tramp(size_t *size)
{
if (size) {
*size = sizeof(default_st2_tramp);
}

return &default_st2_tramp;
}

/*
* arch_get_inline_st2_tramp - architecture specific inline stage 2 tramp
* accessor. This function returns a pointer to the default inline stage 2
* trampoline setting size if a non-NULL pointer was passed in.
*/
void *
arch_get_inline_st2_tramp(size_t *size)
{
if (size) {
*size = sizeof(default_inline_st2_tramp);
}

return &default_inline_st2_tramp;
}
72 changes: 2 additions & 70 deletions ext/x86_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* For example: callq <0xdeadbeef> #rb_newobj
*/
struct st1_base {
static struct st1_base {
unsigned char call;
int32_t displacement;
} __attribute__((__packed__)) st1_mov = {
Expand Down Expand Up @@ -53,7 +53,7 @@ copy_instructions(void *dest, void *src, size_t count)

mprotect(aligned_addr, (dest - aligned_addr) + count, PROT_READ|PROT_WRITE|PROT_EXEC);
memcpy(dest, src, count);
mprotect(aligned_addr, (dest - aligned_addr) + count, PROT_READ|PROT_EXEC);
// mprotect(aligned_addr, (dest - aligned_addr) + count, PROT_READ|PROT_EXEC);

return;
}
Expand All @@ -70,72 +70,4 @@ copy_instructions(void *dest, void *src, size_t count)
mprotect(aligned_addr, count, PROT_READ | PROT_EXEC); \
} while (0)

/*
* arch_insert_st1_tramp - architecture specific stage 1 trampoline insert
*
* Given:
* - a start address (start),
* - the absolute address of the function to intercept (trampee),
* - the absolute address of the code to execute instead (tramp),
*
* This function will:
* - interpret address start as a struct st1_base,
* - check that the instruction at call is actually a call
* - if so, check that the target of the call is trampee
* - and change the target to tramp
*
* Returns 0 on success, 1 otherwise.
*/
int
arch_insert_st1_tramp(void *start, void *trampee, void *tramp)
{
assert(start != NULL);
assert(trampee != NULL);
assert(tramp != NULL);

int32_t fn_addr = 0;
struct st1_base *check = start;

if (check->call == 0xe8) {
fn_addr = check->displacement;
if ((trampee - (void *)(check + 1)) == fn_addr) {
WRITE_INSTRUCTIONS(&check->displacement,
sizeof(*check),
(check->displacement = (tramp - (void *)(check + 1))));
return 0;
}
}

return 1;
}

/*
* arch_get_st2_tramp - architecture specific stage 2 tramp accessor. This
* function returns a pointer to the default stage 2 trampoline setting size
* if a non-NULL pointer was passed in.
*/
void *
arch_get_st2_tramp(size_t *size)
{
if (size) {
*size = sizeof(default_st2_tramp);
}

return &default_st2_tramp;
}

/*
* arch_get_inline_st2_tramp - architecture specific inline stage 2 tramp
* accessor. This function returns a pointer to the default inline stage 2
* trampoline setting size if a non-NULL pointer was passed in.
*/
void *
arch_get_inline_st2_tramp(size_t *size)
{
if (size) {
*size = sizeof(default_inline_st2_tramp);
}

return &default_inline_st2_tramp;
}
#endif

0 comments on commit 228b884

Please sign in to comment.