summaryrefslogtreecommitdiff
path: root/other/wrez/tmp/call.c
blob: d81f072f9cef047a8a2753c889a4cb8ac4d2b919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* use ht on the 'call' executeable to set the first PT_LOAD rwx
 * else it will segfault
 */

#include <stdio.h>

int foofunc (void);


#define	FUNCPTR(dst,functionname) \
{ \
	register unsigned int	fptr; \
	\
	__asm__ __volatile__ ( \
		"	call	l0_%=\n" \
		"l0_%=:	movl	$"##functionname", %%eax\n" \
		"	subl	$l0_%=, %%eax\n" \
		"	popl	%%edx\n" \
		"	addl	%%edx, %%eax\n" \
		: "=a" (fptr) : : "edx"); \
	\
	(dst) = (void *) fptr; \
}

#define	PTRINSTALL(hook,chain) \
{ \
	__asm__ __volatile__ ( \
		"	call	l0_%=\n" \
		"lr_%=:	jmp	lo_%=\n" \
		"l0_%=:	pushl	%%edx\n" \
		"	pushl	$0x64466226\n" \
		"	jmpl	*%%eax\n" \
		"lo_%=:\n" \
		: : "a" (hook), "d" (chain)); \
}

#define	PTRCONTROL(chain) \
{ \
	__asm__ __volatile__ ( \
		"	jmp	l0_%=\n" \
		"lp_%=:	.byte	0x0\n" \
		"	.byte	0x0\n" \
		"	.byte	0x0\n" \
		"	.byte	0x0\n" \
		"\n" \
		"l0_%=:	call	l1_%=\n" \
		"l1_%=:	popl	%%edx\n" \
		"	addl	$lp_%=, %%edx\n" \
		"	subl	$l1_%=, %%edx\n" \
		"\n" \
		"	movl	0x4(%%ebp), %%eax\n" \
		"	cmpl	$0x64466226, %%eax\n" \
		"	jne	lo_%=\n" \
		"\n" \
		"	movl	0x8(%%ebp), %%eax\n" \
		"	movl	%%eax, (%%edx)\n" \
		"\n" \
		"	movl	%%ebp, %%esp\n" \
		"	popl	%%ebp\n" \
		"	addl	$0x8, %%esp\n" \
		"	ret\n" \
		"\n" \
		"lo_%=:	movl	(%%edx), %%eax\n" \
		: "=a" (chain) : : "edx"); \
}


int
main (int argc, char *argv[])
{
	void (* addr)(void);

#if 0
	__asm__ __volatile__ ("
		call	l1_%=
	l1_%=:	movl	$foofunc, %%eax
		subl	$l1_%=, %%eax
		popl	%%edx
		addl	%%edx, %%eax
		pusha
		call	*%%eax
		popa"
		: "=a" (addrdiff) : : "edx");
#endif
	FUNCPTR (addr, "foofunc");

	printf ("0x%08lx\n", (unsigned long int) addr);

	PTRINSTALL (addr, 0x42424242);

	foofunc ();
}


int
foofunc (void)
{
	void *	chain;

	PTRCONTROL (chain);

	printf ("0x%08lx\n", chain);
}