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
00026
#include <ntos.h>
00027 #define _KXPPC_C_HEADER_
00028
#include <kxppc.h>
00029
00030
VOID
00031 RtlInitializeContext(
00032 IN HANDLE Process,
00033 OUT PCONTEXT Context,
00034 IN PVOID Parameter OPTIONAL,
00035 IN PVOID InitialPc OPTIONAL,
00036 IN PVOID InitialSp OPTIONAL
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
00068
00069
00070
if (((ULONG)InitialSp & 0x7) != 0) {
00071
RtlRaiseStatus(STATUS_BAD_INITIAL_STACK);
00072 }
00073
if (((ULONG)InitialPc & 0x3) != 0) {
00074
RtlRaiseStatus(STATUS_BAD_INITIAL_PC);
00075 }
00076
00077
00078
00079
00080
00081 RtlZeroMemory(Context,
sizeof(CONTEXT));
00082
00083
00084
00085
00086
00087
if ( ARGUMENT_PRESENT(InitialPc) ) {
00088 Context->Iar = (ULONG)InitialPc;
00089 }
00090
if ( ARGUMENT_PRESENT(InitialSp) ) {
00091 Context->Gpr1 = (ULONG)InitialSp -
STK_MIN_FRAME;
00092 }
00093
00094 Context->Msr =
00095 MASK_SPR(MSR_ILE,1)|
00096 MASK_SPR(MSR_FP,1) |
00097 MASK_SPR(MSR_FE0,1)|
00098 MASK_SPR(MSR_FE1,1)|
00099 MASK_SPR(MSR_ME,1) |
00100 MASK_SPR(MSR_IR,1) |
00101 MASK_SPR(MSR_DR,1) |
00102 MASK_SPR(MSR_PR,1) |
00103 MASK_SPR(MSR_LE,1);
00104 Context->ContextFlags =
CONTEXT_FULL;
00105
00106
00107
00108
00109
00110 Context->Gpr3 = (ULONG)Parameter;
00111 }
00112
00113
NTSTATUS
00114 RtlRemoteCall(
00115 HANDLE Process,
00116 HANDLE Thread,
00117 PVOID CallSite,
00118 ULONG ArgumentCount,
00119 PULONG Arguments,
00120 BOOLEAN PassContext,
00121 BOOLEAN AlreadySuspended
00122 )
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 {
00161
00162
NTSTATUS Status;
00163 CONTEXT Context;
00164 ULONG NewSp;
00165
00166
if (ArgumentCount > 8) {
00167
return(STATUS_INVALID_PARAMETER);
00168 }
00169
00170
00171
00172
00173
00174
00175
if (AlreadySuspended ==
FALSE) {
00176
Status =
NtSuspendThread(Thread,
NULL);
00177
if (
NT_SUCCESS(
Status) ==
FALSE) {
00178
return(
Status);
00179 }
00180 }
00181
00182
00183
00184
00185
00186 Context.ContextFlags =
CONTEXT_FULL;
00187
Status =
NtGetContextThread(Thread, &Context);
00188
if (
NT_SUCCESS(
Status) ==
FALSE) {
00189
if (AlreadySuspended ==
FALSE) {
00190
NtResumeThread(Thread,
NULL);
00191 }
00192
return(
Status);
00193 }
00194
00195
if (AlreadySuspended ) {
00196
00197 Context.Gpr3 = STATUS_ALERTED;
00198 }
00199
00200
00201
00202
00203
00204
00205 NewSp = Context.Gpr1 -
sizeof(CONTEXT) -
STK_MIN_FRAME;
00206
Status =
NtWriteVirtualMemory(Process, (PVOID)(NewSp +
STK_MIN_FRAME), &Context,
00207
sizeof(CONTEXT),
NULL);
00208
Status =
NtWriteVirtualMemory(Process, (PVOID)NewSp, &Context.Gpr1,
00209
sizeof(ULONG),
NULL);
00210
if (
NT_SUCCESS(
Status) ==
FALSE) {
00211
if (AlreadySuspended ==
FALSE) {
00212
NtResumeThread(Thread,
NULL);
00213 }
00214
return(
Status);
00215 }
00216
00217 Context.Gpr1 = NewSp;
00218
00219
if (PassContext) {
00220 Context.Gpr14 = NewSp +
STK_MIN_FRAME;
00221 RtlMoveMemory(&Context.Gpr15, Arguments, ArgumentCount *
sizeof(ULONG));
00222
00223 }
else {
00224
00225 RtlMoveMemory(&Context.Gpr14, Arguments, ArgumentCount *
sizeof(ULONG));
00226 }
00227
00228
00229
00230
00231
00232
00233 Context.Iar = (ULONG)CallSite;
00234 Context.Gpr2 = 0;
00235
Status =
NtSetContextThread(Thread, &Context);
00236
if (AlreadySuspended ==
FALSE) {
00237
NtResumeThread(Thread,
NULL);
00238 }
00239
return(
Status);
00240 }