CreateProcesssA 函数工作流程分析:
用IDA打开CreateProcessA跟进,调用流程:
call kernel32!CreateProcesssA
call kernel32!CreateProcessInternalA
call kernel32!CreateProcessInternalW
kernel32!CreateProcessInternal函数 流程图太复杂,估计代码超过2000行, 看起来很晕 _ ~ _ ~
用IDA插件 将汇编转换为C源码, 源码最有说服力。
大致看一下 CreateProcessInternal调用了
RtlImageNtHeader
NtQueryInformationToken
RtlAllocateHeap
BasepProcessInvalidImage
GetFileAttributesW
SearchPathW 这些函数
最后调用NtCreateUserProcess
该函数 做的事情是 申请内存, 读取磁盘PE文件,做 一系列的测试工作,一切OK,
调用NtCreateUserProcess去创建进程
0:000> u NtCreateUserProcess l10
ntdll!NtCreateUserProcess:
77285860 b85d000000 mov eax,5Dh
77285865 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
7728586a ff12 call dword ptr [edx]
7728586c c22c00 ret 2Ch
7728586f 90 nop
_KUSER_SHARED_DATA 区域内容是什么?(User 层和 Kernel 层是一样的),在 windbg 用 dt 命令查看:
kd> dt _KUSER_SHARED_DATA 0x7ffe0000
ntdll!_KUSER_SHARED_DATA
0x000 TickCountLowDeprecated : 0
0x004 TickCountMultiplier : 0xfa00000
0x008 InterruptTime : _KSYSTEM_TIME
0x014 SystemTime : _KSYSTEM_TIME
0x020 TimeZoneBias : _KSYSTEM_TIME
0x02c ImageNumberLow : 0x14c
0x02e ImageNumberHigh : 0x14c
0x030 NtSystemRoot : [260] 0x43
0x238 MaxStackTraceDepth : 0
0x23c CryptoExponent : 0
0x240 TimeZoneId : 0
0x244 LargePageMinimum : 0x200000
0x248 Reserved2 : [7] 0
0x264 NtProductType : 3 ( NtProductServer )
0x268 ProductTypeIsValid : 0x1 ''
0x26c NtMajorVersion : 5
0x270 NtMinorVersion : 2
0x274 ProcessorFeatures : [64] ""
0x2b4 Reserved1 : 0x7ffeffff
0x2b8 Reserved3 : 0x80000000
0x2bc TimeSlip : 0
0x2c0 AlternativeArchitecture : 0 ( StandardDesign )
0x2c8 SystemExpirationDate : _LARGE_INTEGER 0x0
0x2d0 SuiteMask : 0x112
0x2d4 KdDebuggerEnabled : 0x3 ''
0x2d5 NXSupportPolicy : 0x2 ''
0x2d8 ActiveConsoleId : 0
0x2dc DismountCount : 0
0x2e0 ComPlusPackage : 0xffffffff
0x2e4 LastSystemRITEventTickCount : 0x239f29d
0x2e8 NumberOfPhysicalPages : 0x17f1b
0x2ec SafeBootMode : 0 ''
0x2f0 TraceLogging : 0
0x2f8 TestRetInstruction : 0xc3
0x300 SystemCall : 0x7c958458 <--------- System Call stub 函数
0x304 SystemCallReturn : 0x7c95845c <--------- System Call return 函数
0x308 SystemCallPad : [3] 0
0x320 TickCount : _KSYSTEM_TIME
0x320 TickCountQuad : 0x2481d8
0x330 Cookie : 0xa4a0f27b
0x334 Wow64SharedInformation : [16] 0
其中 0x300 位置上就是 KiFastSystemCall() stub 而函数地址 0x304 位置为返回函数地址:
ntdll!KiFastSystemCall:
7c958458 8bd4 mov edx,esp ; 传送 caller 的 stack frame pointer
7c95845a 0f34 sysenter ; 快速切入到 kernel
7c95845c c3 ret ; 注意:其实这是独立的 ntdll!KiFastSystemCallRet() 例程
地址 0x7c958458 是 ntdll!KiFastSystemCall() 函数地址,地址 0x7c95845c 是 ntdll!KiFastSystemCallRet() 函数地址。
切入 KiFastCallEntry()在用户层的 stub 函数会使用 sysenter 指令切入内核层 KiFastCallEntry() 函数,再由 KiFastCallEntry() 函数分发到相应的系统服务例程执行。
到这里就Ring3流程完成, 归纳下CreateUserProcessA流程
call kernel32!CreateProcesssA
call kernel32!CreateProcessInternalA
call kernel32!CreateProcessInternalW
call 初始工作
call ntdll!NtCreateUserProcess
call SharedUserData!SystemCallStub
call ntdll!KiFastSystemCall
call ntdll!KiFastCallEntry
1 void __stdcall CreateProcessInternalW(void *a1, _DWORD a2, const wchar_t *a3, int a4, int a5, int a6, int a7, int a8, const WCHAR *a9, int a10, int a11, _DWORD a12) 2 { 3 signed int v12; // eax@130 4 unsigned int v13; // eax@133 5 const wchar_t *v14; // edi@133 6 STRSAFE_LPCWSTR v15; // eax@147 7 const wchar_t v16; // cx@148 8 PVOID v17; // eax@149 9 wchar_t *v18; // esi@149 10 STRSAFE_LPCWSTR v19; // edi@150 11 int v20; // eax@164 12 int v21; // edx@164 13 unsigned int i; // ecx@164 14 HMODULE v23; // eax@175 15 PIMAGE_NT_HEADERS v24; // eax@175 16 _WORD v25; // cx@4 17 HANDLE v26; // ecx@20 18 int v27; // edi@23 19 NTSTATUS v28; // eax@25 20 HANDLE v29; // eax@29 21 PVOID v30; // edi@37 22 DWORD v31; // eax@38 23 DWORD v32; // esi@38 24 DWORD v33; // eax@40 25 int v34; // eax@44 26 ULONG v35; // eax@67 27 int v36; // eax@69 28 struct _RTL_USER_PROCESS_PARAMETERS *v37; // edi@69 29 int v38; // esi@70 30 void *v39; // edi@71 31 NTSTATUS v40; // eax@76 32 int v41; // eax@107 33 NTSTATUS v42; // edi@107 34 int v43; // eax@115 35 NTSTATUS v44; // esi@115 36 HANDLE v45; // eax@116 37 int v46; // esi@118 38 NTSTATUS v47; // eax@183 39 int v48; // esi@213 40 int v49; // eax@214 41 int v50; // eax@248 42 _BYTE v51; // al@261 43 int v52; // edi@268 44 int v53; // esi@271 45 signed int v54; // eax@308 46 NTSTATUS v55; // [sp-4h] [bp-62Ch]@209 47 signed int v56; // [sp-4h] [bp-62Ch]@235 48 NTSTATUS v57; // [sp-4h] [bp-62Ch]@158 49 char v58; // [sp+10h] [bp-618h]@45 50 char v59; // [sp+28h] [bp-600h]@44 51 ULONG v60; // [sp+40h] [bp-5E8h]@27 52 int v61; // [sp+48h] [bp-5E0h]@58 53 int v62; // [sp+6Ch] [bp-5BCh]@34 54 unsigned __int32 v63; // [sp+84h] [bp-5A4h]@205 55 unsigned __int32 v64; // [sp+88h] [bp-5A0h]@153 56 unsigned __int32 v65; // [sp+8Ch] [bp-59Ch]@327 57 unsigned __int32 v66; // [sp+90h] [bp-598h]@185 58 int v67; // [sp+94h] [bp-594h]@69 59 int v68; // [sp+9Ch] [bp-58Ch]@213 60 unsigned __int32 v69; // [sp+A0h] [bp-588h]@144 61 unsigned __int32 v70; // [sp+A4h] [bp-584h]@269 62 PIMAGE_NT_HEADERS v71; // [sp+A8h] [bp-580h]@175 63 unsigned __int32 v72; // [sp+ACh] [bp-57Ch]@149 64 int v73; // [sp+B0h] [bp-578h]@164 65 unsigned __int32 v74; // [sp+B4h] [bp-574h]@185 66 unsigned __int32 v75; // [sp+B8h] [bp-570h]@258 67 unsigned __int32 v76; // [sp+BCh] [bp-56Ch]@141 68 ULONG Arguments; // [sp+C0h] [bp-568h]@277 69 unsigned __int32 v78; // [sp+C8h] [bp-560h]@37 70 WCHAR *v79; // [sp+CCh] [bp-55Ch]@133 71 unsigned __int32 v80; // [sp+D0h] [bp-558h]@276 72 unsigned __int32 v81; // [sp+D4h] [bp-554h]@140 73 char v82; // [sp+D8h] [bp-550h]@19 74 int v83; // [sp+E8h] [bp-540h]@71 75 unsigned __int16 v84; // [sp+ECh] [bp-53Ch]@73 76 unsigned __int16 v85; // [sp+EEh] [bp-53Ah]@73 77 unsigned int v86; // [sp+F6h] [bp-532h]@92 78 unsigned __int16 v87; // [sp+F8h] [bp-530h]@87 79 int v88; // [sp+108h] [bp-520h]@1 80 HANDLE v89; // [sp+10Ch] [bp-51Ch]@1 81 int v90; // [sp+110h] [bp-518h]@110 82 PVOID v91; // [sp+114h] [bp-514h]@110 83 unsigned __int16 v92; // [sp+118h] [bp-510h]@110 84 unsigned __int16 v93; // [sp+11Ah] [bp-50Eh]@110 85 unsigned int v94; // [sp+11Ch] [bp-50Ch]@110 86 int v95; // [sp+120h] [bp-508h]@110 87 int v96; // [sp+128h] [bp-500h]@259 88 int v97; // [sp+12Ch] [bp-4FCh]@259 89 int v98; // [sp+130h] [bp-4F8h]@127 90 ULONG v99; // [sp+134h] [bp-4F4h]@37 91 DWORD v100; // [sp+138h] [bp-4F0h]@40 92 int v101; // [sp+13Ch] [bp-4ECh]@45 93 ULONG ReturnLength; // [sp+140h] [bp-4E8h]@143 94 int v103; // [sp+144h] [bp-4E4h]@118 95 int v104; // [sp+148h] [bp-4E0h]@300 96 DWORD v105; // [sp+14Ch] [bp-4DCh]@38 97 unsigned int v106; // [sp+150h] [bp-4D8h]@271 98 STRING AnsiString; // [sp+154h] [bp-4D4h]@4 99 LPWSTR FilePart; // [sp+15Ch] [bp-4CCh]@4 100 UNICODE_STRING SourceString; // [sp+160h] [bp-4C8h]@4 101 BOOL Result; // [sp+168h] [bp-4C0h]@31 102 ULONG Flags; // [sp+16Ch] [bp-4BCh]@156 103 int TokenInformation; // [sp+170h] [bp-4B8h]@143 104 unsigned int v113; // [sp+174h] [bp-4B4h]@165 105 int v114; // [sp+178h] [bp-4B0h]@86 106 int v115; // [sp+17Ch] [bp-4ACh]@46 107 ULONG MessageBoxResult; // [sp+180h] [bp-4A8h]@277 108 int v117; // [sp+184h] [bp-4A4h]@1 109 int v118; // [sp+188h] [bp-4A0h]@44 110 int v119; // [sp+18Ch] [bp-49Ch]@1 111 ULONG v120; // [sp+190h] [bp-498h]@67 112 int v121; // [sp+194h] [bp-494h]@53 113 int v122; // [sp+198h] [bp-490h]@128 114 void *v123; // [sp+19Ch] [bp-48Ch]@53 115 int v124; // [sp+1A0h] [bp-488h]@58 116 void *v125; // [sp+1A4h] [bp-484h]@71 117 int v126; // [sp+1B8h] [bp-470h]@92 118 int v127; // [sp+1BCh] [bp-46Ch]@83 119 int v128; // [sp+1C0h] [bp-468h]@93 120 int v129; // [sp+1C4h] [bp-464h]@93 121 int v130; // [sp+1CCh] [bp-45Ch]@75 122 int v131; // [sp+1D0h] [bp-458h]@75 123 int v132; // [sp+1D4h] [bp-454h]@75 124 int v133; // [sp+1DCh] [bp-44Ch]@164 125 int v134; // [sp+1E0h] [bp-448h]@164 126 int v135; // [sp+1E4h] [bp-444h]@1 127 int v136; // [sp+1E8h] [bp-440h]@92 128 int v137; // [sp+1ECh] [bp-43Ch]@4 129 int v138; // [sp+1F0h] [bp-438h]@4 130 int v139; // [sp+1F4h] [bp-434h]@4 131 int v140; // [sp+1F8h] [bp-430h]@19 132 int v141; // [sp+1FCh] [bp-42Ch]@93 133 int v142; // [sp+200h] [bp-428h]@203 134 NTSTATUS v143; // [sp+204h] [bp-424h]@203 135 int v144; // [sp+208h] [bp-420h]@51 136 PVOID BaseAddress; // [sp+20Ch] [bp-41Ch]@171 137 int v146; // [sp+210h] [bp-418h]@4 138 char v147[4]; // [sp+214h] [bp-414h]@4 139 unsigned int v148; // [sp+218h] [bp-410h]@1 140 HANDLE v149; // [sp+21Ch] [bp-40Ch]@268 141 int v150; // [sp+220h] [bp-408h]@4 142 int v151; // [sp+224h] [bp-404h]@1 143 int v152; // [sp+228h] [bp-400h]@60 144 int v153; // [sp+230h] [bp-3F8h]@83 145 char v154[4]; // [sp+234h] [bp-3F4h]@4 146 ULONG BufferLength; // [sp+238h] [bp-3F0h]@4 147 int v156; // [sp+23Ch] [bp-3ECh]@4 148 int v157; // [sp+240h] [bp-3E8h]@4 149 LPCWSTR v158; // [sp+244h] [bp-3E4h]@1 150 ULONG v159; // [sp+248h] [bp-3E0h]@51 151 HANDLE v160; // [sp+24Ch] [bp-3DCh]@4 152 PVOID v161; // [sp+250h] [bp-3D8h]@4 153 int v162; // [sp+254h] [bp-3D4h]@1 154 LSA_UNICODE_STRING v163; // [sp+258h] [bp-3D0h]@4 155 int v164; // [sp+260h] [bp-3C8h]@66 156 NTSTATUS v165; // [sp+264h] [bp-3C4h]@69 157 PVOID Environment; // [sp+268h] [bp-3C0h]@1 158 int v167; // [sp+26Ch] [bp-3BCh]@4 159 int v168; // [sp+270h] [bp-3B8h]@1 160 PVOID v169; // [sp+274h] [bp-3B4h]@4 161 PVOID v170; // [sp+278h] [bp-3B0h]@4 162 int v171; // [sp+27Ch] [bp-3ACh]@4 163 int v172; // [sp+284h] [bp-3A4h]@4 164 char v173[4]; // [sp+288h] [bp-3A0h]@4 165 PVOID Buffer; // [sp+28Ch] [bp-39Ch]@4 166 int v175; // [sp+290h] [bp-398h]@1 167 int v176; // [sp+294h] [bp-394h]@4 168 HANDLE v177; // [sp+298h] [bp-390h]@4 169 PVOID v178; // [sp+29Ch] [bp-38Ch]@4 170 PVOID v179; // [sp+2A0h] [bp-388h]@4 171 NTSTATUS ExitStatus; // [sp+2A4h] [bp-384h]@4 172 int v181; // [sp+2A8h] [bp-380h]@70 173 PVOID v182; // [sp+2ACh] [bp-37Ch]@1 174 int v183; // [sp+2B0h] [bp-378h]@4 175 ULONG Size; // [sp+2B4h] [bp-374h]@149 176 LSA_UNICODE_STRING UnicodeString; // [sp+2B8h] [bp-370h]@1 177 LPCWSTR lpPath; // [sp+2C0h] [bp-368h]@1 178 int v187; // [sp+2C4h] [bp-364h]@1 179 int ProcessInformation; // [sp+2C8h] [bp-360h]@88 180 HANDLE TokenHandle; // [sp+2CCh] [bp-35Ch]@1 181 PVOID Address; // [sp+2D0h] [bp-358h]@4 182 int v191; // [sp+2D4h] [bp-354h]@1 183 HANDLE v192; // [sp+2D8h] [bp-350h]@4 184 char v193; // [sp+2DDh] [bp-34Bh]@60 185 char v194; // [sp+2DFh] [bp-349h]@224 186 STRSAFE_LPCWSTR v195; // [sp+2E0h] [bp-348h]@1 187 HANDLE ThreadHandle; // [sp+2E4h] [bp-344h]@4 188 NTSTATUS v197; // [sp+2E8h] [bp-340h]@76 189 int v198; // [sp+2ECh] [bp-33Ch]@4 190 int v199; // [sp+2F0h] [bp-338h]@1 191 HANDLE Handle; // [sp+2F4h] [bp-334h]@4 192 char v201; // [sp+2FAh] [bp-32Eh]@4 193 char v202; // [sp+2FBh] [bp-32Dh]@4 194 STRSAFE_LPCWSTR pszSrc; // [sp+2FCh] [bp-32Ch]@1 195 char Str[6]; // [sp+302h] [bp-326h]@1 196 HANDLE ProcessHandle; // [sp+308h] [bp-320h]@4 197 char v206; // [sp+30Eh] [bp-31Ah]@4 198 char v207; // [sp+30Fh] [bp-319h]@14 199 int v208; // [sp+310h] [bp-318h]@19 200 int v209; // [sp+314h] [bp-314h]@1 201 char Dst; // [sp+318h] [bp-310h]@4 202 int v211; // [sp+418h] [bp-210h]@102 203 NTSTATUS NtStatus; // [sp+438h] [bp-1F0h]@102 204 void *v213; // [sp+440h] [bp-1E8h]@93 205 HANDLE v214; // [sp+444h] [bp-1E4h]@93 206 int v215; // [sp+448h] [bp-1E0h]@93 207 int v216; // [sp+44Ch] [bp-1DCh]@93 208 int v217; // [sp+450h] [bp-1D8h]@93 209 int v218; // [sp+454h] [bp-1D4h]@98 210 int v219; // [sp+458h] [bp-1D0h]@310 211 signed int v220; // [sp+45Ch] [bp-1CCh]@310 212 _DWORD v221; // [sp+460h] [bp-1C8h]@87 213 int v222; // [sp+464h] [bp-1C4h]@92 214 _DWORD v223; // [sp+4C8h] [bp-160h]@107 215 _DWORD v224; // [sp+4D4h] [bp-154h]@110 216 _DWORD v225; // [sp+4E0h] [bp-148h]@107 217 int v226; // [sp+4E8h] [bp-140h]@93 218 int v227; // [sp+4ECh] [bp-13Ch]@93 219 int v228; // [sp+4F0h] [bp-138h]@93 220 _WORD v229; // [sp+4F4h] [bp-134h]@93 221 int v230; // [sp+4F8h] [bp-130h]@70 222 int v231; // [sp+4FCh] [bp-12Ch]@19 223 int v232; // [sp+500h] [bp-128h]@70 224 PWSTR v233; // [sp+504h] [bp-124h]@70 225 int v234; // [sp+508h] [bp-120h]@19 226 int v235; // [sp+50Ch] [bp-11Ch]@19 227 int v236; // [sp+510h] [bp-118h]@19 228 int *v237; // [sp+514h] [bp-114h]@19 229 int v238; // [sp+518h] [bp-110h]@19 230 int v239; // [sp+51Ch] [bp-10Ch]@19 231 int v240; // [sp+520h] [bp-108h]@19 232 char *v241; // [sp+524h] [bp-104h]@19 233 int v242; // [sp+528h] [bp-100h]@19 234 int v243; // [sp+52Ch] [bp-FCh]@252 235 int v244; // [sp+530h] [bp-F8h]@252 236 int v245; // [sp+534h] [bp-F4h]@252 237 int v246; // [sp+538h] [bp-F0h]@252 238 CPPEH_RECORD ms_exc; // [sp+610h] [bp-18h]@23 239 240 TokenHandle = a1; 241 *(_DWORD *)&Str[2] = a2; 242 pszSrc = a3; 243 v119 = a4; 244 v117 = a5; 245 v187 = a8; 246 v158 = a9; 247 v135 = a10; 248 v175 = a11; 249 v209 = 0; 250 v195 = 0; 251 v151 = 0; 252 v168 = 0; 253 v199 = 0; 254 v191 = 0; 255 Environment = 0; 256 v182 = 0; 257 v162 = 0; 258 lpPath = 0; 259 UnicodeString.Length = 0; 260 *(_DWORD *)&UnicodeString.MaximumLength = 0; 261 HIWORD(UnicodeString.Buffer) = 0; 262 v88 = 0; 263 memset(&v89, 0, 0x1Cu); 264 v148 = 0; 265 if ( !a2 && !a3 ) 266 { 267 v57 = -1073741776; 268 LABEL_333: 269 BaseSetLastNTError(v57); 270 return; 271 } 272 if ( !v175 || !v135 ) 273 { 274 v57 = -1073741811; 275 goto LABEL_333; 276 } 277 v192 = 0; 278 Handle = 0; 279 v177 = 0; 280 ProcessHandle = 0; 281 ThreadHandle = 0; 282 v183 = 0; 283 Address = 0; 284 v178 = 0; 285 v172 = 0; 286 v167 = 0; 287 v161 = 0; 288 FilePart = 0; 289 v163.Buffer = 0; 290 Str[0] = 0; 291 v202 = 0; 292 v206 = 0; 293 v201 = 0; 294 v160 = 0; 295 v179 = 0; 296 Buffer = 0; 297 BufferLength = 0; 298 v170 = 0; 299 v156 = 0; 300 v169 = 0; 301 v150 = 0; 302 *(_DWORD *)v173 = 0; 303 *(_DWORD *)v154 = 0; 304 v146 = 0; 305 *(_DWORD *)v147 = 0; 306 v171 = 0; 307 ExitStatus = 0; 308 v198 = 0; 309 v157 = 0; 310 v137 = 0; 311 v138 = 0; 312 v139 = 0; 313 AnsiString.Buffer = 0; 314 SourceString.Buffer = 0; 315 memset(&Dst, 0, 0x100u); 316 v176 = *(_DWORD *)(__readfsdword(24) + 48); 317 v25 = a7; 318 if ( (a7 & 0x18) == 24 ) 319 goto LABEL_242; 320 if ( a7 & 0x800 ) 321 { 322 if ( !(a7 & 0x1000) ) 323 goto LABEL_8; 324 LABEL_242: 325 RtlSetLastWin32Error(87); 326 return; 327 } 328 if ( !(a7 & 0x1000) && *(_BYTE *)(BaseStaticServerData + 1872) ) 329 { 330 v25 = a7 | 0x800; 331 a7 |= 0x800u; 332 } 333 LABEL_8: 334 if ( v25 & 0x40 ) 335 { 336 v207 = 1; 337 } 338 else 339 { 340 if ( v25 & 0x4000 ) 341 { 342 v207 = 5; 343 } 344 else 345 { 346 if ( v25 & 0x20 ) 347 { 348 v207 = 2; 349 } 350 else 351 { 352 if ( v25 & 0x8000 ) 353 { 354 v207 = 6; 355 } 356 else 357 { 358 if ( (char)v25 < 0 ) 359 { 360 v207 = 3; 361 } 362 else 363 { 364 if ( v25 & 0x100 ) 365 v207 = (BasepIsRealtimeAllowed(0, TokenHandle != 0) != 0) + 3; 366 else 367 v207 = 0; 368 } 369 } 370 } 371 } 372 } 373 a7 &= 0xFFFF3E1Fu; 374 if ( a7 & 0x40000 ) 375 v198 = 64; 376 if ( a7 & 0x1000000 ) 377 v198 |= 1u; 378 if ( a7 & 0x10000 ) 379 v198 |= 0x100u; 380 if ( a7 & 3 ) 381 { 382 v50 = DbgUiConnectToDbg(); 383 if ( v50 < 0 ) 384 { 385 v57 = v50; 386 goto LABEL_333; 元器件数据手册、IC替代型号,打造电子元器件IC百科大全!