summaryrefslogtreecommitdiff
path: root/i386.h
blob: 803e635d93d9f8be8904cb21e8759761cb6ad5d5 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		i386.h
 *
 * Abstract:
 *
 *		This module definies various types and macros used by x86 specific routines.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 24-Mar-2004
 *
 * Revision History:
 *
 *		None.
 */


#ifndef __I386_H__
#define __I386_H__



typedef struct _KTSS {

    USHORT  Backlink;
    USHORT  Reserved0;

    ULONG   Esp0;
    USHORT  Ss0;
    USHORT  Reserved1;

    ULONG   NotUsed1[4];

    ULONG   CR3;

    ULONG   Eip;

    ULONG   NotUsed2[9];

    USHORT  Es;
    USHORT  Reserved2;

    USHORT  Cs;
    USHORT  Reserved3;

    USHORT  Ss;
    USHORT  Reserved4;

    USHORT  Ds;
    USHORT  Reserved5;

    USHORT  Fs;
    USHORT  Reserved6;

    USHORT  Gs;
    USHORT  Reserved7;

    USHORT  LDT;
    USHORT  Reserved8;

    USHORT  Flags;

    USHORT  IoMapBase;

	/* IO/INT MAPS go here */

} KTSS, *PKTSS;


typedef struct _KGDTENTRY {
    USHORT  LimitLow;
    USHORT  BaseLow;
    union {
        struct {
            UCHAR   BaseMid;
            UCHAR   Flags1;     // Declare as bytes to avoid alignment
            UCHAR   Flags2;     // Problems.
            UCHAR   BaseHi;
        } Bytes;
        struct {
            ULONG   BaseMid : 8;
            ULONG   Type : 5;
            ULONG   Dpl : 2;
            ULONG   Pres : 1;
            ULONG   LimitHi : 4;
            ULONG   Sys : 1;
            ULONG   Reserved_0 : 1;
            ULONG   Default_Big : 1;
            ULONG   Granularity : 1;
            ULONG   BaseHi : 8;
        } Bits;
    } HighWord;
} KGDTENTRY, *PKGDTENTRY;


#define	INTERRUPTS_OFF()		_asm { cli }
#define	INTERRUPTS_ON()			_asm { sti }


/*
 * WP Write Protect (bit 16 of CR0).
 * Inhibits supervisor-level procedures from writing into user-level read-only pages when set;
 * allows supervisor-level procedures to write into user-level read-only pages when clear.
 * This flag facilitates implementation of the copyon-write method of creating a new process (forking)
 * used by operating systems such as UNIX.
 */

#define	CR0_WP_BIT	(0x10000)

#define	MEMORY_PROTECTION_OFF()		\
	__asm	mov eax, cr0			\
	__asm	and eax, NOT CR0_WP_BIT	\
	__asm	mov cr0, eax

#define	MEMORY_PROTECTION_ON()		\
	__asm	mov eax, cr0			\
	__asm	or	eax, CR0_WP_BIT		\
	__asm	mov cr0, eax



/* x86 opcodes */

#define	X86_OPCODE_PUSH					0x68
#define	X86_OPCODE_MOV_EAX_VALUE		0xB8

#define	X86_OPCODE_CALL_EAX				0xD0FF
#define	X86_OPCODE_JMP_DWORD_PTR		0x25FF



/*
 * Save a value on stack:
 *
 * push	PushValue
 */

#define	ASM_PUSH(CodeAddress, PushValue)											\
					* (PCHAR) (CodeAddress)++ = X86_OPCODE_PUSH;					\
					* (PULONG) (CodeAddress) = (ULONG) (PushValue);					\
					(PCHAR) (CodeAddress) += 4;

/*
 * Call a function:
 *
 * mov	eax, FunctionAddress
 * call	eax
 */

#define	ASM_CALL(CodeAddress, FunctionAddress)										\
					* (PCHAR) (CodeAddress)++ = X86_OPCODE_MOV_EAX_VALUE;			\
					* (PULONG) (CodeAddress) = (ULONG) (FunctionAddress);			\
					(PCHAR) (CodeAddress) += 4;										\
					* ((PUSHORT) (CodeAddress))++ = X86_OPCODE_CALL_EAX;


/*
 * Jump to a specified address:
 *
 * jmp dword ptr [next_4_bytes]
 * *(next_4_bytes) = address
 *
 * NOTE XXX: this should be converted to a direct jmp address but i
 * can't figure out how that instruction is encoded (opcode 0xE9)
 */

#define	ASM_JMP(CodeAddress, JmpAddress)											\
					* ((PUSHORT) (CodeAddress))++ = X86_OPCODE_JMP_DWORD_PTR;		\
					* (PULONG) (CodeAddress) = (ULONG) (JmpAddress);				\
					(PCHAR) (CodeAddress) += 4;


extern ULONG	SystemAddressStart;


BOOLEAN InitI386();
VOID VerifyUserReturnAddress();


#endif	/* __I386_H__ */