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
00027
#include "ntrtlp.h"
00028
00029
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00030
#pragma alloc_text(PAGE,RtlInitializeContext)
00031
#pragma alloc_text(PAGE,RtlRemoteCall)
00032
#endif
00033
00034
00035
VOID
00036 RtlInitializeContext(
00037 IN HANDLE Process,
00038 OUT PCONTEXT Context,
00039 IN PVOID Parameter OPTIONAL,
00040 IN PVOID InitialPc OPTIONAL,
00041 IN PVOID InitialSp OPTIONAL
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
RTL_PAGED_CODE();
00071
00072 Context->Eax = 0
L;
00073 Context->Ebx = 1
L;
00074 Context->Ecx = 2
L;
00075 Context->Edx = 3
L;
00076 Context->Esi = 4
L;
00077 Context->Edi = 5
L;
00078 Context->Ebp = 0
L;
00079
00080 Context->SegGs = 0;
00081 Context->SegFs = KGDT_R3_TEB;
00082 Context->SegEs = KGDT_R3_DATA;
00083 Context->SegDs = KGDT_R3_DATA;
00084 Context->SegSs = KGDT_R3_DATA;
00085 Context->SegCs = KGDT_R3_CODE;
00086
00087 Context->EFlags = 0x200
L;
00088
00089
00090
00091
00092
00093
00094 Context->Esp = (ULONG) InitialSp;
00095 Context->Eip = (ULONG) InitialPc;
00096
00097
00098
00099
00100
00101 Context->ContextFlags =
CONTEXT_CONTROL|
CONTEXT_INTEGER|CONTEXT_SEGMENTS;
00102
00103
00104
00105
00106
00107
00108 Context->Esp -=
sizeof(Parameter);
00109 ZwWriteVirtualMemory(Process,
00110 (PVOID)Context->Esp,
00111 (PVOID)&Parameter,
00112
sizeof(Parameter),
00113
NULL);
00114 Context->Esp -=
sizeof(Parameter);
00115
00116
00117 }
00118
00119
00120
00121
NTSTATUS
00122 RtlRemoteCall(
00123 HANDLE Process,
00124 HANDLE Thread,
00125 PVOID CallSite,
00126 ULONG ArgumentCount,
00127 PULONG Arguments,
00128 BOOLEAN PassContext,
00129 BOOLEAN AlreadySuspended
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
00163
00164
00165 {
00166
NTSTATUS Status;
00167 CONTEXT Context;
00168 ULONG NewSp;
00169 ULONG ArgumentsCopy[5];
00170
00171
RTL_PAGED_CODE();
00172
00173
if (ArgumentCount > 4)
00174
return STATUS_INVALID_PARAMETER;
00175
00176
00177
00178
00179
if (!AlreadySuspended) {
00180
Status =
NtSuspendThread( Thread,
NULL );
00181
if (!
NT_SUCCESS(
Status )) {
00182
return(
Status );
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191 Context.ContextFlags =
CONTEXT_FULL;
00192
Status =
NtGetContextThread( Thread, &Context );
00193
if (!
NT_SUCCESS(
Status )) {
00194
if (!AlreadySuspended) {
00195
NtResumeThread( Thread,
NULL );
00196 }
00197
return(
Status );
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 NewSp = Context.Esp;
00210
if (PassContext) {
00211 NewSp -=
sizeof( CONTEXT );
00212
Status =
NtWriteVirtualMemory( Process,
00213 (PVOID)NewSp,
00214 &Context,
00215
sizeof( CONTEXT ),
00216
NULL
00217 );
00218
if (!
NT_SUCCESS(
Status )) {
00219
if (!AlreadySuspended) {
00220
NtResumeThread( Thread,
NULL );
00221 }
00222
return(
Status );
00223 }
00224 ArgumentsCopy[0] = NewSp;
00225 RtlMoveMemory(&(ArgumentsCopy[1]),Arguments,ArgumentCount*
sizeof( ULONG ));
00226 ArgumentCount++;
00227 }
00228
else {
00229 RtlMoveMemory(ArgumentsCopy,Arguments,ArgumentCount*
sizeof( ULONG ));
00230 }
00231
00232
00233
00234
00235
if (ArgumentCount) {
00236 NewSp -= ArgumentCount *
sizeof( ULONG );
00237
Status =
NtWriteVirtualMemory( Process,
00238 (PVOID)NewSp,
00239 ArgumentsCopy,
00240 ArgumentCount *
sizeof( ULONG ),
00241
NULL
00242 );
00243
if (!
NT_SUCCESS(
Status )) {
00244
if (!AlreadySuspended) {
00245
NtResumeThread( Thread,
NULL );
00246 }
00247
return(
Status );
00248 }
00249 }
00250
00251
00252
00253
00254
00255 Context.Esp = NewSp;
00256 Context.Eip = (ULONG)CallSite;
00257
Status =
NtSetContextThread( Thread, &Context );
00258
if (!AlreadySuspended) {
00259
NtResumeThread( Thread,
NULL );
00260 }
00261
00262
return(
Status );
00263 }