ke vinsID:iiprogram
1157103次访问,排名19好友0人,关注者49
残云收夏暑,新雨带秋岚!
[加为好友] [即时聊天] [发私信]
iiprogram的文章
原创 1354 篇
翻译 0 篇
转载 1238 篇
评论 344 篇
Kevins的公告
    留言


自2005年07月20日

Kevins的聯係方式:
unix@yiii.net


天氣預報


最近评论
山东啥:你好 下载已经失效了 可以再提供吗?
山东啥:你好 下载已经失效了 可以再提供吗?
山东啥:你好 下载已经失效了 可以再提供吗?
ZeroChou:Kernel driver? 第一次看到这种插DLL的方法。
ZeroChou:Kevins, 您好, 我是这方面的新手, 有些问题不明白,为什么要用这种方式来找API的地址,直接用LoadLibrary和GetProcAddress不可以吗,是不是为了防止被AV查杀?
文章分类
收藏
相册
1
test
美女
*NUX技术
delphij
hitbsecconf2005
knoppix-std
linux admin
linuxsir
LWN.net
最爱chinaunix
HOT SITES
cnbeta
et8论坛
eyeos 中文
ntdebugging
rootkit
taiwan.cnet
techeblog
web代理
三联生活周刊
中国传统节日
中日文翻译
国学网
深度
看雪学院
驱动开发网
编程技术和代码下载
80x86 Opcodes
awarenetwork
bo2k-plugins
borland update site
C++/C电子书籍
c++builder 研究
chinaaspx文档
code source
codecomments
codeguru
codegurus
codeproject
coffee个人
cprogramming
crack-warez
CrackZ's Reverse Engineering
csdn
csdnbbs文档简易
dd调试技巧代码
debugman
delphi盒子
dephi goo site
diybl
Doron Holan's Blog: Kernel-Mode Drivers
driverdevelop
driverdevsite
electronicstalk_driver
EliCZ
ext2fsd
Flier's Sky
FWB
icode
itconsult_vc
jiurl系统研究
kernel resource
kernel source
kernel-mode development link
krugle.com
LCC
lookcode
mad hook api
mfc
Michael Howard's Web Log
ms_srv protocol
msdn magazine
network code
newhua_deve
ntkernel.com
osronline
pcvc
planet-source-code
putty code
reactos
RECON
reverse-engineering
shadowgo 个人blog
smartphone开发
sockaddr.com
Source Code Search Engine
tty64
tutorialdownloads
txakynetwork(driver,firewall)
undocumented.ntinternals
uty oldblog(driver&kernel)
vbs脚本
vccode
VCFORGE
vchelp
vckbase
vc-qq
vczx
vc原动力
vc原动力
vc在线
wasm.ru
webcrazyjp
Windows network services internals
世纪站长
中国站长源码
免费ie代理1
免费代理2
拼搏
操作系统开发研究
服务器开发技术
源代码
源代码下载2
电子书
编程网摘
藏鲸阁
豆豆源码
個人輔站
another blog?
个人blog-3
人气第一的台湾小美女
個人blog
個人技術輔2
资料blog
软件工具下载
0DAY 下载
0DAY-ART
chinaitpwo资料
flash下载
icwin资料
infoxa
MYEBOOK.CN
scitech.susx
soft8
source520
tooooold_searcj
torrentreactor.net
VCBOOK
xpbook
卡饭
文学ebook
核心编程
水电
源码天空
绿色下载
计算机与信息技术杂志
超好电子书籍站
非凡绿色下载
高校教材
硬件系统
hri.sourceforge.net
juniper mannel
资讯安全国内站
艾克索夫實驗室
0GINR
0ginr
0ginr论坛
51tiger.com安全
5eCur!ty Labs
5iliby
6code
77169
aloner
Alter's home page
antiprotect
astalavista
axis#ph4nt0m BLOG
ayarei/
bluehack
c.i.s.r.t
chinafe
CISRT
cncert
cto技术圈-ddos
cvcvxk
darkshell
debugman
debugman_wintools
dm-0day
dummy24
enet安全
eva
FCG
flowercode
FreeWin
friend-hsy
greatdong
h31home
H4x0r's Blog
hackee
heifou team
http://hi.baidu.com/yuange1975
huaidan's blog
icylife
inkings
insigma
internet worm
isip.cn
Juniper-bbs
kendivblog
KIJS
lenmo
loveshell
loveshell
luoluo
LYSOFT
lzx
majun 's blog
micropoint
mj0011
n4ry
NCPh
ne365-virus
neeao's blog
neeao's millow exp
Nethackonline 网络黑客在线
nop
nosec.org
open-bug
open-bug
PANTAO
raystyle
redhyphone union
regeliu
regshot
sometips
sudami
sysadmin.cn
System Repair Engineer安全检测
System Repair Engineer安全检测
T4NK's blog
team509
techtarget中文
TINK'S BLOG
unpack
unpackcn
uuty
vfocus
vxk
vxk大侠
Windows PowerShell及微软脚本
windowssky
xizi1023 blog
xwind
yiming 管理
yunshu-blog
ZUOJIE
zwell
一蓑烟雨
东来blog
中国x黑客小组
中国信息安全研究小组(CISRG)
中国信息安全组织
中国协议分析网
中国安全信息网-企业安全方案
从c开始
冷漠blog
刘涛涛blog
华夏同盟bbs
南域剑盟
危特网安
大牛蛙
安 翼 网 络
安全中国(RSS)
安全警戒
幻影
当下放下
影子鹰安全
微点blog
成都黑客在线
攻防blog
木马帝国
武汉黑客联盟
源码网
溢出专题study
白细胞
立华软件园安全防线
第八个男人
网安俱乐部
网络安全日志
艾克索夫實驗室.
补天
邪恶八进制
邪恶八进制
邪恶的hackza镜像
邪恶的oldexp
陆麟的主页
飞花堂
鬼仔blog
黑客百宝箱
資訊安全国外站
(kernel,virus code)
0DAY
158apps
62nds virus source
62nds-virus-code
advdbg.com
alexfedoto
allife(RSS)
Alter.Org.UA
anticode(RSS)
antirootkit
ANTIrootkit
ANYSIDE-EXP
anyside-exploit
arteam
astalavista.com
auscert
bifrost
bjwever
Black Hats Manual Software Security Auditing, Cracking,
blackcode.com(RSS)
blackhat mirror
blacksecurity
blogs.borland
bluemicro.digibase
bugtraq
bugtraq2
cert.org
chasenet.org-birfost
codebreakers-journal
community.reverse-engineering
Computer Forensics
computerterrorism
cool linux hack tool site
crackserver
CrackZ's Reverse Engineering
CVC电脑病毒
dark it sec
defcon
determina
dkcs security
DOXARA
eeye_0day_tra
eggheadcafe
elicz
elitehackers
elitehaven
European Hacker Conference
EVA的回收站
Evilcry
Expcode
exploit-1
exploitdatabase
foro.elhacke
Fortinet Security Research Team(RSS)
fredeyk
freexploit
freon-security
frsirt(RSS)
f-secure.weblog
Full Disclosure
full-disclosure
full-disclosure
gmc9
gmer
governmentsecurity(RSS)
h4cky0u
hackcoza
hackerscenter(RSS)
hackersclub
hackersplayground
hackwire(RSS)
haking.pl
he4dev
heapoverflow(RSS)
hexview
hick.org
hitbsecconf
hi-tech.nsys
hsc.fr(RSS)
icst.org.tw(RSS)
igniteds
infosecdaily
infosecwriters
infosyssec
insecure.org
internals
invisiblethings
jav.ch(RSS)
jeffrey.vanderstad
kd-team
l33tsecurity
labs.idefense
lcamtuf.coredump
malware analyze & reverse engineering
Mark Russinovich blog(cool)
markrussinovich
MC AV-Test site
Memory Forensic
metasploit-SHELLCODE(RSS)
microsoft安全(RSS)
milw0rm-shellcode(RSS)
MSDN杂志
msuiche
mtaulty(RSS)
mwcollect
nessus
nessus_plugin
net-security
net-security
network-file-explorers
networksecurityarchive(cool)
neworder.box.sk
neworder.box.sk
ngssoftware(RSS)
nirsoft
niscc.gov.uk(RSS)
NIST
nmd-labs
nnove-exploits
northsecuritylabs
noxusfiles
ntbugtraq
ntcore
nteam.ru
ntsecurity
Obsidis
offensivecomputing
offensivecomputing
omcd
only4gurus
Open Source Vulnerability Database
opennet.ru-exp
openrce(RSS)
openrce
openrce-articles
opensc
open-security
opferman
osvdb
packetstorm(RSS)
phenoelit.de
progenic
pulltheplug
PWDUMP6
Raymond Chen(msdn)
RECON
remoteassessment-exploit-file
remote-exploit
Reverse Compilation Techniques
reverse engineering team
ring 0 debugger
rootkit.com
rootkitunhooker(unreal)
ruder.cdut
RUS-CERT
s0ftpj.org
sabre-security
sabre-security
sec-consult(RSS)
seclist-fulldisclosure
secunia.com
secunia.com
secureworks
secureworks
securiteam
security.ittoolbox
security.nnov.ru
security.org.sg-code
securityarchitects
security-briefings
securitycatalyst(RSS)
securitydot-exploit
securityfocus(RSS)
securityforest
securitylab.ru
security-protocols(RSS)
securityreasonExploitAlert
securitysearch.net
securitytracker
sensepost
spywareinfo
Stanford's stinson
SUCK-O
sweRAT
sysinternals forum
taosecurity
taosecurity.blogspot(cool)
techmeme
techmeme.
tenablesecurity
THC(RSS)
thc.org
The 20 Most Critical Internet Security Vulnerabilities
the Month of Kernel Bugs
The Open Source Vulnerability Database
theaimsgroup bug
thebugs.ws
thenetworksecurity
tibbar(RSS)
tibbar
tippingpoint
topix-tech
triviasecurity
undergroundnews(RSS)
undocumented
undocumented.ntinternals
uninformed
uninformed
uninformed
uninformed.org
US-CERT
virustotal detect
vuln-search
VX Heavens
wd-3(RSS)
websense
WebSense Security Labs
whitehat
wilderssecurity
Win NT, Win 2000, and Win XP Security Tips
Windows network services internals
windowsecurity(RSS)
WOODMANN
woodmann.com
xatrix.org
xzziroz
yorn security
ZDNET_security
zdnet's security
zero day (RSS)
zone-h
zone-h.
反汇编引擎distorm
最新被黑站点
查询windows不明进程
汇编引擎yasm
经典phrack(RSS)
经典ussrback(RSS)
存档
订阅我的博客
XML聚合  FeedSky

