一个福雷乐趣进入Windows纤维

2021-06-18 03:03:26

Warning: Can only detect less than 5000 characters

在递增我们的马铃薯后,我们切换到下一个热点函数.Seems直观。所以为什么DO / while和switchtofiber回到主线程?考虑替代函数,Badhotpotatoone:

void __stdcall badhotpotatoone(lpvoid lpparam){unsigned int * potato_local =(unsigned int *)getfiberdata(); * potato_local + = 1; Printf("热马铃薯一次添加1,马铃薯现在是%d!\ n&#34 ;, * potato_local); switchtofiber(hot_potatoes [fiber_hp_two]); if(* potato_local> 1337){switchtofiber(hot_potatoes [mainfiber]); }}

Badhotpotatoone切换到Hotpotatotwo Hotpotatotwo开关到Hotpotatothree Hotpotatothree交换机到Badhotpotatoone会发生什么呢?当HotpotatoThree将SwitchTofiBer呼叫回到BadhotPotatoone时,SwitchTofiBer开始基于BadhotPotatoone呼叫后的下一个指令执行,然后在这种情况下,我们的归属后的下一个指令到Badhotpotatoone是我们的if语句,而不是我们光纤的开头。

void __stdcall badhotpotatoone(lpvoid lpparam){unsigned int * potato_local =(unsigned int *)getfiberdata(); * potato_local + = 1; Printf("热马铃薯一次添加1,马铃薯现在是%d!\ n&#34 ;, * potato_local); switchtofiber(hot_potatoes [fiber_hp_two]); < - 切换到热柱,然后切换到热柱,然后 - 如果(* potato_local> 1337){< - 执行当热斑点交换机后面的switchtofiber时返回下一个语句(hot_potatoes [mainfiber]); }}

因此,我们希望确保我们的期望行为是循环的下一条指令,在我们呼叫SwitchTofiBer之后。在我们的良好功能,热点,下一个指令是A""比较,然后是一个"做"将我们带回热柱的循环。这条路,当执行从热斑点的热点切换到热斑点时,我们循环而不是返回。

void __stdcall热点(lpvoid lpparam){// step 3 unsigned int * potato_local =(unsigned int *)getfiberdata(); do {* potato_local + = 1; Printf("热马铃薯一次添加1,马铃薯现在是%d!\ n&#34 ;, * potato_local); // step 4 switchtofiber(hot_potatoes [fiber_hp_two]); < - 切换到热柱,然后是hotpotatothree,然后 - }(* potato_local< 1337); < - 执行返回比较,保持循环到* potato_local> 1337 switchtofiber(hot_potatoes [fiber_main]); }

文档是一个谎言。没有认真。出色地。类型的.creadiber和convertthreadtofiber的MSDN文档告诉我们返回值是光纤的地址。这是"真,"但误导为"纤维"结构未记录。我最初将其解释为例程I' m转换为/创建作为光纤的基础地址。这些函数的实际返回值是光纤对象。 (代表性的对象,而不是类型的感觉).This数据结构似乎与Get / SetThreadContext函数中使用的线程和#39; scountcuts结构非常相似。' s仔细研究每个功能我们调用它返回一个LPVOID光纤对象(ConvertThreadtofiber,Createfiber)。ReactOS的罚款已经写了一个ConvertThreadTofiber / Ex.let和#39; S看那个来源并与Kernelbase的拆卸进行比较!convertThreadtofiberex.reactos convertthreadtofiberex:

lpvoidwinapiconvertthreadtofiberex(_in_opt_ lpvoid lpparameter,_in_ dword dwflags){pteb teb; Pfiber纤维; dprint1("将线程转换为光纤\ n"); / *检查无效标志* / if(dwflags&〜fiber_flag_float_switch){/ * fall * / setLasterror(error_invalid_parameter);返回null; } / *我们已经是纤维吗? * / teb = ntcurrentteb(); if(teb-> hasfiberdata){/ * fall * / setLasterror(Error_Already_Fiber);返回null; } / *分配光纤* / fible = rtlallocateHeap(RTLGetProcessheap(),0,sizeof(光纤)); if(!fible){/ * fall * / setLasterror(error_not_enough_memory);返回null; }。 。 。被截断的,无聊的狗屎我不在乎。 。 。 / *将光纤与当前线程* / teb-&gt相关联; nttiib.fiberdata =光纤; teb-> hasfiberdata = true; //我们真正关心/ *返回不透明光纤数据* /返回(LPVOID)光纤; // msdn表示这是指向光纤的指针,而不是光纤对象// hmmmmmmmm}

KERNELBASE!CONVERTTHREADTOFIBR:00007FFC`CDD58160 48895C2408 MOV QWORD PTR [RSP + 8],RBX SS:000000C4`533BF970 = {FibleBlog!_NullBlog + 0x22015)(00007FF6`CDD58165 4889742410 MOV QWORD PTR [RSP + 10H ],RSI00007FFC`CDD5816A 57推送RDI00007FFC`CDD5816B 4883EC20子RSP,20H 00007FFC`CDD5816F 65488B3C253000000000 MOV RDI,QWORD PTR GS:[30H]; RDI获取指向当前_nt_tib的指针。 。 。 t r u n c a t e d。 。 。 00007FFC`CDD58252 66838FEE17000004或Word PTR [RDI + 17EEH],4;设置teb-> hasfiberdata标志到true 00007ffc`cdd5825a 48895720 mov qword ptr [rdi + 20h],rdx;设置Teb-> FiberData00007ffc`cdd5825e 488b742438 MOV RSI,qword的PTR [RSP + 38H] 00007ffc`cdd58263 488bc3 MOV RAX,rbx00007ffc`cdd58266 488b5c2430 MOV RBX,qword的PTR [RSP + 30H] 00007ffc`cdd5826b 4883c420加RSP,20h00007ffc`cdd5826f 5F POP RDI00007FFC`CDD58270 C3 RET

对于所有语义目的,行为是相同的。谢谢Reactos团队:)所以,与TEB和TIB的交易是什么'好吧,我很高兴你问你询问。从拆卸中取出两条说明并检查他们的抵消参考#39;重新引用。 (RDI == TEB)

00007FFC`CDD58252 66838FEE17000004或Word PTR [RDI + 17EEH],4;设置teb-> hasfiberdata标志到true 00007ffc`cdd5825a 48895720 mov qword ptr [rdi + 20h],rdx;设置teb-> fiberdata

检查TEB结构,我们发现*(rdi + 0x17ee)引用的单词实际上代表了该过程中不同功能的位标志。

0:000> dt nt!_tebntdll!_teb + 0x17ee sametebflags:uint2b + 0x17ee safethunkcall:pos 0,1位+ 0x17ee indebugprett:pos 1,1位+ 0x17ee hasfiberdata:pos 2,1 bit; "或word ptr [rdi + 17eeh],4"将其设置为True + 0x17ee SkipthreaTach:POS 3,1位+ 0x17ee WerInshipAstCode:POS 4,1位+ 0x17EE RanProcessInit:POS 5,1位+ 0x17ee ClonedThread:POS 6,1位+ 0x17ee SuppressDebugMSG:POS 7,1位+ 0x17ee disableSertackWalk:POS 8,1比特+ 0x17EE rttlexceptionattached:pos 9,1 bit + 0x17ee initialThread:POS 10,1位+ 0x17ee SessawAware:POS 11,1位+ 0x17ee Loadowner:POS 12,1位+ 0x17ee LoaderWorker:POS 13 ,1位+ 0x17ee skiploaderInit:POS 14,1位+ 0x17ee Sparesametebbits:POS 15,1位

我们还可以看到*(rdi + 0x20)引用的qword ptr是过程中的光纤指针; tib。

Warning: Can only detect less than 5000 characters