00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include <ntos.h>
00026
00027
VOID
00028 RtlInitializeContext(
00029 IN HANDLE Process,
00030 OUT PCONTEXT Context,
00031 IN PVOID Parameter OPTIONAL,
00032 IN PVOID InitialPc OPTIONAL,
00033 IN PVOID InitialSp OPTIONAL
00034 )
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 {
00062
00063
00064
00065
00066
00067
if (((ULONG)InitialSp & 0x7) != 0) {
00068
RtlRaiseStatus(STATUS_BAD_INITIAL_STACK);
00069 }
00070
if (((ULONG)InitialPc & 0x3) != 0) {
00071
RtlRaiseStatus(STATUS_BAD_INITIAL_PC);
00072 }
00073
00074
00075
00076
00077
00078 Context->XIntZero = 0;
00079 Context->XIntAt = 1;
00080 Context->XIntV0 = 2;
00081 Context->XIntV1 = 3;
00082 Context->XIntA0 = 4;
00083 Context->XIntA1 = 5;
00084 Context->XIntA2 = 6;
00085 Context->XIntA3 = 7;
00086 Context->XIntT0 = 8;
00087 Context->XIntT1 = 9;
00088 Context->XIntT2 = 10;
00089 Context->XIntT3 = 11;
00090 Context->XIntT4 = 12;
00091 Context->XIntT5 = 13;
00092 Context->XIntT6 = 14;
00093 Context->XIntT7 = 15;
00094 Context->XIntS0 = 16;
00095 Context->XIntS1 = 17;
00096 Context->XIntS2 = 18;
00097 Context->XIntS3 = 19;
00098 Context->XIntS4 = 20;
00099 Context->XIntS5 = 21;
00100 Context->XIntS6 = 22;
00101 Context->XIntS7 = 23;
00102 Context->XIntT8 = 24;
00103 Context->XIntT9 = 25;
00104 Context->XIntS8 = 30;
00105 Context->XIntLo = 0;
00106 Context->XIntHi = 0;
00107
00108
00109
00110
00111
00112
00113 Context->FltF0 = 0;
00114 Context->FltF1 = 0;
00115 Context->FltF2 = 2;
00116 Context->FltF3 = 0;
00117 Context->FltF4 = 4;
00118 Context->FltF5 = 0;
00119 Context->FltF6 = 6;
00120 Context->FltF7 = 0;
00121 Context->FltF8 = 8;
00122 Context->FltF9 = 0;
00123 Context->FltF10 = 10;
00124 Context->FltF11 = 0;
00125 Context->FltF12 = 12;
00126 Context->FltF13 = 0;
00127 Context->FltF14 = 14;
00128 Context->FltF15 = 0;
00129 Context->FltF16 = 16;
00130 Context->FltF17 = 0;
00131 Context->FltF18 = 18;
00132 Context->FltF19 = 0;
00133 Context->FltF20 = 20;
00134 Context->FltF21 = 0;
00135 Context->FltF22 = 22;
00136 Context->FltF23 = 0;
00137 Context->FltF24 = 24;
00138 Context->FltF25 = 0;
00139 Context->FltF26 = 26;
00140 Context->FltF27 = 0;
00141 Context->FltF28 = 28;
00142 Context->FltF29 = 0;
00143 Context->FltF30 = 30;
00144 Context->FltF31 = 0;
00145 Context->Fsr = 0;
00146
00147
00148
00149
00150
00151
00152
00153 Context->XIntGp = 0;
00154 Context->XIntSp = (LONG)InitialSp;
00155 Context->XIntRa = 1;
00156 Context->Fir = (ULONG)InitialPc;
00157 Context->Psr = 0;
00158 Context->ContextFlags =
CONTEXT_FULL;
00159
00160
00161
00162
00163
00164 Context->XIntA0 = (LONG)Parameter;
00165 Context->XIntSp -= KTRAP_FRAME_ARGUMENTS;
00166 }
00167
00168
NTSTATUS
00169 RtlRemoteCall(
00170 HANDLE Process,
00171 HANDLE Thread,
00172 PVOID CallSite,
00173 ULONG ArgumentCount,
00174 PULONG Arguments,
00175 BOOLEAN PassContext,
00176 BOOLEAN AlreadySuspended
00177 )
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 {
00216
00217
NTSTATUS Status;
00218 CONTEXT Context;
00219 ULONG NewSp;
00220
00221
if (ArgumentCount > 8) {
00222
return(STATUS_INVALID_PARAMETER);
00223 }
00224
00225
00226
00227
00228
00229
00230
if (AlreadySuspended ==
FALSE) {
00231
Status =
NtSuspendThread(Thread,
NULL);
00232
if (
NT_SUCCESS(
Status) ==
FALSE) {
00233
return(
Status);
00234 }
00235 }
00236
00237
00238
00239
00240
00241 Context.ContextFlags =
CONTEXT_FULL;
00242
Status =
NtGetContextThread(Thread, &Context);
00243
if (
NT_SUCCESS(
Status) ==
FALSE) {
00244
if (AlreadySuspended ==
FALSE) {
00245
NtResumeThread(Thread,
NULL);
00246 }
00247
00248
return Status;
00249 }
00250
00251
if (AlreadySuspended) {
00252 Context.XIntV0 = (LONG)STATUS_ALERTED;
00253 }
00254
00255
00256
00257
00258
00259
00260 NewSp = (ULONG)(Context.XIntSp -
sizeof(CONTEXT));
00261
Status =
NtWriteVirtualMemory(Process,
00262 (PVOID)NewSp,
00263 &Context,
00264
sizeof(CONTEXT),
00265
NULL);
00266
00267
if (
NT_SUCCESS(
Status) ==
FALSE) {
00268
if (AlreadySuspended ==
FALSE) {
00269
NtResumeThread(Thread,
NULL);
00270 }
00271
00272
return Status;
00273 }
00274
00275 Context.XIntSp = (LONG)NewSp;
00276
if (PassContext) {
00277 Context.XIntS0 = (LONG)NewSp;
00278 RtlMoveMemory(&Context.XIntS1, Arguments, ArgumentCount *
sizeof(ULONG));
00279
00280 }
else {
00281 RtlMoveMemory(&Context.XIntS0, Arguments, ArgumentCount *
sizeof(ULONG));
00282 }
00283
00284
00285
00286
00287
00288
00289 Context.Fir = (ULONG)CallSite;;
00290
Status =
NtSetContextThread(Thread, &Context);
00291
if (AlreadySuspended ==
FALSE) {
00292
NtResumeThread(Thread,
NULL);
00293 }
00294
00295
return Status;
00296 }