原创 线程调度的部分资料收藏

新一篇: shellcode 之 JMP ESP 与 JMP EBX  | 旧一篇: Recognizer & FS & Filter

PART 1: Kernel Object

//每一位表示对应这个特权级的队列中是否有线程(主要在KiSwapThread用,详细代码见PART3) ULONG KiReadySummary = 0 

 - Referenced by KeSetAffinityThread(),KiFindReadyThread(),KiReadyThread(),    KiScanReadyQueues(),  KiSetPriorityThread(), and NtYieldExecution().

// LIST_ENTRY  KeBugCheckCallbackListHead

// LIST_ENTRY KiDispatcherReadyListHead[MAXIMUM_PRIORITY] 

  - Referenced by KeSetAffinityThread(), KiFindReadyThread(), KiInitSystem(),     KiReadyThread(), KiScanReadyQueues(), KiSetPriorityThread(),     and NtYieldExecution().

// LIST_ENTRY KiProfileListHead 

  - Referenced by KeStartProfile(), and KiInitSystem().

LIST_ENTRY KiProfileSourceListHead 

  - Referenced by KeStartProfile(), KeStopProfile(), and KiInitSystem().

// LIST_ENTRY KiProcessOutSwapListHead 

  - Referenced by KeDetachProcess(), KeSwapProcessOrStack(), KeTerminateThread(),     KeUnstackDetachProcess(), KiInitSystem(), KiOutSwapKernelStacks(), and     KiOutSwapProcesses().

