usb: getting string descriptors, minor improvements
[quarnos.git] / manes / ods / injector.c
blob715d27d6b232430d4e423b443c25ce235c0e8ff9
1 /* Quarn OS / Manes
3 * Execution Flow Controller
4 * Function Injector for GCC 4.x
6 * Copyright (C) 2008-2009 Pawel Dziepak
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "arch/low/fast_util.h"
25 #include "injector.h"
27 unsigned int syscalls_count = 0;
28 unsigned int functioncalls_count = 0;
30 /* Functions */
31 void *new_ventry(int impl);
32 void inject_caller(void *object);
33 int call_function(int (*method)(void*,struct __fill_size), int *stack);
34 void *get_vptr(void *instance);
36 /* Syscalls */
37 int do_syscall(int (*method)(void*,struct __fill_size), int *stack) {
38 syscalls_count++;
39 functioncalls_count--;
40 int *stub = (int*)stack[1];
41 stack[1] = stub[1];
42 return call_function(method, stack);
45 int call_system(int (*method)(void*,struct __fill_size), int *stack) {
46 int ret;
47 __asm__("int $0x33" : "=a" (ret) : "a" (method), "d" (stack));
48 return ret;
51 /* Symbols from vcall.S */
52 extern char vcall;
53 extern char vmth;
54 extern char end_vcall;
56 extern char rcall;
57 extern char rmth;
58 extern char end_rcall;
60 /* TODO: dynamic structure instead of static */
61 #define comp_vtable_size 0x4000
62 char *comp_vtable = (char*)0x1b0000; //[comp_vtable_size];
63 int comp_vtable_ptr = 0;
65 extern unsigned int get_symbol_size(unsigned int);
67 /* Replace old vtable entry with hacked one */
68 void *new_ventry(int impl) {
69 int entry_size = (int)&end_vcall - (int)&vcall;
71 /* Put hacked vtable entry function in comp_vtable */
72 memcpy(&comp_vtable[comp_vtable_ptr], &vcall, (int)&end_vcall - (int)&vcall);
74 /* Set correct method address (vcall.S) */
75 *(unsigned int*)((int)comp_vtable + comp_vtable_ptr + (int)&vmth - (int)&vcall + 1) = (unsigned int)impl;
77 /* Get address of injected code */
78 void *ventry = &comp_vtable[comp_vtable_ptr];
79 comp_vtable_ptr += entry_size;
81 if (comp_vtable_ptr >= comp_vtable_size)
82 __asm__ ("cli\nhlt"::"a"(0xfeedbeef),"b"(entry_size));
84 /* Return value to put in vtable */
85 return ventry;
88 /* Replace old vtable entry with hacked one */
89 void *new_remote_ventry(int impl) {
90 /* Put hacked vtable entry function in comp_vtable */
91 memcpy(&comp_vtable[comp_vtable_ptr], &rcall, (int)&end_rcall - (int)&rcall);
93 /* Set correct method address (vcall.S) */
94 *(unsigned int*)((int)comp_vtable + comp_vtable_ptr + (int)&rmth - (int)&rcall + 1) = (unsigned int)impl;
96 /* Get address of injected code */
97 void *ventry = &comp_vtable[comp_vtable_ptr];
98 comp_vtable_ptr += (int)&end_rcall - (int)&rcall;
100 if (comp_vtable_ptr >= comp_vtable_size)
101 __asm__ ("cli\nhlt"::"a"(0xfeedbeef));
103 /* Return value to put in vtable */
104 return ventry;
107 /* Inject EFC */
108 void inject_efc(void *object) {
109 int *vtable = (int*)get_vptr(object);
110 int size = get_symbol_size((unsigned int)vtable - 8) / sizeof(void*) - 2;
112 /* Replace all entries in Vtable */
113 for (int i = 0; i < size; i++)
114 if (vtable[i] < 0x1b0000 || vtable > 0x2fffff)
115 vtable[i] = (int)new_ventry(vtable[i]);
118 void inject_remote_efc(void *object, int size) {
119 int *vtable = object;
120 size = size / sizeof(void*) - 2;
122 /* Replace all entries in Vtable */
123 for (int i = 0; i < size; i++)
124 if (vtable[i] < 0x1b0000 || vtable > 0x2fffff)
125 vtable[i] = (int)new_remote_ventry(vtable[i]);
129 #if DEBUG_MODE == CONF_YES
130 unsigned int last_call0 = 0;
131 unsigned int last_call1 = 0;
132 #endif
134 /* Get Vtable of an object */
135 void *get_vptr(void *instance) {
136 return *(void**)instance;
139 /* Vtable was hacked incorrectly */
140 void efc_incomplete() {
141 while(1);