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"
27 unsigned int syscalls_count
= 0;
28 unsigned int functioncalls_count
= 0;
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
);
37 int do_syscall(int (*method
)(void*,struct __fill_size
), int *stack
) {
39 functioncalls_count
--;
40 int *stub
= (int*)stack
[1];
42 return call_function(method
, stack
);
45 int call_system(int (*method
)(void*,struct __fill_size
), int *stack
) {
47 __asm__("int $0x33" : "=a" (ret
) : "a" (method
), "d" (stack
));
51 /* Symbols from vcall.S */
54 extern char end_vcall
;
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 */
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 */
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;
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() {