LIST_ENTRY KiProcessInSwapListHead 

  - Referenced by KeSwapProcessOrStack(), KiAttachProcess(), KiInitSystem(),      KiInSwapProcesses(), KiOutSwapProcesses(), and KiReadyThread().

 

LIST_ENTRY KiStackInSwapListHead 

  - Referenced by KeSwapProcessOrStack(), KiInitSystem(), KiInSwapKernelStacks(),     and KiReadyThread().

// LIST_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE] 

  - Referenced by KeCheckForTimer(), KeSetSystemTime(), KiInitSystem(),     KiInsertTimerTable(), KiTimerExpiration(), and VerifierKeInitializeTimerEx().

 

// LIST_ENTRY KiWaitInListHead 

  - Referenced by KiInitSystem(), and KiOutSwapKernelStacks().

LIST_ENTRY KiWaitOutListHead 

  - Referenced by KiInitSystem(), and KiOutSwapKernelStacks().

 

 

PART 2: Kernel Object of KPROCESS

LIST_ENTRY _KPROCESS::ThreadListHead     - Referenced by ExpGetProcessInformation(), KeDetachProcess(), KeFreezeAllThreads(),      KeTerminateThread(), KeThawAllThreads(), and KeUnstackDetachProcess().

 

LIST_ENTRY _KPROCESS::SwapListEntry 

  - Referenced by KeDetachProcess(), KeTerminateThread(), KeUnstackDetachProcess(),     KiOutSwapKernelStacks(), KiOutSwapProcesses(), and KiReadyThread().

 

LIST_ENTRY _KPROCESS::ReadyListHead 

  - Referenced by KiInSwapProcesses(), KiOutSwapProcesses(), and KiReadyThread().

 

PART 3:

/*------------------------- MmInitSystem -------------------------

- MmInitSystem启动两个线程: KeBalanceSetManager 和 KeSwapProcessOrStack;

- 平衡集管理器(balance set manager)

- 交换管理器(KeSwapProcessOrStack)

- 其实它还启动了MiModifiedPageWriter(将某些页面置入pagefile中)

-----------------------------------------------------------------*/ 01337         // 01338         // Start the modified page writer. 01339         // 01340 01341         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL ); 01342 01343         if (!NT_SUCCESS(PsCreateSystemThread( 01344                         &ThreadHandle, 01345                         THREAD_ALL_ACCESS, 01346                         &ObjectAttributes, 01347                         0L, 01348                         NULL, 01349                         MiModifiedPageWriter, 01350                         NULL 01351                         ))) { 01352             return FALSE; 01353         } 01354         ZwClose (ThreadHandle); 01355 01356         // 01357         // Start the balance set manager. 01358         // 01359         // The balance set manager performs stack swapping and working 01360         // set management and requires two threads. 01361         // 01362 01363         KeInitializeEvent (&MmWorkingSetManagerEvent, 01364                            SynchronizationEvent, 01365                            FALSE); 01366 01367         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL ); 01368 01369         if (!NT_SUCCESS(PsCreateSystemThread( 01370                         &ThreadHandle, 01371                         THREAD_ALL_ACCESS, 01372                         &ObjectAttributes, 01373                         0L, 01374                         NULL, 01375                         KeBalanceSetManager, 01376                         NULL 01377                         ))) { 01378 01379             return FALSE; 01380         } 01381         ZwClose (ThreadHandle); 01382 01383         if (!NT_SUCCESS(PsCreateSystemThread( 01384                         &ThreadHandle, 01385                         THREAD_ALL_ACCESS, 01386                         &ObjectAttributes, 01387                         0L, 01388                         NULL, 01389                         KeSwapProcessOrStack, 01390                         NULL 01391                         ))) { 01392 01393             return FALSE; 01394         }

 

 

/*---------------------- KeBalanceSetManager ---------------------

-  KeBalanceSetManager也一直循环着并等待着一个MmWorkingSetManagerEvent事件 (当内存低时调整工作集的大小)和另一个定时器.

-  定时器事件处理程序周期性地将KiStackOutSwapRequest设置为TRUE, 并且触发KiSwapEvent信号通知KeSwapProcessOrStack线程, KeSwapProcessOrStack线程 不得不将长时间等待某个东西的线程的内核堆栈交换出去.

-  KeBalanceSetManager也调用KiScanReadyQueues 来提高在就绪队列中线程(KiDispatcherReadyListHead数组)的优先级.

-  对于每一个提高了优先级的线程, KiReadyThread将会被调用, 所以马上将PRCB.NextThread设置为提高了优先级的线程也是很有可能的 (KiReadyThread 会抢占原先的NextThread).

-----------------------------------------------------------------*/

00141 VOID 00142 KeBalanceSetManager ( 00143     IN PVOID Context 00144     ) 00145 00146 /*++ 00147 00148 Routine Description: 00149 00150     This function is the startup code for the balance set manager. The 00151     balance set manager thread is created during system initialization 00152     and begins execution in this function. 00153 00154 Arguments: 00155 00156     Context - Supplies a pointer to an arbitrary data structure (NULL). 00157 00158 Return Value: 00159 00160     None. 00161 00162 --*/ 00163 00164 { 00165 00166     LARGE_INTEGER DueTime; 00167     KTIMER PeriodTimer; 00168     KIRQL OldIrql; 00169     ULONG StackScanPeriod; 00170     ULONG ExecutionTimeLimitPeriod; 00171     NTSTATUS Status; 00172     KWAIT_BLOCK WaitBlockArray[MaximumObject]; 00173     PVOID WaitObjects[MaximumObject]; 00174 00175     // 00176     // Raise the thread priority to the lowest realtime level. 00177     // 00178 00179     KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); 00180 00181     // 00182     // Initialize the periodic timer, set it to expire one period from 00183     // now, and set the stack scan period. 00184     // 00185 00186     KeInitializeTimer(&PeriodTimer); 00187     DueTime.QuadPart = - PERIODIC_INTERVAL; 00188     KeSetTimer(&PeriodTimer, DueTime, NULL); 00189     StackScanPeriod = STACK_SCAN_PERIOD; 00190     ExecutionTimeLimitPeriod = EXECUTION_TIME_LIMITS_PERIOD; 00191     // 00192     // Compute the stack protect time based on the system size. 00193     // 00194 00195     if (MmQuerySystemSize() == MmSmallSystem) { 00196         KiStackProtectTime = SMALL_SYSTEM_STACK_PROTECT_TIME; 00197 00198     } else { 00199         KiStackProtectTime = STACK_PROTECT_TIME; 00200     } 00201 00202     // 00203     // Initialize the wait objects array. 00204     // 00205 00206     WaitObjects[TimerExpiration] = (PVOID)&PeriodTimer; 00207     WaitObjects[WorkingSetManagerEvent] = (PVOID)&MmWorkingSetManagerEvent; 00208 00209     // 00210     // Loop forever processing balance set manager events. 00211     // 00212 00213     do { 00214 00215         // 00216         // Wait for a memory management memory low event, a swap event, 00217         // or the expiration of the period timout rate that the balance 00218         // set manager runs at. 00219         // 00220 00221         Status = KeWaitForMultipleObjects(MaximumObject, 00222                                           &WaitObjects[0], 00223                                           WaitAny, 00224                                           Executive, 00225                                           KernelMode, 00226                                           FALSE, 00227                                           NULL, 00228                                           &WaitBlockArray[0]); 00229 00230         // 00231         // Switch on the wait status. 00232         // 00233 00234         switch (Status) { 00235 00236             // 00237             // Periodic timer expiration. 00238             // 00239 00240         case TimerExpiration: 00241 00242             // 00243             // Attempt to initiate outswaping of kernel stacks. 00244             // 00245 00246             StackScanPeriod -= 1; 00247             if (StackScanPeriod == 0) { 00248                 StackScanPeriod = STACK_SCAN_PERIOD; 00249                 KiLockDispatcherDatabase(&OldIrql); 00250                 if (KiStackOutSwapRequest == FALSE) { 00251                     KiStackOutSwapRequest = TRUE; 00252                     KiUnlockDispatcherDatabase(OldIrql); 00253                     KeSetEvent(&KiSwapEvent, 0, FALSE); 00254 00255                 } else { 00256                     KiUnlockDispatcherDatabase(OldIrql); 00257                 } 00258             } 00259 00260             // 00261             // Adjust the depth of lookaside lists. 00262             // 00263 00264             ExAdjustLookasideDepth(); 00265 00266             // 00267             // Scan ready queues and boost thread priorities as appropriate. 00268             // 00269 00270             KiScanReadyQueues(); 00271 00272             // 00273             // Execute the virtual memory working set manager. 00274             // 00275 00276             MmWorkingSetManager(); 00277 00278             // 00279             // Enforce execution time limits 00280             // 00281 00282             ExecutionTimeLimitPeriod -= 1; 00283             if (ExecutionTimeLimitPeriod == 0) { 00284                 ExecutionTimeLimitPeriod = EXECUTION_TIME_LIMITS_PERIOD; 00285                 PsEnforceExecutionTimeLimits(); 00286                 } 00287 00288             // 00289             // Set the timer to expire at the next periodic interval. 00290             // 00291 00292             KeSetTimer(&PeriodTimer, DueTime, NULL); 00293             break; 00294 00295             // 00296             // Working set manager event. 00297             // 00298 00299         case WorkingSetManagerEvent: 00300 00301             // 00302             // Call the working set manager to trim working sets. 00303             // 00304 00305             MmWorkingSetManager(); 00306             break; 00307 00308             // 00309             // Illegal return status. 00310             // 00311 00312         default: 00313             KdPrint(("BALMGR: Illegal wait status, %lx =\n", Status)); 00314             break; 00315         } 00316 00317     } while (TRUE); 00318     return; 00319 }

 

 

/*---------------------- KeSwapProcessOrStack ---------------------

-  将内核堆栈交换出去(由BOOLEAN KiStackOutSwapRequest指定) -  将进程交换出去 (需要交换出去的进程存放在KiProcessOutSwapListHead中) -  将进程交换进来  (需要交换出去的进程存放在KiProcessInSwapListHead中) -  将内核堆栈交换进来(需要交换进来的线程存放在KiStackInSwapListHead中).

-----------------------------------------------------------------*/

00321 VOID 00322 KeSwapProcessOrStack ( 00323     IN PVOID Context 00324     ) 00325 00326 /*++ 00327 00328 Routine Description: 00329 00330     This thread controls the swapping of processes and kernel stacks. The 00331     order of evaluation is: 00332 00333         Outswap kernel stacks 00334         Outswap processes 00335         Inswap processes 00336         Inswap kernel stacks 00337 00338 Arguments: 00339 00340     Context - Supplies a pointer to the routine context - not used. 00341 00342 Return Value: 00343 00344     None. 00345 00346 --*/ 00347 00348 { 00349 00350     KIRQL OldIrql; 00351     NTSTATUS Status; 00352 00353     // 00354     // Raise the thread priority to the lowest realtime level + 7 (i.e., 00355     // priority 23). 00356     // 00357 00358     KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY + 7); 00359 00360     // 00361     // Loop for ever processing swap events. 00362     // 00363 00364     do { 00365 00366         // 00367         // Wait for a swap event to occur. 00368         // 00369 00370         Status = KeWaitForSingleObject(&KiSwapEvent, 00371                                        Executive, 00372                                        KernelMode, 00373                                        FALSE, 00374                                        NULL); 00375 00376         // 00377         // Raise IRQL to dispatcher level and lock dispatcher database. 00378         // 00379 00380         KiLockDispatcherDatabase(&OldIrql); 00381 00382         // 00383         // Loop until all of the four possible actions cannot be initiated. 00384         // 00385 00386         do { 00387 00388             // 00389             // If a request has been made to out swap kernel stacks, then 00390             // attempt to outswap kernel stacks. Otherwise, if the process 00391             // out swap list is not empty, then initiate process outswapping. 00392             // Otherwise, if the process inswap list is not empty, then start 00393             // process inswapping. Otherwise, if the kernal stack inswap list 00394             // is not active, then initiate kernel stack inswapping. Otherwise, 00395             // no work is available. 00396             // 00397 00398             if (KiStackOutSwapRequest != FALSE) { 00399                 KiStackOutSwapRequest = FALSE; 00400                 KiOutSwapKernelStacks(OldIrql); 00401                 continue; 00402 00403             } else if (IsListEmpty(&KiProcessOutSwapListHead) == FALSE) { 00404                 KiOutSwapProcesses(OldIrql); 00405                 continue; 00406 00407             } else if (IsListEmpty(&KiProcessInSwapListHead) == FALSE) { 00408                 KiInSwapProcesses(OldIrql); 00409                 continue; 00410 00411             } else if (IsListEmpty(&KiStackInSwapListHead) == FALSE) { 00412                 KiInSwapKernelStacks(OldIrql); 00413                 continue; 00414 00415             } else { 00416                 break; 00417             } 00418         } while (TRUE); 00419 00420         // 00421         // Unlock the dispatcher database and lower IRQL to its previous 00422         // value. 00423         // 00424 00425         KiUnlockDispatcherDatabase(OldIrql); 00426     } while (TRUE); 00427     return; 00428 }

 

 

/*------------------------ KiSwapThread -------------------------

-----------------------------------------------------------------*/ ;++ ; ; VOID ; KiSwapThread ( ;    VOID ;    ) ; ; Routine Description: ; ;    This routine is called to select the next thread to run on the ;    current processor and to perform a context switch to the thread. ; ; Arguments: ; ;    None. ; ; Return Value: ; ;    Wait completion status (eax). ; ;--

cPublicFastCall KiSwapThread, 0 .fpo (0, 0, 0, 4, 1, 0)

; ; N.B. The following registers MUST be saved such that ebp is saved last. ;      This is done so the debugger can find the saved ebp for a thread ;      that is not currently in the running state. ;

        sub     esp, 4*4         mov     [esp+12], ebx           ; save registers         mov     [esp+8], esi            ;         mov     [esp+4], edi            ;         mov     [esp+0], ebp            ;

        mov     ebx, PCR[PcSelfPcr]     ; get address of PCR         mov     edx, [ebx].PcPrcbData.PbNextThread ; get next thread address         or      edx, edx                ; check if next thread selected         jnz     Swt140                  ; if nz, next thread selected

; ; Find the highest nibble in the ready summary that contains a set bit ; and left justify so the nibble is in bits <31:28> ;

        mov     ecx, 16                 ; set base bit number         mov     edi, _KiReadySummary    ; get ready summary         mov     esi, edi                ; copy ready summary         shr     esi, 16                 ; isolate bits <31:16> of summary         jnz     short Swt10             ; if nz, bits <31:16> are nonzero         xor     ecx, ecx                ; set base bit number         mov     esi, edi                ; set bits <15:0> of summary Swt10:  shr     esi, 8                  ; isolate bits <15:8> of low bits         jz      short Swt20             ; if z, bits <15:8> are zero         add     ecx, 8                  ; add offset to nonzero byte Swt20:  mov     esi, edi                ; isolate highest nonzero byte         shr     esi, cl                 ;         add     ecx, 3                  ; adjust to high bit of nibble         cmp     esi, 10h                ; check if high nibble nonzero         jb      short Swt30             ; if b, then high nibble is zero         add     ecx, 4                  ; compute ready queue priority Swt30:  mov     esi, ecx                ; left justify ready summary nibble         not     ecx                     ;         shl     edi, cl                 ;         or      edi, edi                ;

; ; If the next bit is set in the ready summary, then scan the corresponding ; dispatcher ready queue. ;

Swt40:  js      short Swt60             ; if s, queue contains an entry Swt50:  sub     esi, 1                  ; decrement ready queue priority         shl     edi, 1                  ; position next ready summary bit         jnz     short Swt40             ; if nz, more queues to scan

; ; If the next bit is set in the ready summary, then scan the corresponding ; dispatcher ready queue. ;

Swt40:  js      short Swt60             ; if s, queue contains an entry Swt50:  sub     esi, 1                  ; decrement ready queue priority         shl     edi, 1                  ; position next ready summary bit         jnz     short Swt40             ; if nz, more queues to scan

posted on 2007-08-23 17:28 垃圾一堆 阅读(2109) 评论(1)  编辑 收藏
Comments
  • 垃圾一堆 Posted @ 2007-08-27 11:18

    00188 typedef enum _KTHREAD_STATE { 00189     Initialized, 00190     Ready, 00191     Running, 00192     Standby, 00193     Terminated, 00194     Waiting, 00195     Transition 00196     } KTHREAD_STATE; //PS:Transition(转换状态)      处于此状态的线程的内核堆栈不在内存中;      Insert KiStackInSwapListHead 等待平衡集管理器 通知 交换管理器 进行换进动作;

    //一般情况下线程处于等待状态,是因为等待的内核对象(当然是可等待对象含有DISPATCH_HEAD & WaitBlock)还未触发;  如果触发了,线程从等待状态 切换的到 准备状态;下面这几个函数实现了这个功能; /*------------------------   KeSetEvent --------------------------

    -----------------------------------------------------------------*/

    00343 KeSetEvent ( 00344     IN PRKEVENT Event, 00345     IN KPRIORITY Increment, 00346     IN BOOLEAN Wait 00347     ) 00348 00349 /*++ 00350 00351 Routine Description: 00352 00353     This function sets the signal state of an event object to Signaled 00354     and attempts to satisfy as many Waits as possible. The previous 00355     signal state of the event object is returned as the function value. 00356 00357 Arguments: 00358 00359     Event - Supplies a pointer to a dispatcher object of type event. 00360 00361     Increment - Supplies the priority increment that is to be applied 00362        if setting the event causes a Wait to be satisfied. 00363 00364     Wait - Supplies a boolean value that signifies whether the call to 00365        KePulseEvent will be immediately followed by a call to one of the 00366        kernel Wait functions. 00367 00368 Return Value: 00369 00370     The previous signal state of the event object. 00371 00372 --*/ 00373 00374 { 00375 00376     KIRQL OldIrql; 00377     LONG OldState; 00378     PRKTHREAD Thread; 00379     PRKWAIT_BLOCK WaitBlock; 00380 00381     ASSERT_EVENT(Event); 00382     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00383 00384     // 00385     // Collect call data. 00386     // 00387 00388 #if defined(_COLLECT_SET_EVENT_CALLDATA_) 00389 00390     RECORD_CALL_DATA(&KiSetEventCallData); 00391 00392 #endif 00393 00394     // 00395     // Raise IRQL to dispatcher level and lock dispatcher database. 00396     // 00397 00398     KiLockDispatcherDatabase(&OldIrql); 00399 00400     // 00401     // If the wait list is empty, then set the state of the event to signaled. 00402     // Otherwise, check if the wait can be satisfied immediately. 00403     // 00404 00405     OldState = Event->Header.SignalState; 00406     if (IsListEmpty(&Event->Header.WaitListHead) != FALSE) { 00407         Event->Header.SignalState = 1; 00408 00409     } else { 00410 00411         // 00412         // If the event is a notification event or the wait is not a wait any, 00413         // then set the state of the event to signaled and attempt to satisfy 00414         // as many waits as possible. Otherwise, the wait can be satisfied by 00415         // directly unwaiting the thread. 00416         // 00417 00418         WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, 00419                                       KWAIT_BLOCK, 00420                                       WaitListEntry); 00421 00422         if ((Event->Header.Type == NotificationEvent) || 00423             (WaitBlock->WaitType != WaitAny)) { 00424             if (OldState == 0) { 00425                 Event->Header.SignalState = 1; 00426                 KiWaitTest(Event, Increment); 00427             } 00428 00429         } else { 00430             KiUnwaitThread(WaitBlock->Thread, (NTSTATUS)WaitBlock->WaitKey, Increment); 00431         } 00432     } 00433 00434     // 00435     // If the value of the Wait argument is TRUE, then return to the 00436     // caller with IRQL raised and the dispatcher database locked. Else 00437     // release the dispatcher database lock and lower IRQL to its 00438     // previous value. 00439     // 00440 00441     if (Wait != FALSE) { 00442        Thread = KeGetCurrentThread(); 00443        Thread->WaitNext = Wait; 00444        Thread->WaitIrql = OldIrql; 00445 00446     } else { 00447        KiUnlockDispatcherDatabase(OldIrql); 00448     } 00449 00450     // 00451     // Return previous signal state of event object. 00452     // 00453 00454     return OldState; 00455 }

     

    /*------------------------ KiUnwaitThread-------------------------

    -----------------------------------------------------------------*/

    00029 VOID 00030 FASTCALL 00031 KiUnwaitThread ( 00032     IN PRKTHREAD Thread, 00033     IN LONG_PTR WaitStatus, 00034     IN KPRIORITY Increment 00035     ) 00036 00037 /*++ 00038 00039 Routine Description: 00040 00041     This function unwaits a thread, sets the thread's wait completion status, 00042     calculates the thread's new priority, and readies the thread for execution. 00043 00044 Arguments: 00045 00046     Thread - Supplies a pointer to a dispatcher object of type thread. 00047 00048     WaitStatus - Supplies the wait completion status. 00049 00050     Increment - Supplies the priority increment that is to be applied to 00051         the thread's priority. 00052 00053 Return Value: 00054 00055     None. 00056 00057 --*/ 00058 00059 { 00060 00061     KPRIORITY NewPriority; 00062     PKPROCESS Process; 00063     PKQUEUE Queue; 00064     PKTIMER Timer; 00065     PRKWAIT_BLOCK WaitBlock; 00066 00067     // 00068     // Set wait completion status, remove wait blocks from object wait 00069     // lists, and remove thread from wait list. 00070     // 00071 00072     Thread->WaitStatus |= WaitStatus; 00073     WaitBlock = Thread->WaitBlockList; 00074     do { 00075         RemoveEntryList(&WaitBlock->WaitListEntry); 00076         WaitBlock = WaitBlock->NextWaitBlock; 00077     } while (WaitBlock != Thread->WaitBlockList); 00078 00079     RemoveEntryList(&Thread->WaitListEntry); 00080 00081     // 00082     // If thread timer is still active, then cancel thread timer. 00083     // 00084 00085     Timer = &Thread->Timer; 00086     if (Timer->Header.Inserted != FALSE) { 00087         KiRemoveTreeTimer(Timer); 00088     } 00089 00090     // 00091     // If the thread is processing a queue entry, then increment the 00092     // count of currently active threads. 00093     // 00094 00095     Queue = Thread->Queue; 00096     if (Queue != NULL) { 00097         Queue->CurrentCount += 1; 00098     } 00099 00100     // 00101     // If the thread runs at a realtime priority level, then reset the 00102     // thread quantum. Otherwise, compute the next thread priority and 00103     // charge the thread for the wait operation. 00104     // 00105 00106     Process = Thread->ApcState.Process; 00107     if (Thread->Priority < LOW_REALTIME_PRIORITY) { 00108         if ((Thread->PriorityDecrement == 0) && 00109             (Thread->DisableBoost == FALSE)) { 00110             NewPriority = Thread->BasePriority + Increment; 00111             if (((PEPROCESS)Process)->Vm.MemoryPriority == MEMORY_PRIORITY_FOREGROUND) { 00112                 NewPriority += PsPrioritySeperation; 00113             } 00114 00115             if (NewPriority > Thread->Priority) { 00116                 if (NewPriority >= LOW_REALTIME_PRIORITY) { 00117                     Thread->Priority = LOW_REALTIME_PRIORITY - 1; 00118 00119                 } else { 00120                     Thread->Priority = (SCHAR)NewPriority; 00121                 } 00122             } 00123         } 00124 00125         if (Thread->BasePriority >= TIME_CRITICAL_PRIORITY_BOUND) { 00126             Thread->Quantum = Process->ThreadQuantum; 00127 00128         } else { 00129             Thread->Quantum -= WAIT_QUANTUM_DECREMENT; 00130             if (Thread->Quantum <= 0) { 00131                 Thread->Quantum = Process->ThreadQuantum; 00132                 Thread->Priority -= (Thread->PriorityDecrement + 1); 00133                 if (Thread->Priority < Thread->BasePriority) { 00134                     Thread->Priority = Thread->BasePriority; 00135                 } 00136 00137                 Thread->PriorityDecrement = 0; 00138             } 00139         } 00140 00141     } else { 00142         Thread->Quantum = Process->ThreadQuantum; 00143     } 00144 00145     // 00146     // Reready the thread for execution. 00147     // 00148 00149     KiReadyThread(Thread); 00150     return; 00151 }

     

     

    /*------------------------ KiReadyThread -------------------------

    -----------------------------------------------------------------*/

    00268 VOID 00269 FASTCALL 00270 KiReadyThread ( 00271     IN PRKTHREAD Thread 00272     ) 00273 00274 /*++ 00275 00276 Routine Description: 00277 00278     This function readies a thread for execution and attempts to immediately 00279     dispatch the thread for execution by preempting another lower priority 00280     thread. If a thread can be preempted, then the specified thread enters 00281     the standby state and the target processor is requested to dispatch. If 00282     another thread cannot be preempted, then the specified thread is inserted 00283     either at the head or tail of the dispatcher ready selected by its priority 00284     acccording to whether it was preempted or not. 00285 00286 Arguments: 00287 00288     Thread - Supplies a pointer to a dispatcher object of type thread. 00289 00290 Return Value: 00291 00292     None. 00293 00294 --*/ 00295 00296 { 00297 00298     PRKPRCB Prcb; 00299     BOOLEAN Preempted; 00300     KPRIORITY Priority; 00301     PRKPROCESS Process; 00302     ULONG Processor; 00303     KPRIORITY ThreadPriority; 00304     PRKTHREAD Thread1; 00305     KAFFINITY IdleSet; 00306 00307     // 00308     // Save value of thread's preempted flag, set thread preempted FALSE, 00309     // capture the thread priority, and set clear the read wait time. 00310     // 00311 00312     Preempted = Thread->Preempted; 00313     Thread->Preempted = FALSE; 00314     ThreadPriority = Thread->Priority; 00315     Thread->WaitTime = KiQueryLowTickCount(); 00316 00317     // 00318     // If the thread's process is not in memory, then insert the thread in 00319     // the process ready queue and inswap the process. 00320     // 00321 00322     Process = Thread->ApcState.Process; 00323     if (Process->State != ProcessInMemory) { 00324         Thread->State = Ready; 00325         Thread->ProcessReadyQueue = TRUE; 00326         InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry); 00327         if (Process->State == ProcessOutOfMemory) { 00328             Process->State = ProcessInTransition; 00329             InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry); 00330             KiSwapEvent.Header.SignalState = 1; 00331             if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00332                 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00333             } 00334         } 00335 00336         return; 00337 00338     } else if (Thread->KernelStackResident == FALSE) { 00339 00340         // 00341         // The thread's kernel stack is not resident. Increment the process 00342         // stack count, set the state of the thread to transition, insert 00343         // the thread in the kernel stack inswap list, and set the kernel 00344         // stack inswap event. 00345         // 00346 00347         Process->StackCount += 1; 00348         Thread->State = Transition; 00349         InsertTailList(&KiStackInSwapListHead, &Thread->WaitListEntry); 00350         KiSwapEvent.Header.SignalState = 1; 00351         if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00352             KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00353         } 00354 00355         return; 00356 00357     } else { 00358 00359         // 00360         // If there is an idle processor, then schedule the thread on an 00361         // idle processor giving preference to the processor the thread 00362         // last ran on. Otherwise, try to preempt either a thread in the 00363         // standby or running state. 00364         // 00365 00366 #if defined(NT_UP) 00367 00368         Prcb = KiProcessorBlock[0]; 00369         if (KiIdleSummary != 0) { 00370             KiIdleSummary = 0; 00371             KiIncrementSwitchCounter(IdleLast); 00372             Prcb->NextThread = Thread; 00373             Thread->State = Standby; 00374 00375 #else 00376 00377         IdleSet = KiIdleSummary & Thread->Affinity; 00378         if (IdleSet != 0) { 00379             Prcb = KeGetCurrentPrcb(); 00380             Processor = Thread->IdealProcessor; 00381             if ((IdleSet & (1 << Processor)) == 0) { 00382                 Processor = Thread->NextProcessor; 00383                 if ((IdleSet & (1 << Processor)) == 0) { 00384                     if ((IdleSet & Prcb->SetMember) == 0) { 00385                         FindFirstSetLeftMember(IdleSet, &Processor); 00386                         KiIncrementSwitchCounter(IdleAny); 00387 00388                     } else { 00389                         Processor = Prcb->Number; 00390                         KiIncrementSwitchCounter(IdleCurrent); 00391                     } 00392 00393                 } else { 00394                     KiIncrementSwitchCounter(IdleLast); 00395                 } 00396 00397             } else { 00398                 KiIncrementSwitchCounter(IdleIdeal); 00399             } 00400 00401             Thread->NextProcessor = (CCHAR)Processor; 00402             ClearMember(Processor, KiIdleSummary); 00403             KiProcessorBlock[Processor]->NextThread = Thread; 00404             Thread->State = Standby; 00405 00406             if ((PoSleepingSummary & (1 << Processor)) && 00407               &nbs