Windows串口调试通信协议KDCOM.DLL的反向分析及Asm和C源代码

前段时间突然兴趣大发,把KDCOM.DLL用IDA进行了分析和阅读,并导出成asm文件,作了修改和编译使之可以编译后替换原先的kdcom.dll正常工作, 这之间最难的莫过于kdcom.dll无法进行调试和跟踪的问题了, 手段非常有限, 我暂时只知道使用一下Vmware的后门I/O port进行一些检测性的LOG,以致使由反向代码编译出的kdom.dll最终能正常工作花费了我极多的时间.

事实上, 由IDA导出的代码要修改的问题并不多,只涉及到以下方面:

1.API函数导入和导出的问题,包括命名和正确链接;

2.代码的区段问题和一些全局绝对址的引用问题,如_KUSER_SHARED_DATA的引用,IDA反编出是这样的 
and byte ptr ds:0FFDF02D4h, 0FDh
事实上必须写成 and byte ptr ds:[0FFDF02D4h], 0FDh
否则Masm32编译生成出问题,VMWARE直接就崩溃.

3.导入变量的地址使用问题,这里是搞了我最多时间的地方,因为,发生这种异常VMWARE直接就出错,结束,郁闷呀.
 类似第2点的问题,
 例如,IDA反编出来的,关于使用KdDebuggerNotPresent这个由ntosknrl.exe导出的符时,语句是这样的

  1.  mov     eax, ds:_KdDebuggerNotPresent
  2.  and     byte ptr [eax], 0


 把_KdDebuggerNotPresent改成KdDebuggerNotPresent编译和链接都没有问题,都一运行VMWARE就直接崩溃.
 事实上应该写成这样的(这个可是花了我无数的时间才发现的,--#):

  1.  mov     eax, dword ptr ds:[KdDebuggerNotPresent]
  2.   and     byte ptr [eax], 0


下面给出可以编译生成正常运行的反向汇编源代码,有三个文件kdcom.Inc,kdcom.def和kdcom.Asm,需要安装RadASM这个IDE来编译.

kdcom.Inc:

 

  1. ;kdcom.Inc
  2. ;
  3. include w2k/ntstatus.inc
  4. include w2k/ntddk.inc
  5. include w2k/ntoskrnl.inc
  6. include w2k/hal.inc
  7. includelib hal.lib
  8. includelib ntoskrnl.lib

 

kdcom.def

  1. EXPORTS
  2.  KdD0Transition          
  3.  KdD3Transition=KdD0Transition 
  4.  KdDebuggerInitialize0      
  5.  KdDebuggerInitialize1      
  6.  KdReceivePacket            
  7.  KdRestore                  
  8.  KdSave                     
  9.  KdSendPacket               

kdcom.Asm:

 

 

 

  1. ;
  2. ; BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  3. ; ?This file is generated by The Interactive Disassembler (IDA)     ?
  4. .686p
  5. .model flat,stdcall
  6. include kdcom.inc
  7. ;
  8. ;import variable 
  9. ;            extrn KdComPortInUse:dword
  10. ;                extrn KdDebuggerNotPresent:dword
  11. ;                extrn HalPrivateDispatchTable:dword
  12. ; Section 2. (virtual address 00000D00)
  13. ; Virtual size          : 0000009C (    156.)
  14. ; Section size in file      : 00000100 (    256.)
  15. ; Offset to raw data for section: 00000D00
  16. ; Flags C8000040: Data Not pageable Readable Writable
  17. ; Alignment : default
  18. ; BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  19. ; Segment type: Pure data
  20. ; Segment permissions: Read/Write
  21. _data       segment para public 'DATA' use32
  22.         
  23. aKdReceivePacket        db 'KdReceivePacket',0Ah,0Dh,0
  24. aKdSendPacket           db 'KdSendPacket',0
  25. aSwitchingDebug         db 'Switching debugger to 9600 baud',0Ah,0 ; DATA XREF: CpReadLsr(x,x)+194o
  26. aDebugport          db 'DEBUGPORT',0        ; DATA XREF: KdDebuggerInitialize0(x)+18o
  27. aBaudrate           db 'BAUDRATE',0         ; DATA XREF: KdDebuggerInitialize0(x)+25o
  28. aCom                db 'COM',0              ; DATA XREF: KdDebuggerInitialize0(x)+3Bo
  29. _KdCompNumberRetries        dd  5       ; DATA XREF: KdReceivePacket(x,x,x,x,x)+51w
  30.                         ; KdSendPacket(x,x,x,x)+54w ...
  31. _KdCompRetryCount       dd  5           ; DATA XREF: KdReceivePacket(x,x,x,x,x)+4Br
  32.                         ; KdSendPacket(x,x,x,x)+3Br ...
  33. _KdCompDbgPortsPresent      db  1       ; DATA XREF: KdRestore(x)+7w
  34.                         ; CpReadLsr(x,x)+34w ...
  35. aPrtOvlFrm          db  20h         ; DATA XREF: CpReadLsr(x,x)+1ACo
  36.                 db  50h ; P
  37.                 db  52h ; R
  38.                 db  54h ; T
  39.                 db  20h
  40.                 db  4Fh ; O
  41.                 db  56h ; V
  42.                 db  4Ch ; L
  43.                 db  20h
  44.                 db  46h ; F
  45.                 db  52h ; R
  46.                 db  4Dh ; M
  47. aAt             db 0Ah          ; DATA XREF: CpReadLsr(x,x)+D5o
  48.                 db 0Dh,'AT',0Ah
  49.                 db 0Dh,0
  50. _Port               dd    0         ; DATA XREF: KdCompGetByte(x)+6o
  51.                     ; KdCompPollByte(x)+6o ...
  52. _com_status_flag        db    1         ; DATA XREF: KdCompRestore()w
  53.                     ; KdCompSave()w ...
  54.                 db    0
  55.                 db    0
  56.                 db    0
  57.                 db    0
  58.                 db    0
  59.                 db    0
  60.                 db    0
  61.                 db    0
  62.                 db    0
  63.                 db    0
  64.                 db    0
  65.                 db    0
  66.                 db    0
  67.                 db    0
  68.                 db    0
  69.                 db    0
  70.                 db    0
  71.                 db    0
  72.                 db    0
  73. _PortInformation        dd 0            ; DATA XREF: KdCompInitialize(x,x)+88w
  74.                     ; KdCompInitialize(x,x):loc_GetSavedPortInfow ...
  75. _ComBaudratePara        dd 0            ; DATA XREF: KdCompInitialize(x,x)+B5w
  76.                     ; KdCompInitialize(x,x)+CBw ...
  77.                 db    1
  78.                 db    0
  79.                 db    0
  80.                 db    0
  81.                 db    0
  82.                 db    0
  83.                 db    0
  84.                 db    0
  85.                 db    0
  86.                 db    0
  87.                 db    0
  88.                 db    0
  89.                 db    0
  90.                 db    0
  91.                 db    0
  92.                 db    0
  93.                 db    0
  94.                 db    0
  95.                 db    0
  96.                 db    0
  97. _KdComAddressID         db 1            ; DATA XREF: KdCompInitialize1()r
  98.                                 ; KdCompInitialize(x,x)+4Aw ...
  99. _KdWriteUchar           dd offset CpWritePortUchar ;    DATA XREF: CpSetBaud(x,x)+2Dr
  100.                                 ; CpSetBaud(x,x)+3Er ...
  101.                                 ; CpWritePortUchar(x,x)
  102. _KdReadUchar            dd offset CpReadPortUchar ; DATA XREF: CpSetBaud(x,x)+1Er
  103.                                 ; CpSendModemString(x,x)+A4r ...
  104.                                 ; CpReadPortUchar(x)
  105. _KdCompDbgParams        dd 0            ; DATA XREF: KdDebuggerInitialize0(x)+56w
  106.                                 ; KdDebuggerInitialize0(x)+7Fo
  107. _ArgKdcomBaudrate       dd 0            ; DATA XREF: KdDebuggerInitialize0(x)+78w
  108. _KdCompPacketIdExpected     dd 0        ; DATA XREF: KdDebuggerInitialize0(x)+98w
  109.                                 ; KdReceivePacket(x,x,x,x,x)+13Dr ...
  110. _KdCompNextPacketIdToSend   dd 0        ; DATA XREF: KdDebuggerInitialize0(x)+8Ew
  111.                                 ; KdReceivePacket(x,x,x,x,x)+F8r ...
  112. byte_MsrLastValue       db 0            ; DATA XREF: CpReadLsr(x,x)+149r
  113.                                 ; CpReadLsr(x,x)+1E0w
  114. byte_LsrExpectedError       db 0            ; DATA XREF: CpReadLsr(x,x)+74w
  115.                                 ; CpReadLsr(x,x)+13Er ...
  116. dword_80010D7C          dd 0            ; DATA XREF: CpSendModemString(x,x)+1Er
  117.                     ; CpSendModemString(x,x)+4Bw ...
  118. byte_LsrParityError     db 0            ; DATA XREF: CpReadLsr(x,x)+4Cw
  119.                     ; CpReadLsr(x,x)+1A7o
  120. byte_LsrOverrunError        db 0            ; DATA XREF: CpReadLsr(x,x)+58w
  121. byte_LsrFramingError        db 0            ; DATA XREF: CpReadLsr(x,x)+64w
  122. _KdCompDbgErrorCount        db  0       ; DATA XREF: CpReadLsr(x,x)+21w
  123.                     ; CpReadLsr(x,x)+27r ...
  124. byte_MsrRingIndicator       db 0            ; DATA XREF: CpReadLsr(x,x)+BDw
  125.                     ; CpReadLsr(x,x)+15Ew ...
  126. _ComPort            dd 0            ; DATA XREF: KdCompInitialize(x,x)+22Cw
  127. _HalpGetInfoFromACPI        db  0       ; DATA XREF: KdCompInitialize(x,x)+A1w
  128.                     ; KdCompInitialize(x,x)+E9r
  129.                     
  130. _DbgpKdComPhysicalAddress0      dd 0 ; DATA XREF: KdCompInitialize1()+13r
  131. _DbgpKdComPhysicalAddress4      dd 0 ; DATA XREF: KdCompInitialize1()+13r
  132.                     ; KdCompInitialize(x,x)+60w ...
  133. _HalpDebugPortTable         dd 0        ; DATA XREF: KdCompInitialize(x,x)+2Ew
  134.                     ; KdCompInitialize(x,x):loc_80010A63r ...
  135. _HintsCount         dd  0CAFEBEBEh      
  136. _data       ends
  137. .CODE _text     
  138. HintOsNotFound  proc near               ; CODE XREF: KdVmCommunicationsBackChannelNotify+1Ap
  139.                     pushad
  140.                 mov     eax, 564D5868h
  141.                 mov ebx,_HintsCount
  142.                 inc ebx
  143.                 mov _HintsCount,ebx
  144.                 cmp         ebx,0CAFEBEC0h
  145.                                 ja  loc_return
  146.                 mov     cx, 12h
  147.                 mov     dx, 5658h
  148.                 in      eax, dx         
  149. loc_return:
  150.                 popad
  151.                 retn
  152. HintOsNotFound  endp
  153. ; BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  154. ; Segment type: Pure code
  155. ; Segment permissions: Read/Execute
  156. ;_text      segment para public 'CODE' use32
  157. ;       assume cs:_text
  158.         ;org 80010344h
  159. ;       assume es:nothing, ss:nothing, _data, fs:nothing, gs:nothing
  160. ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  161. ; Exported entry   1. KdD0Transition
  162. ; Exported entry   2. KdD3Transition
  163. ; _stdcall KdD0Transition()
  164.         public KdD0Transition
  165. KdD0Transition proc near
  166.         xor eax, eax    ; KdD0Transition
  167.         retn
  168. KdD0Transition endp
  169. ; CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  170. ; Exported entry   3. KdDebuggerInitialize0
  171. ; _stdcall KdDebuggerInitialize0(pctx)
  172.         public KdDebuggerInitialize0
  173. KdDebuggerInitialize0 proc near
  174. var_C       = dword ptr -0Ch
  175. arg_0       = dword ptr  8
  176.         push    ebx
  177.         mov ebx, [esp+arg_0]
  178.         test    ebx, ebx
  179.         jz  short loc_reinit
  180.         
  181.         push    esi
  182.         mov esi, [ebx+44h]
  183.         test    esi, esi
  184.         jz  short loc_80010423
  185.         push    edi
  186.         push    esi     ; char *
  187.         call    _strupr
  188.         
  189.         mov [esp+0Ch+var_C], offset aDebugport ; "DEBUGPORT"
  190.         push    esi     ; char *
  191.         call     strstr
  192.         push    offset aBaudrate ; "BAUDRATE"
  193.         push    esi     ; char *
  194.         mov edi, eax
  195.         call     strstr
  196.         add esp, 10h
  197.         test    edi, edi
  198.         mov esi, eax
  199.         jz  short loc_80010401
  200.         push    offset aCom ; "COM"
  201.         push    edi     ; char *
  202.         call     strstr
  203.         test    eax, eax
  204.         pop ecx
  205.         pop ecx
  206.         jz  short loc_80010401
  207.         add eax, 3
  208.         push    eax
  209.         call     atol
  210.         pop ecx
  211.         mov _KdCompDbgParams, eax
  212. loc_80010401:               ; CODE XREF: KdDebuggerInitialize0(x)+39j
  213.                     ; KdDebuggerInitialize0(x)+4Aj
  214.         test    esi, esi
  215.         pop edi
  216.         jz  short loc_80010423
  217.         add esi, 8
  218.         jmp short loc_8001040C
  219. ; CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  220. loc_8001040B:               ; CODE XREF: KdDebuggerInitialize0(x)+69j
  221.         inc esi
  222. loc_8001040C:               ; CODE XREF: KdDebuggerInitialize0(x)+63j
  223.         cmp byte ptr [esi], 20h ; Data Ready?
  224.         jz  short loc_8001040B
  225.         cmp byte ptr [esi], 0
  226.         jz  short loc_80010423
  227.         inc esi
  228.         push    esi
  229.         call     atol
  230.         pop ecx
  231.         mov _ArgKdcomBaudrate,  eax
  232. loc_80010423:               ; CODE XREF: KdDebuggerInitialize0(x)+Fj
  233.                     ; KdDebuggerInitialize0(x)+5Ej ...
  234.         pop esi
  235. loc_reinit:             ; CODE XREF: KdDebuggerInitialize0(x)+7j
  236.         push    ebx
  237.         push    offset _KdCompDbgParams
  238.         call    KdCompInitialize ; KdCompInitialize(_KdCompDbgParams,pctx)
  239.         
  240.         test    eax, eax
  241.         pop ebx
  242.         jl  short locret_80010448
  243.         mov _KdCompNextPacketIdToSend, 80800800h
  244.         mov _KdCompPacketIdExpected, 80800000h
  245. locret_80010448:            ; CODE XREF: KdDebuggerInitialize0(x)+8Cj
  246.         retn    4
  247. KdDebuggerInitialize0 endp
  248. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  249. ; Exported entry   4. KdDebuggerInitialize1
  250. ;------------------------------------------------------------------------ 
  251. ; _stdcall KdDebuggerInitialize1(x)
  252.         public KdDebuggerInitialize1
  253. KdDebuggerInitialize1 proc near
  254.         call    KdCompInitialize1 ; KdCompInitialize1()
  255.         xor eax, eax
  256.         retn    4
  257. KdDebuggerInitialize1 endp
  258. ; Exported entry   7. KdSave
  259. ;------------------------------------------------------------------------ 
  260. ; _stdcall KdSave(x)
  261.         public KdSave
  262. KdSave  proc near
  263.         call    KdCompSave  ; KdCompSave()
  264.         xor eax, eax
  265.         retn    4
  266. KdSave  endp
  267. ; Exported entry   6. KdRestore
  268. ;------------------------------------------------------------------------ 
  269. ; _stdcall KdRestore(x)
  270.         public KdRestore
  271. KdRestore   proc near
  272. arg_0       = byte ptr  4
  273.         cmp [esp+arg_0], 0
  274.         jz  short loc_80010470
  275.         and _KdCompDbgPortsPresent, 0
  276.         jmp short loc_80010475
  277. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  278. loc_80010470:               ; CODE XREF: KdRestore(x)+5j
  279.         call    KdCompRestore ; KdCompRestore()
  280. loc_80010475:               ; CODE XREF: KdRestore(x)+Ej
  281.         xor eax, eax
  282.         retn    4
  283. KdRestore   endp
  284. ;------------------------------------------------------------------------ 
  285. ; Attributes: bp-based frame
  286. ; _stdcall CpSetBaud(x, x)
  287. CpSetBaud   proc near       ; CODE XREF: CpReadLsr(x,x)+1A0p
  288.                     ; CpGetByte(x,x,x)+3Ap ...
  289. arg_0       = dword ptr  8
  290. arg_4       = dword ptr  0Ch
  291.         
  292.         push    ebp
  293.         mov ebp, esp
  294.         push    ebx
  295.         mov ebx, [ebp+arg_4]
  296.         xor edx, edx
  297.         mov eax, 1C200h
  298.         div ebx
  299.         push    esi
  300.         push    edi
  301.         mov edi, [ebp+arg_0]
  302.         mov esi, [edi]
  303.         add esi, 3
  304.         push    esi
  305.         mov [ebp+arg_4], eax
  306.         call    _KdReadUchar    ; CpReadPortUchar(x)
  307.         
  308.         or  al, 80h
  309.         mov byte ptr [ebp+arg_0], al
  310.         push    [ebp+arg_0]
  311.         push    esi
  312.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  313.         mov eax, [ebp+arg_4]
  314.         mov esi, [edi]
  315.         shr eax, 8
  316.         push    eax
  317.         inc esi
  318.         push    esi
  319.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  320.         push    [ebp+arg_4]
  321.         dec esi
  322.         push    esi
  323.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  324.         mov eax, [edi]
  325.         push    3
  326.         add eax, 3
  327.         push    eax
  328.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  329.         mov [edi+4], ebx
  330.         pop edi
  331.         pop esi
  332.         pop ebx
  333.         pop ebp
  334.         retn    8
  335. CpSetBaud   endp
  336. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  337. ;------------------------------------------------------------------------ 
  338. ; Attributes: bp-based frame
  339. ; _stdcall CpSendModemString(x, x)
  340. CpSendModemString proc near     ; CODE XREF: CpReadLsr(x,x)+ECp
  341.                     ; CpReadLsr(x,x)+120p
  342. var_10      = dword ptr -10h
  343. var_6       = word ptr -6
  344. arg_0       = dword ptr  8
  345. arg_4       = dword ptr  0Ch
  346.         push    ebp
  347.         mov ebp, esp
  348.         sub esp, 10h
  349.         push    esi
  350.         mov esi, [ebp+arg_0]
  351.         mov ax, [esi+8]
  352.         test    al, 40h
  353.         jnz loc_80010597
  354.         
  355.         or  ax, 40h
  356.         mov [esi+8], ax
  357.         mov eax, dword_80010D7C
  358.         test    eax, eax
  359.         push    ebx
  360.         push    edi
  361.         jnz short loc_80010548
  362.         
  363.         lea eax, [ebp+var_10]
  364.         push    eax
  365.         call     HalQueryRealTimeClock ; HalQueryRealTimeClock(x)
  366.         movsx   edi, [ebp+var_6]
  367. loc_80010518:               ; CODE XREF: CpSendModemString(x,x)+53j
  368.         push    0
  369.         push    esi
  370.         call    CpReadLsr   ; CpReadLsr(x,x)
  371.         lea eax, [ebp+var_10]
  372.         push    eax
  373.         call     HalQueryRealTimeClock ; HalQueryRealTimeClock(x)
  374.         movsx   eax, [ebp+var_6]
  375.         inc dword_80010D7C
  376.         cmp edi, eax
  377.         jz  short loc_80010518
  378.         
  379.         mov eax, dword_80010D7C
  380.         push    3
  381.         xor edx, edx
  382.         pop ecx
  383.         div ecx
  384.         mov dword_80010D7C, eax
  385. loc_80010548:               ; CODE XREF: CpSendModemString(x,x)+27j
  386.         mov edi, [ebp+arg_4]
  387.         mov ebx, eax
  388.         jmp short loc_8001058C
  389. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  390. loc_8001054F:               ; CODE XREF: CpSendModemString(x,x)+ADj
  391.         lea eax, [ebp+var_10]
  392.         push    eax
  393.         call     HalQueryRealTimeClock ; HalQueryRealTimeClock(x)
  394.         push    0
  395.         push    esi
  396.         call    CpReadLsr   ; CpReadLsr(x,x)
  397.         test    al, 20h
  398.         mov byte ptr [ebp+arg_0+3], al
  399.         jz  short loc_8001057E
  400.         dec ebx
  401.         jnz short loc_8001057E
  402.         xor eax, eax
  403.         mov al, [edi]
  404.         push    eax
  405.         push    dword ptr [esi]
  406.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  407.         mov ebx, dword_80010D7C
  408.         inc edi
  409. loc_8001057E:               ; CODE XREF: CpSendModemString(x,x)+83j
  410.                     ; CpSendModemString(x,x)+86j
  411.         test    byte ptr [ebp+arg_0+3], 1
  412.         jz  short loc_8001058C
  413.         push    dword ptr [esi]
  414.         call    _KdReadUchar    ; CpReadPortUchar(x)
  415. loc_8001058C:               ; CODE XREF: CpSendModemString(x,x)+6Bj
  416.                     ; CpSendModemString(x,x)+A0j
  417.         cmp byte ptr [edi], 0
  418.         jnz short loc_8001054F
  419.         and byte ptr [esi+8], 0BFh
  420.         pop edi
  421.         pop ebx
  422. loc_80010597:               ; CODE XREF: CpSendModemString(x,x)+10j
  423.         pop esi
  424.         leave
  425.         retn    8
  426. CpSendModemString endp
  427. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  428. ;------------------------------------------------------------------------ 
  429. ; Attributes: bp-based frame
  430. ; _stdcall CpReadLsr(x, x)
  431. CpReadLsr   proc near       ; CODE XREF: CpSendModemString(x,x)+39p
  432.                     ; CpSendModemString(x,x)+79p ...
  433. var_18      = dword ptr -18h
  434. var_10      = dword ptr -10h
  435. var_8       = word ptr -8
  436. var_6       = word ptr -6
  437. port        = dword ptr  8
  438. vLsr        = dword ptr  0Bh
  439. CheckStatus = byte ptr  0Ch
  440. vMsr        = byte ptr  0Fh
  441.         push    ebp
  442.         mov ebp, esp
  443.         sub esp, 40h
  444.         push    esi
  445.         mov esi, [ebp+port]
  446.         mov eax, [esi]
  447.         add eax, 5
  448.         push    eax
  449.         call    _KdReadUchar    ; CpReadPortUchar(x)
  450.         mov cl, al
  451.         mov al, 0FFh
  452.         cmp cl, al
  453.         mov byte ptr [ebp+vLsr],    cl ;Lsr
  454.         jnz short loc_80010604
  455.         inc _KdCompDbgErrorCount
  456.         cmp _KdCompDbgErrorCount, 19h
  457.         jb  loc_800107A4
  458.         and _KdCompDbgPortsPresent, 0
  459.         and _KdCompDbgErrorCount, 0
  460.         jmp loc_800107A4
  461. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  462. loc_80010604:               ; CODE XREF: CpReadLsr(x,x)+1Fj
  463.         test    cl, 4       ; Parity Error?
  464.         jz  short loc_80010610
  465.         mov byte_LsrParityError, 8
  466. loc_80010610:               ; CODE XREF: CpReadLsr(x,x)+4Aj
  467.         test    cl, 2       ; Overrun Error?
  468.         jz  short loc_8001061C
  469.         mov byte_LsrOverrunError, 8
  470. loc_8001061C:               ; CODE XREF: CpReadLsr(x,x)+56j
  471.         test    cl, 8       ; Framing Error?
  472.         jz  short loc_80010628
  473.         mov byte_LsrFramingError, 8
  474. loc_80010628:               ; CODE XREF: CpReadLsr(x,x)+62j
  475.         test    [ebp+CheckStatus], cl   ; ?Expectecd
  476.         jz  short loc_notCheckStatus
  477.         mov al, cl
  478.         or  al, 0FEh
  479.         mov byte_LsrExpectedError, al
  480.         mov al, cl
  481.         jmp loc_800107A4
  482. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  483. loc_notCheckStatus:             ; CODE XREF: CpReadLsr(x,x)+6Ej
  484.         mov eax, [esi]
  485.         push    edi
  486.         add eax, 6
  487.         push    eax
  488.         call    _KdReadUchar    ; CpReadPortUchar(x)
  489.         mov [ebp+vMsr], al
  490.         mov ax, [esi+8]
  491.         test    al, 2
  492.         jz  loc_800106E2
  493.         test    [ebp+vMsr], 80h
  494.         jz  short loc_80010669
  495.         or  ax, 90h
  496.         mov [esi+8], ax
  497.         jmp short loc_800106E2
  498. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  499. loc_80010669:               ; CODE XREF: CpReadLsr(x,x)+A0j
  500.         test    al, 10h
  501.         jz  short loc_80010681
  502.         lea eax, [esi+0Ah]
  503.         push    eax
  504.         call     HalQueryRealTimeClock ; HalQueryRealTimeClock(x)
  505.         and byte ptr [esi+8], 0EFh
  506.         and byte_MsrRingIndicator, 0
  507. loc_80010681:               ; CODE XREF: CpReadLsr(x,x)+AEj
  508.         lea eax, [ebp+var_10]
  509.         push    eax
  510.         call     HalQueryRealTimeClock ; HalQueryRealTimeClock(x)
  511.         mov ax, [ebp+var_8]
  512.         cmp ax, [esi+12h]
  513.         mov edi, offset aAt ; "/n/rAT/n/r"
  514.         jz  short loc_800106AE
  515.         mov ax, [ebp+var_6]
  516.         cmp ax, [esi+14h]
  517.         jl  short loc_800106AE
  518.         and byte ptr [esi+8], 0FDh
  519.         push    edi
  520.         push    esi
  521.         call    CpSendModemString ; CpSendModemString(x,x)
  522. loc_800106AE:               ; CODE XREF: CpReadLsr(x,x)+DAj
  523.                     ; CpReadLsr(x,x)+E4j
  524.         mov ax, [esi+8]
  525.         test    al, al
  526.         jns short loc_800106E2
  527.         mov cx, [esi+14h]
  528.         cmp [ebp+var_6], cx
  529.         jge short loc_800106C5
  530.         add [ebp+var_6], 3Ch
  531. loc_800106C5:               ; CODE XREF: CpReadLsr(x,x)+101j
  532.         movsx   edx, [ebp+var_6]
  533.         movsx   ecx, cx
  534.         add ecx, 0Ah
  535.         cmp edx, ecx
  536.         jle short loc_800106E2
  537.         push    edi
  538.         and ax, 0FF7Fh
  539.         push    esi
  540.         mov [esi+8], ax
  541.         call    CpSendModemString ; CpSendModemString(x,x)
  542. loc_800106E2:               ; CODE XREF: CpReadLsr(x,x)+96j
  543.                     ; CpReadLsr(x,x)+AAj ...
  544.         test    byte ptr [esi+8], 4
  545.         jnz short loc_800106F0
  546.         mov al, byte ptr [ebp+vLsr]
  547.         jmp loc_800107A3
  548. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  549. loc_800106F0:               ; CODE XREF: CpReadLsr(x,x)+129j
  550.         mov eax, dword ptr ds:[HalPrivateDispatchTable]
  551.         call    dword ptr [eax+3Ch]
  552.         mov al, byte ptr [ebp+vLsr]
  553.         cmp al, byte_LsrExpectedError
  554.         jnz short loc_80010712
  555.         mov cl, [ebp+vMsr]
  556.         cmp cl, byte_MsrLastValue
  557.         jz  loc_800107A3
  558. loc_80010712:               ; CODE XREF: CpReadLsr(x,x)+144j
  559.         test    [ebp+vMsr], 40h ; Ring Indicator ?
  560.         setz    al
  561.         inc al
  562.         or  byte_MsrRingIndicator, al
  563.         cmp byte_MsrRingIndicator, 3
  564.         jnz short loc_80010762
  565.         and byte_MsrRingIndicator, 0
  566.         xor eax, eax
  567.         mov ax, [esi+8]
  568.         and eax, 0FF7Fh
  569.         or  eax, 12h
  570.         test    al, 1
  571.         mov [esi+8], ax
  572.         jz  short loc_80010762
  573.         mov edi, 2580h
  574.         cmp [esi+4], edi
  575.         jz  short loc_80010762
  576.         push    offset aSwitchingDebug ; "Switching debugger to 9600 baud/n"
  577.         call    ds:InbvDisplayString ; InbvDisplayString(x)
  578.         push    edi
  579.         push    esi
  580.         call    CpSetBaud   ; CpSetBaud(x,x)
  581. loc_80010762:               ; CODE XREF: CpReadLsr(x,x)+16Bj
  582.                     ; CpReadLsr(x,x)+188j ...
  583.         push    3
  584.         mov edx, offset byte_LsrParityError
  585.         mov esi, offset aPrtOvlFrm
  586.         lea ecx, [ebp+var_18]
  587.         pop edi
  588. loc_80010772:               ; CODE XREF: CpReadLsr(x,x)+1D3j
  589.         mov al, [edx]
  590.         test    al, al
  591.         jz  short loc_80010782
  592.         dec al
  593.         mov [edx], al
  594.         mov eax, [esi]
  595.         mov [ecx], eax
  596.         jmp short loc_80010788
  597. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  598. loc_80010782:               ; CODE XREF: CpReadLsr(x,x)+1B9j
  599.         mov dword ptr [ecx], 20202020h
  600. loc_80010788:               ; CODE XREF: CpReadLsr(x,x)+1C3j
  601.         inc edx
  602.         add esi, 4
  603.         sub ecx, 4
  604.         dec edi
  605.         jnz short loc_80010772
  606.         mov al, byte ptr [ebp+vLsr]
  607.         mov cl, [ebp+vMsr]
  608.         mov byte_LsrExpectedError, al
  609.         mov byte_MsrLastValue, cl
  610. loc_800107A3:               ; CODE XREF: CpReadLsr(x,x)+12Ej
  611.                     ; CpReadLsr(x,x)+14Fj
  612.         pop edi
  613. loc_800107A4:               ; CODE XREF: CpReadLsr(x,x)+2Ej
  614.                     ; CpReadLsr(x,x)+42j ...
  615.         pop esi
  616.         leave
  617.         retn    8
  618. CpReadLsr   endp
  619. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  620. ;------------------------------------------------------------------------ 
  621. ; _stdcall CpPutByte(x, x)
  622. CpPutByte   proc near       ; CODE XREF: KdCompPutByte(x)+9p
  623. arg_0       = dword ptr  4
  624.         cmp _KdCompDbgPortsPresent, 0
  625.         jz  short locret_8001080D
  626.         push    esi
  627.         mov esi, [esp+4+arg_0]
  628.         test    byte ptr [esi+8], 2
  629.         jz  short loc_800107F4
  630.         push    ebx
  631. loc_800107BF:               ; CODE XREF: CpPutByte(x,x)+47j
  632.         mov eax, [esi]
  633.         add eax, 6
  634.         push    eax
  635.         call    _KdReadUchar    ; CpReadPortUchar(x)
  636.         mov bl, al
  637.         and bl, 0B0h
  638.         cmp bl, 0B0h
  639.         jz  short loc_800107F3
  640.         push    0
  641.         push    esi
  642.         call    CpReadLsr   ; CpReadLsr(x,x)
  643.         test    bl, bl
  644.         js  short loc_800107ED
  645.         test    al, 1
  646.         jz  short loc_800107ED
  647.         push    dword ptr [esi]
  648.         call    _KdReadUchar    ; CpReadPortUchar(x)
  649. loc_800107ED:               ; CODE XREF: CpPutByte(x,x)+35j
  650.                     ; CpPutByte(x,x)+39j
  651.         test    byte ptr [esi+8], 2
  652.         jnz short loc_800107BF
  653. loc_800107F3:               ; CODE XREF: CpPutByte(x,x)+29j
  654.         pop ebx
  655. loc_800107F4:               ; CODE XREF: CpPutByte(x,x)+12j
  656.                     ; CpPutByte(x,x)+54j
  657.         push    20h
  658.         push    esi
  659.         call    CpReadLsr   ; CpReadLsr(x,x)
  660.         test    al, 20h
  661.         jz  short loc_800107F4
  662.         push    dword ptr [esp+0Ch]
  663.         push    dword ptr [esi]
  664.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  665.         pop esi
  666. locret_8001080D:            ; CODE XREF: CpPutByte(x,x)+7j
  667.         retn    8
  668. CpPutByte   endp
  669. ;------------------------------------------------------------------------ 
  670. ; Attributes: bp-based frame
  671. ; _stdcall CpGetByte(x, x, x)
  672. CpGetByte   proc near       ; CODE XREF: KdCompGetByte(x)+Bp
  673.                     ; KdCompPollByte(x)+Bp
  674. arg_0       = dword ptr  8
  675. arg_4       = dword ptr  0Ch
  676. arg_8       = byte ptr  10h
  677. arg_B       = byte ptr  13h
  678.         push    ebp
  679.         mov ebp, esp
  680.         push    esi
  681.         mov esi, [ebp+arg_0]
  682.         cmp dword ptr [esi], 0
  683.         jnz short loc_portIsOk
  684.         
  685.         mov eax, dword ptr ds:[HalPrivateDispatchTable]
  686.         call    dword ptr [eax+3Ch]
  687.         mov ax, 1
  688.         jmp loc_return
  689. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  690. loc_portIsOk:               ; CODE XREF: CpGetByte(x,x,x)+Aj
  691.         push    ebx
  692.         xor ebx, ebx
  693.         inc ebx
  694.         cmp _KdCompDbgPortsPresent, 0
  695.         push    edi
  696.         jnz short loc_80010855
  697.         
  698.         push    ebx
  699.         push    esi
  700.         call    CpReadLsr   ; CpReadLsr(x,x)
  701.         cmp al, 0FFh
  702.         jz  short loc_800108AE
  703.         
  704.         push    dword ptr [esi+4]
  705.         push    esi
  706.         call    CpSetBaud   ; CpSetBaud(x,x)
  707.         mov _KdCompDbgPortsPresent, bl
  708. loc_80010855:               ; CODE XREF: CpGetByte(x,x,x)+29j
  709.         mov al, [ebp+arg_8]
  710.         neg al
  711.         sbb eax, eax
  712.         and eax, 31FFFh
  713.         inc eax
  714.         mov edi, eax
  715.         jz  short loc_8001089F
  716. loc_80010866:               ; CODE XREF: CpGetByte(x,x,x)+8Dj
  717.         push    ebx
  718.         push    esi
  719.         dec edi
  720.         call    CpReadLsr   ; CpReadLsr(x,x)
  721.         cmp al, 0FFh
  722.         jz  short loc_800108AE
  723.         test    al, bl
  724.         jz  short loc_8001089B
  725.         test    al, 0Eh
  726.         jnz short loc_800108B8
  727.         push    dword ptr [esi]
  728.         call    _KdReadUchar    ; CpReadPortUchar(x)
  729.         test    byte ptr [esi+8], 2
  730.         mov [ebp+arg_B], al
  731.         jz  short loc_800108C4
  732.         mov eax, [esi]
  733.         add eax, 6
  734.         push    eax
  735.         call    _KdReadUchar    ; CpReadPortUchar(x)
  736.         test    al, al
  737.         js  short loc_800108C4
  738. loc_8001089B:               ; CODE XREF: CpGetByte(x,x,x)+64j
  739.         test    edi, edi
  740.         jnz short loc_80010866
  741. loc_8001089F:               ; CODE XREF: CpGetByte(x,x,x)+54j
  742.         and byte_LsrExpectedError, 0
  743.         push    0
  744.         push    esi
  745.         call    CpReadLsr   ; CpReadLsr(x,x)
  746. loc_800108AE:               ; CODE XREF: CpGetByte(x,x,x)+34j
  747.                     ; CpGetByte(x,x,x)+60j
  748.         mov ax, bx
  749. loc_800108B1:               ; CODE XREF: CpGetByte(x,x,x)+B2j
  750.                     ; CpGetByte(x,x,x)+BFj
  751.         pop edi
  752.         pop ebx
  753. loc_return:             ; CODE XREF: CpGetByte(x,x,x)+18j
  754.         pop esi
  755.         pop ebp
  756.         retn    0Ch
  757. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  758. loc_800108B8:               ; CODE XREF: CpGetByte(x,x,x)+68j
  759.         mov eax, [ebp+arg_4]
  760.         and byte ptr [eax], 0
  761.         mov ax, 2
  762.         jmp short loc_800108B1
  763. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  764. loc_800108C4:               ; CODE XREF: CpGetByte(x,x,x)+79j
  765.                     ; CpGetByte(x,x,x)+89j
  766.         mov eax, [ebp+arg_4]
  767.         mov cl, [ebp+arg_B]
  768.         mov [eax], cl
  769.         xor ax, ax
  770.         jmp short loc_800108B1
  771. CpGetByte   endp
  772. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  773.         align 2
  774. ;------------------------------------------------------------------------ 
  775. ; Attributes: bp-based frame
  776. ; _stdcall CpDoesPortExist(x)
  777. CpDoesPortExist proc    near        ; CODE XREF: KdCompInitialize(x,x)+19Cp
  778.                     ; KdCompInitialize(x,x)+1B3p
  779. arg_0       = dword ptr  8
  780.         push    ebp
  781.         mov ebp, esp
  782.         push    ebx
  783.         push    esi
  784.         push    edi
  785.         mov edi, [ebp+arg_0]
  786.         lea esi, [edi+4]
  787.         push    esi
  788.         mov bl, 1
  789.         call    _KdReadUchar    ; CpReadPortUchar(x)
  790.         push    10h
  791.         push    esi
  792.         mov byte ptr [ebp+arg_0], al
  793.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  794.         push    10h
  795.         push    esi
  796.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  797.         add edi, 6
  798.         push    edi
  799.         call    _KdReadUchar    ; CpReadPortUchar(x)
  800.         test    al, 0F0h
  801.         jnz short loc_8001091E
  802.         push    14h
  803.         push    esi
  804.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  805.         push    edi
  806.         call    _KdReadUchar    ; CpReadPortUchar(x)
  807.         test    al, 40h
  808.         jnz short loc_80010920
  809. loc_8001091E:               ; CODE XREF: CpDoesPortExist(x)+36j
  810.         xor bl, bl
  811. loc_80010920:               ; CODE XREF: CpDoesPortExist(x)+4Aj
  812.         push    [ebp+arg_0]
  813.         push    esi
  814.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  815.         pop edi
  816.         pop esi
  817.         mov al, bl
  818.         pop ebx
  819.         pop ebp
  820.         retn    4
  821. CpDoesPortExist endp
  822. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  823.         align 4
  824. ;------------------------------------------------------------------------ 
  825. ; _stdcall CpWritePortUchar(x,  x)
  826. CpWritePortUchar proc near      ; CODE XREF: CpSetBaud(x,x)+2Dp
  827.                     ; CpSetBaud(x,x)+3Ep ...
  828.         jmp  ds:WRITE_PORT_UCHAR ; WRITE_PORT_UCHAR(x,x)
  829. CpWritePortUchar endp
  830. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  831.         align 2
  832. ;------------------------------------------------------------------------ 
  833. ; _stdcall CpReadPortUchar(x)
  834. CpReadPortUchar proc    near        ; CODE XREF: CpSetBaud(x,x)+1Ep
  835.                     ; CpSendModemString(x,x)+A4p ...
  836.         jmp  ds:READ_PORT_UCHAR ; READ_PORT_UCHAR(x)
  837. CpReadPortUchar endp
  838. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  839.         align 10h
  840. ;------------------------------------------------------------------------ 
  841. ; _stdcall CpWriteRegisterUchar(x, x)
  842. CpWriteRegisterUchar    proc near   ; DATA XREF: KdCompInitialize(x,x)+246o
  843.         jmp  ds:WRITE_REGISTER_UCHAR ; WRITE_REGISTER_UCHAR(x,x)
  844. CpWriteRegisterUchar    endp
  845. ;------------------------------------------------------------------------ 
  846. ; _stdcall CpReadRegisterUchar(x)
  847. CpReadRegisterUchar proc near   ; DATA XREF: KdCompInitialize(x,x)+250o
  848.         jmp  ds:READ_REGISTER_UCHAR ; READ_REGISTER_UCHAR(x)
  849. CpReadRegisterUchar endp
  850. ;------------------------------------------------------------------------ 
  851. ; _stdcall CpInitialize(x, x, x)
  852. CpInitialize proc near      ; CODE XREF: KdCompInitialize(x,x)+266p
  853. arg_0       = dword ptr  4
  854. arg_4       = dword ptr  8
  855. arg_8       = dword ptr  0Ch
  856.         
  857.     
  858.         
  859.         mov eax, [esp+arg_4]
  860.         push    esi
  861.         mov esi, [esp+4+arg_0]
  862.         push    [esp+4+arg_8]
  863.         and dword ptr [esi+4], 0
  864.         push    esi
  865.         mov [esi], eax
  866.         call    CpSetBaud   ; CpSetBaud(x,x)
  867.         
  868.         mov eax, [esi]
  869.         push    3
  870.         add eax, 4
  871.         push    eax
  872.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  873.         mov eax, [esi]
  874.         push    0
  875.         inc eax
  876.         push    eax
  877.         call    _KdWriteUchar   ; CpWritePortUchar(x,x)
  878.         pop esi
  879.         retn    0Ch
  880. CpInitialize endp
  881. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  882.         align 4
  883. ;------------------------------------------------------------------------ 
  884. ; _stdcall KdCompGetByte(x)
  885. KdCompGetByte proc near  pucdata:PUCHAR     ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+11p
  886.                     ; KdpReceiveString(x,x)+11p ...
  887.         push    1
  888.         push    pucdata
  889.         push    offset _Port
  890.         call    CpGetByte   ; CpGetByte(x,x,x)
  891.         movzx   eax, ax
  892.         ret
  893. KdCompGetByte endp
  894. ;------------------------------------------------------------------------ 
  895. ; _stdcall KdCompPollByte(x)
  896. KdCompPollByte proc near  pucdata:PUCHAR        ; CODE XREF: KdReceivePacket(x,x,x,x,x)+10p
  897.         push    0
  898.         push    pucdata
  899.         push    offset _Port
  900.         call    CpGetByte   ; CpGetByte(x,x,x)
  901.         movzx   eax, ax
  902.         ret
  903. KdCompPollByte endp
  904. ;------------------------------------------------------------------------ 
  905. ; _stdcall KdCompPutByte(x)
  906. KdCompPutByte proc near ucdata:DWORD        ; CODE XREF: KdpSendString(x,x)+18p
  907.                                                     ; KdSendPacket(x,x,x,x)+C9p
  908.         push    ucdata
  909.         push    offset _Port
  910.         call    CpPutByte   ; CpPutByte(x,x)
  911.         ret
  912. KdCompPutByte endp
  913. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  914.         align 2
  915. ;------------------------------------------------------------------------ 
  916. ; _stdcall KdCompRestore()
  917. KdCompRestore proc near     ; CODE XREF: KdRestore(x):loc_80010470p
  918.         and _com_status_flag, 0FBh
  919.         retn
  920. KdCompRestore endp
  921. ;------------------------------------------------------------------------ 
  922. ; _stdcall KdCompSave()
  923. KdCompSave  proc near       ; CODE XREF: KdSave(x)p
  924.         or  _com_status_flag, 4
  925.         retn
  926. KdCompSave  endp
  927. ;------------------------------------------------------------------------ 
  928. ; _stdcall KdCompInitialize1()
  929. KdCompInitialize1 proc near     ; CODE XREF: KdDebuggerInitialize1(x)p
  930.         cmp _KdComAddressID, 0
  931.         jnz short locret_800109FE
  932.         push    0       ; CacheType
  933.         push    8       ; NumberOfBytes
  934.         push    dword ptr _DbgpKdComPhysicalAddress4
  935.         push    dword ptr _DbgpKdComPhysicalAddress0 ; PhysicalAddress
  936.         call     MmMapIoSpace ; MmMapIoSpace(x,x,x,x)
  937.         mov ecx, dword ptr ds:[KdComPortInUse]
  938.         mov _Port, eax
  939.         mov [ecx], eax
  940. locret_800109FE:            ; CODE XREF: KdCompInitialize1()+7j
  941.         retn
  942. KdCompInitialize1 endp
  943. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  944.         align 10h
  945. ;------------------------------------------------------------------------ 
  946. ; _stdcall KdCompGetDebugTblBaudRate(x)
  947. KdCompGetDebugTblBaudRate proc near ; CODE XREF: KdCompInitialize(x,x)+C6p
  948. arg_0       = byte ptr  4
  949.         movzx   ecx, [esp+arg_0]
  950.         sub ecx, 3
  951.         mov eax, 0E100h
  952.         jz  short loc_80010A25
  953.         dec ecx
  954.         jz  short loc_80010A1E
  955.         sub ecx, 3
  956.         jnz short locret_80010A2A
  957.         mov eax, 1C200h
  958.         jmp short locret_80010A2A
  959. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  960. loc_80010A1E:               ; CODE XREF: KdCompGetDebugTblBaudRate(x)+10j
  961.         mov eax, 4B00h
  962.         jmp short locret_80010A2A
  963. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  964. loc_80010A25:               ; CODE XREF: KdCompGetDebugTblBaudRate(x)+Dj
  965.         mov eax, 2580h
  966. locret_80010A2A:            ; CODE XREF: KdCompGetDebugTblBaudRate(x)+15j
  967.                     ; KdCompGetDebugTblBaudRate(x)+1Cj ...
  968.         retn    4
  969. KdCompGetDebugTblBaudRate endp
  970. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  971.         align 2
  972. ;------------------------------------------------------------------------ 
  973. ; Attributes: bp-based frame
  974. ; _stdcall KdCompInitialize(_kdParams,  pctx)
  975. KdCompInitialize proc near      ; CODE XREF: KdDebuggerInitialize0(x)+84p
  976. var_8       = dword ptr -8
  977. var_4       = dword ptr -4
  978. arg_0       = dword ptr  8
  979. arg_4       = dword ptr  0Ch
  980.     
  981.     
  982.         
  983.         push    ebp
  984.         mov ebp, esp
  985.         push    ecx
  986.         push    ecx
  987.         and [ebp+var_4], 0
  988.         push    ebx
  989.         mov ebx, [ebp+arg_4] ;pctx
  990.         test    ebx, ebx
  991.         push    esi
  992.         push    edi
  993.         mov [ebp+var_8], 4B00h
  994.         
  995.         
  996.         
  997.         jz  short loc_GetSavedDbgp
  998.         
  999.         
  1000.         mov eax, dword ptr ds:[HalPrivateDispatchTable] 
  1001.         mov eax, [eax+38h] 
  1002.         test    eax, eax
  1003.         jz  short loc_GetSavedDbgp
  1004.             
  1005.         
  1006.         
  1007.         push    50474244h ;'DBGP'
  1008.         push    ebx ;pctx
  1009.         call    eax  ; 取得 _HalpDebugPortTable 
  1010.         
  1011.         
  1012.         mov _HalpDebugPortTable , eax
  1013.         jmp short loc_DbgPortGot
  1014. ; ---------------------------------------------------------------------------------C--
  1015. loc_GetSavedDbgp:               ; CODE XREF: KdCompInitialize(x,x)+18j
  1016.                     ; KdCompInitialize(x,x)+24j
  1017.         mov eax, _HalpDebugPortTable
  1018. loc_DbgPortGot:             ; CODE XREF: KdCompInitialize(x,x)+33j
  1019.         
  1020.         
  1021.         test    eax, eax
  1022.         mov esi, [ebp+arg_0]
  1023.         
  1024.         jz  loc_checkDbgPortInfo ;无法取得_HalpDebugPortTable,则跳转
  1025.         
  1026.         mov dl, [eax+28h]
  1027.         test    dl, dl
  1028.         mov _KdComAddressID, dl
  1029.         jz  short loc_getPhiscalAddr ;如果_KdComAddressID为零,跳
  1030.         cmp dl, 1
  1031.         jnz loc_checkDbgPortInfo; 如果_KdComAddressID是1,跳转
  1032. loc_getPhiscalAddr:             ; CODE XREF: KdCompInitialize(x,x)+50j
  1033.         ;
  1034.         ;实际调试发现睟B嶂葱械秸饫?
  1035.         ;
  1036.         test    dl, dl
  1037.         mov ecx, [eax+2Ch]
  1038.         mov dword ptr _DbgpKdComPhysicalAddress0, ecx
  1039.         mov edi, [eax+30h]
  1040.         mov dword ptr _DbgpKdComPhysicalAddress4, edi
  1041.         
  1042.         jnz short loc_GetSavedPortInfo
  1043.         
  1044.         mov ecx, dword ptr ds:[HalPrivateDispatchTable]
  1045.         mov ecx, [ecx+44h]
  1046.         test    ecx, ecx
  1047.         jz  short loc_GotPortInfo
  1048.         
  1049.         push    1
  1050.         push    dword ptr [eax+30h] ;B厦嫒〉玫C物理地址
  1051.         push    dword ptr [eax+2Ch] ;
  1052.         call    ecx         ;B袢PortInformation.
  1053.         mov _PortInformation, eax
  1054.         mov eax, _HalpDebugPortTable
  1055.         jmp short loc_GotPortInfo
  1056. ; -----------------------------------------------------------------------------------C
  1057. loc_GetSavedPortInfo:               ; CODE XREF: KdCompInitialize(x,x)+6Fj
  1058.         mov _PortInformation, ecx
  1059. loc_GotPortInfo:                ; CODE XREF: KdCompInitialize(x,x)+7Cj
  1060.                         ; KdCompInitialize(x,x)+92j
  1061.         and _com_status_flag, 0FCh
  1062.         mov _HalpGetInfoFromACPI, 1
  1063.         cmp byte ptr [eax+24h], 0   
  1064.         
  1065.         jnz short loc_setDefaultBaudrate
  1066.         
  1067.         mov ecx, [esi+4]
  1068.         test    ecx, ecx
  1069.         jz  short loc_usrNotSetBaudrate
  1070.         mov _ComBaudratePara,   ecx
  1071.         jmp short loc_checkDbgPortInfo
  1072. ; -----------------------------------------------------------------------------------C
  1073. loc_usrNotSetBaudrate:              ; CODE XREF: KdCompInitialize(x,x)+B3j
  1074.         movzx   eax, byte ptr [eax+3Ah]     ;如果用BB有指定速度,则从刚才取读礐信息中B袢?
  1075.         test    al, al              
  1076.         
  1077.         jz  short loc_setDefaultBaudrate  ;如果速度礐tableIndex为零,B柚萌≡ざǖC0E100h
  1078.         
  1079.         push    eax         
  1080.         call    KdCompGetDebugTblBaudRate ; KdCompGetDebugTblBaudRate(x)
  1081.         mov _ComBaudratePara,   eax
  1082.         
  1083.         jmp short loc_checkDbgPortInfo
  1084. ; -----------------------------------------------------------------------------------C
  1085. loc_setDefaultBaudrate:             ; CODE XREF: KdCompInitialize(x,x)+ACj
  1086.                     ; KdCompInitialize(x,x)+C3j
  1087.         mov _ComBaudratePara,   0E100h
  1088. loc_checkDbgPortInfo:               ; CODE XREF: KdCompInitialize(x,x)+3Fj
  1089.                     ; KdCompInitialize(x,x)+55j ...
  1090.     
  1091.         mov eax, _PortInformation
  1092.         test    eax, eax
  1093.         jnz loc_PortInformationNonZero
  1094.         
  1095.         cmp _HalpGetInfoFromACPI, al
  1096.         jnz loc_PortInformationNonZero
  1097.         mov eax, [esi+4]
  1098.         test    eax, eax
  1099.         jz  short loc_passInBaudrateIsZero
  1100.         and _com_status_flag, 0FEh
  1101.         mov [ebp+var_8], eax
  1102. loc_passInBaudrateIsZero:               ; CODE XREF: KdCompInitialize(x,x)+FAj
  1103.         mov eax, [esi]
  1104.         test    eax, eax
  1105.         jz  short loc_portidIsZero
  1106.         
  1107.         test    ebx, ebx
  1108.         mov edi, eax
  1109.         lea eax, [edi-1]
  1110.         mov [ebp+arg_4], eax
  1111.         jz  short loc_80010B5E ;如果pCtx为空则跳转
  1112.         
  1113.         lea eax, [ebp+arg_4]
  1114.         push    eax
  1115.         push    11h
  1116.         push    4
  1117.         push    dword ptr [ebx+30h]
  1118.         call     ds:KeFindConfigurationEntry ;  KeFindConfigurationEntry(x,x,x,x)
  1119.         mov esi, eax
  1120.         jmp loc_80010BFC
  1121. ; -----------------------------------------------------------------------------------C
  1122. loc_80010B5E:               ; CODE XREF: KdCompInitialize(x,x)+116j
  1123.         xor esi, esi
  1124.         jmp loc_80010BFC
  1125. ; -----------------------------------------------------------------------------------C
  1126. loc_portidIsZero:               ; CODE XREF: KdCompInitialize(x,x)+10Aj
  1127.         test    ebx, ebx
  1128.         mov edi, ds:KeFindConfigurationEntry ; KeFindConfigurationEntry(x,x,x,x)
  1129.         mov [ebp+arg_4], 1
  1130.         jz  short loc_80010B87
  1131.         
  1132.         lea eax, [ebp+arg_4]
  1133.         push    eax
  1134.         push    11h
  1135.         push    4
  1136.         push    dword ptr [ebx+30h]
  1137.         call    edi ; KeFindConfigurationEntry(x,x,x,x) ; KeFindConfigurationEntry(x,x,x,x)
  1138.         mov esi, eax
  1139.         jmp short loc_FoundConfigEntry
  1140. ; -----------------------------------------------------------------------------------C
  1141. loc_80010B87:               ; CODE XREF: KdCompInitialize(x,x)+146j
  1142.         xor esi, esi
  1143. loc_FoundConfigEntry:               ; CODE XREF: KdCompInitialize(x,x)+157j
  1144.         test    esi, esi
  1145.         jz  short loc_80010BA0
  1146.         mov eax, [esi+4]
  1147.         test    eax, eax
  1148.         jz  short loc_80010B9C
  1149.         cmp dword ptr [eax+10h], 1Fh
  1150.         jnz short loc_80010B9C
  1151.         xor esi, esi
  1152. loc_80010B9C:               ; CODE XREF: KdCompInitialize(x,x)+164j
  1153.                     ; KdCompInitialize(x,x)+16Aj
  1154.         test    esi, esi
  1155.         jnz short loc_80010BF9
  1156. loc_80010BA0:               ; CODE XREF: KdCompInitialize(x,x)+15Dj
  1157.         and [ebp+arg_4], 0
  1158.         test    ebx, ebx
  1159.         jz  short loc_80010BB9
  1160.         lea eax, [ebp+arg_4]
  1161.         push    eax
  1162.         push    11h
  1163.         push    4
  1164.         push    dword ptr [ebx+30h]
  1165.         call    edi ; KeFindConfigurationEntry(x,x,x,x) ; KeFindConfigurationEntry(x,x,x,x)
  1166.         mov esi, eax
  1167.         jmp short loc_80010BBB
  1168. ; -----------------------------------------------------------------------------------C
  1169. loc_80010BB9:               ; CODE XREF: KdCompInitialize(x,x)+178j
  1170.         xor esi, esi
  1171. loc_80010BBB:               ; CODE XREF: KdCompInitialize(x,x)+189j
  1172.         test    esi, esi
  1173.         jz  short loc_TestPortIdBrute
  1174. loc_port3f8Ok:              ; CODE XREF: KdCompInitialize(x,x)+1BFj
  1175.         xor edi, edi
  1176.         inc edi
  1177.         jmp short loc_80010BFC
  1178. ; -----------------------------------------------------------------------------------C
  1179. loc_TestPortIdBrute:                ; CODE XREF: KdCompInitialize(x,x)+18Fj
  1180.         mov edi, 2F8h
  1181.         push    edi
  1182.         call    CpDoesPortExist ; CpDoesPortExist(x)
  1183.         test    al, al
  1184.         jz  short loc_TestPortIdBrute_3f8
  1185.         push    2
  1186.         mov [ebp+var_4], edi
  1187.         pop edi
  1188.         jmp short loc_SaveComPortId
  1189. ; -----------------------------------------------------------------------------------C
  1190. loc_TestPortIdBrute_3f8:                ; CODE XREF: KdCompInitialize(x,x)+1A3j
  1191.         mov edi, 3F8h       
  1192.         push    edi
  1193.         call    CpDoesPortExist ; CpDoesPortExist(x)
  1194.         test    al, al
  1195.         jz  short loc_Brutefailed
  1196.         mov [ebp+var_4], edi ;var_4 = tempport
  1197.         jmp short loc_port3f8Ok
  1198. ; -----------------------------------------------------------------------------------C
  1199. loc_Brutefailed:                ; CODE XREF: KdCompInitialize(x,x)+1BAj
  1200.         mov eax, 0C0000225h
  1201.         jmp loc_80010CC7
  1202. ; -----------------------------------------------------------------------------------C
  1203. loc_80010BF9:               ; CODE XREF: KdCompInitialize(x,x)+170j
  1204.         push    2
  1205.         pop edi
  1206. loc_80010BFC:               ; CODE XREF: KdCompInitialize(x,x)+12Bj
  1207.                     ; KdCompInitialize(x,x)+132j ...
  1208.         test    esi, esi
  1209.         jz  short loc_getPortIdByIndex
  1210.         mov esi, [esi+30h]
  1211.         mov ecx, [esi+4]
  1212.         test    ecx, ecx
  1213.         jbe short loc_getPortIdByIndex
  1214.         lea eax, [esi+8]
  1215. loc_80010C0D:               ; CODE XREF: KdCompInitialize(x,x)+1EEj
  1216.         cmp byte ptr [eax], 1
  1217.         jnz short loc_80010C18
  1218.         mov edx, [eax+4]
  1219.         mov [ebp+var_4], edx
  1220. loc_80010C18:               ; CODE XREF: KdCompInitialize(x,x)+1E2j
  1221.         add eax, 10h
  1222.         dec ecx
  1223.         jnz short loc_80010C0D
  1224. loc_getPortIdByIndex:               ; CODE XREF: KdCompInitialize(x,x)+1D0j
  1225.                     ; KdCompInitialize(x,x)+1DAj
  1226.         cmp [ebp+var_4], 0  ;TEMP PORT
  1227.         jnz short loc_SaveComPortId
  1228.         mov eax, edi
  1229.         dec eax
  1230.         jz  short loc_80010C4D
  1231.         dec eax
  1232.         jz  short loc_80010C44
  1233.         dec eax
  1234.         jz  short loc_80010C3B
  1235.         dec eax
  1236.         jnz short loc_SaveComPortId
  1237.         mov [ebp+var_4], 2E8h
  1238.         jmp short loc_SaveComPortId
  1239. ; -----------------------------------------------------------------------------------C
  1240. loc_80010C3B:               ; CODE XREF: KdCompInitialize(x,x)+1FFj
  1241.         mov [ebp+var_4], 3E8h
  1242.         jmp short loc_SaveComPortId
  1243. ; -----------------------------------------------------------------------------------C
  1244. loc_80010C44:               ; CODE XREF: KdCompInitialize(x,x)+1FCj
  1245.         mov [ebp+var_4], 2F8h
  1246.         jmp short loc_SaveComPortId
  1247. ; -----------------------------------------------------------------------------------C
  1248. loc_80010C4D:               ; CODE XREF: KdCompInitialize(x,x)+1F9j
  1249.         mov [ebp+var_4], 3F8h
  1250. loc_SaveComPortId:              ; CODE XREF: KdCompInitialize(x,x)+1ABj
  1251.                     ; KdCompInitialize(x,x)+1F4j ...
  1252.         mov eax, [ebp+var_4]
  1253.         mov ecx, [ebp+var_8]
  1254.         mov _ComPort, edi
  1255.         mov _PortInformation,   eax
  1256.         mov _ComBaudratePara,   ecx
  1257. loc_PortInformationNonZero:             ; CODE XREF: KdCompInitialize(x,x)+E3j
  1258.                     ; KdCompInitialize(x,x)+EFj
  1259.         cmp _KdComAddressID, 0
  1260.         jnz short loc_comAddrIdNonZero
  1261.         
  1262.         mov _KdWriteUchar, offset CpWriteRegisterUchar ;    CpWriteRegisterUchar(x,x)
  1263.         mov _KdReadUchar, offset CpReadRegisterUchar ; CpReadRegisterUchar(x)
  1264. loc_comAddrIdNonZero:               ; CODE XREF: KdCompInitialize(x,x)+244j
  1265.         push    _ComBaudratePara
  1266.         push    eax
  1267.         push    offset _Port
  1268.         call    CpInitialize ; CpInitialize(x,x,x)
  1269.         cmp _HalpDebugPortTable, 0
  1270.         jz  short loc_80010CB8
  1271.         cmp _KdComAddressID, 0
  1272.         jnz short loc_80010CB8
  1273.         mov eax, dword ptr ds:[KdComPortInUse]
  1274.         and dword ptr [eax], 0FFFh
  1275.         jmp short loc_80010CC5
  1276. ; -----------------------------------------------------------------------------------C
  1277. loc_80010CB8:               ; CODE XREF: KdCompInitialize(x,x)+272j
  1278.                     ; KdCompInitialize(x,x)+27Bj
  1279.         mov eax, _PortInformation
  1280.         mov ecx,dword ptr ds:[KdComPortInUse]
  1281.         mov [ecx], eax
  1282. loc_80010CC5:               ; CODE XREF: KdCompInitialize(x,x)+288j
  1283.         xor eax, eax
  1284. loc_80010CC7:               ; CODE XREF: KdCompInitialize(x,x)+1C6j
  1285.         pop edi
  1286.         pop esi
  1287.         pop ebx
  1288.         leave
  1289.         retn    8
  1290. KdCompInitialize endp
  1291.                  public DllEntryPoint
  1292. DllEntryPoint   proc near
  1293.              
  1294.                  jmp      HalInitSystem; HalInitSystem(x,x)
  1295.        
  1296.                  xor eax,eax
  1297.          retn 8;                 
  1298. DllEntryPoint   endp
  1299.         align 10h
  1300. _text       ends
  1301. ; Section 3. (virtual address 00000E00)
  1302. ; Virtual size          : 000004DF (   1247.)
  1303. ; Section size in file      : 00000500 (   1280.)
  1304. ; Offset to raw data for section: 00000E00
  1305. ; Flags 60000020: Text Executable Readable
  1306. ; Alignment : default
  1307. ; BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  1308. ; Segment type: Pure code
  1309. ; Segment permissions: Read/Execute
  1310. ;PAGEKD     segment para public 'CODE' use32
  1311. ;       assume cs:PAGEKD
  1312. ;       ;org 80010E00h
  1313. ;       assume es:nothing, ss:nothing, _data, fs:nothing, gs:nothing
  1314. .code PAGEKD 
  1315. ;------------------------------------------------------------------------ 
  1316. ; _stdcall KdpComputeChecksum(x, x)
  1317. KdpComputeChecksum proc near Buffer:PUCHAR,Len:ULONG
  1318.                     ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1F0p
  1319.                     ; KdReceivePacket(x,x,x,x,x)+1FEp ...
  1320.         mov     edx, Len
  1321.         xor     eax, eax
  1322.         test    edx, edx
  1323.         jbe     short locret_80010E19
  1324.         mov     ecx, Buffer
  1325.         push    esi
  1326. loc_80010E0F:               ; CODE XREF: KdpComputeChecksum(x,x)+16j
  1327.         movzx   esi, byte ptr [ecx]
  1328.         add     eax, esi
  1329.         inc     ecx
  1330.         dec     edx
  1331.         jnz     short loc_80010E0F
  1332.         pop     esi
  1333. locret_80010E19:            ; CODE XREF: KdpComputeChecksum(x,x)+8j
  1334.         ret
  1335. KdpComputeChecksum endp
  1336. ;------------------------------------------------------------------------ 
  1337. ; Attributes: bp-based frame
  1338. ; _stdcall KdCompReceivePacketLeader(x, x, x)
  1339. KdCompReceivePacketLeader proc near ; CODE XREF: KdReceivePacket(x,x,x,x,x)+3Ep
  1340.    var_2           = dword ptr -2
  1341.    arg_4           = dword ptr  0Ch
  1342.    arg_8           = dword ptr  10h
  1343.                   
  1344.                   push    ebp
  1345.                 mov     ebp, esp
  1346.                 push    ecx
  1347.                 push    ebx
  1348.                 xor     bl, bl
  1349.                 and     byte ptr [ebp+var_2+1], bl
  1350.                 push    esi
  1351. loc_80010E27:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+20j
  1352.                                         ; KdCompReceivePacketLeader(x,x,x)+33j
  1353.                 xor     esi, esi
  1354. loc_80010E29:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+3Dj
  1355.                                         ; KdCompReceivePacketLeader(x,x,x)+4Dj
  1356.                 lea     eax, [ebp+var_2]
  1357.                 push    eax
  1358.                 call    KdCompGetByte ; KdCompGetByte(x)
  1359.                 xor     ecx, ecx
  1360.                 inc     ecx
  1361.                 cmp     eax, ecx
  1362.                 jz      short loc_80010EA9
  1363.                 cmp     eax, 2
  1364.                 jz      short loc_80010E27
  1365.                 mov     al, byte ptr [ebp+var_2]
  1366.                 cmp     al, 30h
  1367.                 jz      short loc_80010E51
  1368.                 cmp     al, 69h
  1369.                 jz      short loc_80010E51
  1370.                 cmp     al, 62h
  1371.                 setz    byte ptr [ebp+var_2+1]
  1372.                 jmp     short loc_80010E27
  1373. ;-------------------------------------------------------------------------
  1374.                                                                           
  1375. loc_80010E51:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+27j
  1376.                                         ; KdCompReceivePacketLeader(x,x,x)+2Bj
  1377.                 test    esi, esi
  1378.                 jnz     short loc_80010E5B
  1379.                 mov     bl, al
  1380.                 mov     esi, ecx
  1381.                 jmp     short loc_80010E29
  1382. ;-------------------------------------------------------------------------
  1383.                                                                           
  1384. loc_80010E5B:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+37j
  1385.                 cmp     al, bl
  1386.                 jnz     short loc_80010E62
  1387.                 inc     esi
  1388.                 jmp     short loc_80010E66
  1389. ;-------------------------------------------------------------------------
  1390.                                                                           
  1391. loc_80010E62:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+41j
  1392.                 mov     bl, al
  1393.                 mov     esi, ecx
  1394. loc_80010E66:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+44j
  1395.                 cmp     esi, 4
  1396.                 jb      short loc_80010E29
  1397.                 cmp     byte ptr [ebp+var_2+1], 0
  1398.                 jz      short loc_80010E78
  1399.                 mov     ecx, [ebp+arg_8]
  1400.                 mov     byte ptr [ecx+4], 1
  1401. loc_80010E78:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+53j
  1402.                 xor     ecx, ecx
  1403.                 cmp     al, 30h
  1404.                 mov     eax, [ebp+arg_4]
  1405.                 setnz   cl
  1406.                 dec     ecx
  1407.                 and     ecx, 0C6C6C6C7h
  1408.                 add     ecx, 69696969h
  1409.                 mov     [eax], ecx
  1410.                 mov     eax, dword ptr ds:[KdDebuggerNotPresent]
  1411.                 and     byte ptr [eax], 0
  1412.                 or      byte ptr ds:[0FFDF02D4h], 2
  1413.                 xor     ax, ax
  1414. loc_80010EA3:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+9Ej
  1415.                                         ; KdCompReceivePacketLeader(x,x,x)+A3j
  1416.                 pop     esi
  1417.                 pop     ebx
  1418.                 pop         ecx
  1419.                 leave
  1420.                 retn    0Ch
  1421. ;-------------------------------------------------------------------------
  1422.                                                                           
  1423. loc_80010EA9:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+1Bj
  1424.                 cmp     byte ptr [ebp+var_2+1], 0
  1425.                 jz      short loc_80010EBC
  1426.                 mov     eax, [ebp+arg_8]
  1427.                 mov     byte ptr [eax+4], 1
  1428.                 mov     ax, 2
  1429.                 jmp     short loc_80010EA3
  1430. ;-------------------------------------------------------------------------
  1431. loc_80010EBC:                           ; CODE XREF: KdCompReceivePacketLeader(x,x,x)+91j
  1432.                 mov     ax, cx
  1433.                 jmp     short loc_80010EA3
  1434. KdCompReceivePacketLeader endp
  1435. ; -----------------------------------------------------------------------------------C
  1436.         align 2
  1437. ;------------------------------------------------------------------------ 
  1438. ; Attributes: bp-based frame
  1439. ; _stdcall KdpReceiveString(x,  x)
  1440. KdpReceiveString proc near      ; CODE XREF: KdReceivePacket(x,x,x,x,x)+67p
  1441.                     ; KdReceivePacket(x,x,x,x,x)+92p ...
  1442. arg_0       = dword ptr  8
  1443. arg_4       = dword ptr  0Ch
  1444.         push    ebp
  1445.         mov ebp, esp
  1446.         cmp [ebp+arg_4], 0
  1447.         push    esi
  1448.         jbe short loc_80010EE7
  1449.         mov esi, [ebp+arg_0]
  1450. loc_80010ECF:               ; CODE XREF: KdpReceiveString(x,x)+23j
  1451.         lea eax, [ebp+arg_0+3]
  1452.         push    eax
  1453.         call     KdCompGetByte ; KdCompGetByte(x)
  1454.         test    eax, eax
  1455.         jnz short loc_80010EE9
  1456.         mov al, byte ptr [ebp+arg_0+3]
  1457.         mov [esi], al
  1458.         inc esi
  1459.         dec [ebp+arg_4]
  1460.         jnz short loc_80010ECF
  1461. loc_80010EE7:               ; CODE XREF: KdpReceiveString(x,x)+8j
  1462.         xor eax, eax
  1463. loc_80010EE9:               ; CODE XREF: KdpReceiveString(x,x)+18j
  1464.         pop esi
  1465.         pop ebp
  1466.         retn    8
  1467. KdpReceiveString endp
  1468. ;------------------------------------------------------------------------ 
  1469. ; Attributes: bp-based frame
  1470. ; _stdcall KdpSendString(x, x)
  1471. KdpSendString proc near     ; CODE XREF: KdpSendControlPacket(x,x)+2Ep
  1472.                     ; KdSendPacket(x,x,x,x)+A0p ...
  1473. arg_0       = dword ptr  8
  1474. arg_4       = dword ptr  0Ch
  1475.         push    ebp
  1476.         mov ebp, esp
  1477.         push    edi
  1478.         mov edi, [ebp+arg_4]
  1479.         test    edi, edi
  1480.         jbe short loc_80010F0F
  1481.         push    esi
  1482.         mov esi, [ebp+arg_0]
  1483. loc_80010EFD:               ; CODE XREF: KdpSendString(x,x)+1Ej
  1484.         mov al, [esi]
  1485.         mov byte ptr [ebp+arg_4], al
  1486.         push    [ebp+arg_4]
  1487.         inc esi
  1488.         call     KdCompPutByte ; KdCompPutByte(x)
  1489.         dec edi
  1490.         jnz short loc_80010EFD
  1491.         pop esi
  1492. loc_80010F0F:               ; CODE XREF: KdpSendString(x,x)+9j
  1493.         pop edi
  1494.         pop ebp
  1495.         retn    8
  1496. KdpSendString endp
  1497. ;------------------------------------------------------------------------ 
  1498. ; Attributes: bp-based frame
  1499. ; _stdcall KdpSendControlPacket(x, x)
  1500. KdpSendControlPacket    proc near   ; CODE XREF: KdReceivePacket(x,x,x,x,x):loc_sendControlPacketAndWaitAgainp
  1501.                     ; KdReceivePacket(x,x,x,x,x)+232p ...
  1502. var_10      = dword ptr -10h
  1503. var_C       = word ptr -0Ch
  1504. var_A       = word ptr -0Ah
  1505. var_8       = dword ptr -8
  1506. var_4       = dword ptr -4
  1507. arg_0       = word ptr  8
  1508. arg_4       = dword ptr  0Ch
  1509.         push    ebp
  1510.         mov ebp, esp
  1511.         sub esp, 10h
  1512.         mov eax, [ebp+arg_4]
  1513.         test    eax, eax
  1514.         mov [ebp+var_10], 69696969h
  1515.         jz  short loc_80010F2B
  1516.         mov [ebp+var_8], eax
  1517. loc_80010F2B:               ; CODE XREF: KdpSendControlPacket(x,x)+12j
  1518.         mov ax, [ebp+arg_0]
  1519.         and [ebp+var_A], 0
  1520.         and [ebp+var_4], 0
  1521.         mov [ebp+var_C], ax
  1522.         push    10h
  1523.         lea eax, [ebp+var_10]
  1524.         push    eax
  1525.         call    KdpSendString ; KdpSendString(x,x)
  1526.         leave
  1527.         retn    8
  1528. KdpSendControlPacket    endp
  1529. ; -----------------------------------------------------------------------------------C
  1530.         align 4
  1531. ; Exported entry   5. KdReceivePacket
  1532. ;------------------------------------------------------------------------ 
  1533. ; Attributes: bp-based frame
  1534. ; _stdcall KdReceivePacket(x, x, x, x,  x)
  1535.         public KdReceivePacket
  1536. KdReceivePacket proc near       ; CODE XREF: KdSendPacket(x,x,x,x)+D8p
  1537. PacketLeader        = dword ptr -10h
  1538. vPacketType         = dword ptr -0Ch
  1539. vByteCount          = dword ptr -0Ah
  1540. vPacketId       = dword ptr -8
  1541. varCheckSum     = dword ptr -4
  1542. argPacketType       = dword ptr  8
  1543. arg_7       = dword ptr  0Fh
  1544. arg_C       = dword ptr  14h
  1545. lpKdContext     = dword ptr  18h
  1546.         
  1547.         push    ebp
  1548.         mov ebp, esp
  1549.         sub esp, 10h
  1550.         cmp [ebp+argPacketType], 8  ;PACKET_TYPE_KD_POLL_BREAKIN
  1551.         jnz short loc_NormalPacketType
  1552.         
  1553.         ;
  1554.         ;PACKET_TYPE_KD_POLL_BREAKIN
  1555.         ;
  1556.         lea eax, [ebp+arg_7]
  1557.         push    eax
  1558.         call     KdCompPollByte ; KdCompPollByte(x)
  1559.         test    eax, eax
  1560.         jnz short loc_recvPacketTimeOut
  1561.         cmp byte ptr [ebp+arg_7], 62h
  1562.         jz  loc_return
  1563. loc_recvPacketTimeOut:              ; CODE XREF: KdReceivePacket(x,x,x,x,x)+17j
  1564.         xor eax, eax
  1565.         inc eax             ;KDP_PACKET_TIMEOUT
  1566.         jmp loc_return
  1567. ; -----------------------------------------------------------------------------------C
  1568. loc_NormalPacketType:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+Aj
  1569.         push    ebx
  1570.         mov ebx, [ebp+arg_C]
  1571.         push    esi
  1572.         push    edi
  1573.         mov edi, [ebp+0Ch]
  1574. loc_WaitForPacketLeader:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+DEj
  1575.                     ; KdReceivePacket(x,x,x,x,x)+105j ...
  1576.         push    [ebp+lpKdContext]
  1577.         lea eax, [ebp+PacketLeader]
  1578.         push    eax
  1579.         push    [ebp+argPacketType]
  1580.         
  1581.         call    KdCompReceivePacketLeader ; KdCompReceivePacketLeader(x,x,x)
  1582.         
  1583.         movzx   eax, ax
  1584.         cmp eax, 1
  1585.         jz  short loc_RecvTimeout
  1586.         
  1587.         mov ecx, _KdCompRetryCount
  1588.         mov _KdCompNumberRetries, ecx
  1589. loc_RecvTimeout:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+49j
  1590.         test    eax, eax
  1591.         jnz     loc_return0
  1592.         
  1593.         ;
  1594.         ;Read packet type.
  1595.         ;
  1596.         
  1597.         push    2
  1598.         pop     esi
  1599.         push    esi
  1600.         lea     eax, [ebp+vPacketType]
  1601.         push    eax
  1602.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1603.         cmp     eax, 1      ;CP_GET_NODATA
  1604.         jz      loc_GetNoData
  1605.         
  1606.         cmp eax, esi    ;CP_GET_ERROR
  1607.         jz  short loc_GetStrError
  1608.         
  1609.         cmp [ebp+PacketLeader], 69696969h ;CONTROL_PACKET_LEADER
  1610.         jnz short loc_NotControlPacketLeader
  1611.         
  1612.         cmp word ptr [ebp+vPacketType], 5
  1613.         jz  loc_returnReSend
  1614. loc_NotControlPacketLeader:             ; CODE XREF: KdReceivePacket(x,x,x,x,x)+80j
  1615.         ;
  1616.         ; Read data length.
  1617.         ;
  1618.         push    esi
  1619.         lea eax, [ebp+vByteCount]
  1620.         push    eax
  1621.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1622.         cmp eax, 1
  1623.         jz  loc_GetNoData
  1624.         cmp eax, esi
  1625.         jz  short loc_GetStrError
  1626.         
  1627.         ;
  1628.         ;Read Packet Id.
  1629.         ;
  1630.         push    4
  1631.         pop esi
  1632.         push    esi
  1633.         lea eax, [ebp+vPacketId]
  1634.         push    eax
  1635.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1636.         cmp eax, 1
  1637.         jz  loc_GetNoData
  1638.         cmp eax, 2
  1639.         jz  short loc_GetStrError
  1640.         
  1641.         ;
  1642.         ; Read packet checksum.
  1643.         ;
  1644.         push    esi
  1645.         lea eax, [ebp+varCheckSum]
  1646.         push    eax
  1647.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1648.         cmp eax, 1
  1649.         jz  loc_GetNoData
  1650.         
  1651.         cmp eax, 2
  1652.         jnz short loc_cpGetDataOk
  1653. loc_GetStrError:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+77j
  1654.                     ; KdReceivePacket(x,x,x,x,x)+A2j ...
  1655.         cmp [ebp+PacketLeader], 69696969h
  1656.         jz  loc_WaitForPacketLeader
  1657.         jmp loc_SendControlPacketResend
  1658. ; -----------------------------------------------------------------------------------C
  1659. loc_cpGetDataOk:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+D5j
  1660.         cmp [ebp+PacketLeader], 69696969h
  1661.         jnz short loc_NotControlPacketLeader2
  1662.         
  1663.         cmp word ptr [ebp+vPacketType], si
  1664.         jnz short loc_notPacketTypeAcknowlodge
  1665.         
  1666.         mov eax, _KdCompNextPacketIdToSend
  1667.         and eax, 0FFFFF7FFh
  1668.         cmp [ebp+vPacketId], eax
  1669.         jnz loc_WaitForPacketLeader
  1670.         cmp [ebp+argPacketType], 4
  1671.         jnz loc_WaitForPacketLeader
  1672.         jmp loc_PacketTypeAcknowlege
  1673. ; -----------------------------------------------------------------------------------C
  1674. loc_notPacketTypeAcknowlodge:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+F6j
  1675.         cmp word ptr [ebp+vPacketType], 6
  1676.         jz  loc_vPacketTypeReset
  1677.         cmp word ptr [ebp+vPacketType], 5
  1678.         jnz loc_WaitForPacketLeader
  1679.         jmp loc_vPacketTypeResend
  1680. ; -----------------------------------------------------------------------------------C
  1681. loc_NotControlPacketLeader2:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+F0j
  1682.         cmp [ebp+argPacketType], esi
  1683.         jnz short loc_receivedvByteCountOk
  1684.         mov eax, [ebp+vPacketId]
  1685.         cmp eax, _KdCompPacketIdExpected
  1686.         jz  loc_SendResendControlPacket
  1687.         
  1688.         push    eax
  1689.         push    esi
  1690. loc_sendControlPacketAndWaitAgain:              ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1E1j
  1691.                                     ; KdReceivePacket(x,x,x,x,x)+211j
  1692.         call    KdpSendControlPacket    ; KdpSendControlPacket(x,x)
  1693.         jmp loc_WaitForPacketLeader
  1694. ; -----------------------------------------------------------------------------------C
  1695. loc_receivedvByteCountOk:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+138j
  1696.         cmp word ptr [ebp+vByteCount],  0FA0h
  1697.         movzx   esi, word ptr [edi+2]
  1698.         ja  loc_SendControlPacketResend
  1699.         
  1700.         cmp word ptr [ebp+vByteCount],  si
  1701.         jb  loc_SendControlPacketResend
  1702.         
  1703.         ;
  1704.         ;***Read the message header.
  1705.         ;
  1706.         movzx   eax, word ptr [ebp+vByteCount]
  1707.         sub eax, esi
  1708.         push    esi
  1709.         mov [ebx], eax
  1710.         push    dword ptr [edi+4]
  1711.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1712.         test    eax, eax
  1713.         jnz loc_SendControlPacketResend
  1714.         
  1715.         ;
  1716.         ; ***Read the message data.
  1717.         ;
  1718.         mov [edi], si
  1719.         push    dword ptr [ebx]
  1720.         mov esi, [ebp+arg_7+1]
  1721.         push    dword ptr [esi+4]
  1722.         call    KdpReceiveString ; KdpReceiveString(x,x)
  1723.         test    eax, eax
  1724.         jnz short loc_SendControlPacketResend
  1725.         
  1726.         ;
  1727.         ;****Get Tailing Byte
  1728.         ;
  1729.         mov ax, [ebx]
  1730.         mov [esi], ax
  1731.         lea eax, [ebp+arg_7]
  1732.         push    eax
  1733.         call     KdCompGetByte ; KdCompGetByte(x)
  1734.         test    eax, eax
  1735.         jnz short loc_SendControlPacketResend
  1736.         
  1737.         cmp byte ptr [ebp+arg_7], 0AAh
  1738.         jnz short loc_SendControlPacketResend
  1739.         
  1740.         movzx   eax, word ptr [ebp+vPacketType]
  1741.         cmp [ebp+argPacketType], eax
  1742.         jz  short loc_ReceivedPacketIdOk
  1743.         
  1744.         push    [ebp+vPacketId]
  1745.         jmp short loc_AcknowledgeAndWait
  1746. ; -----------------------------------------------------------------------------------C
  1747. loc_ReceivedPacketIdOk:             ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1BCj
  1748.         mov esi, [ebp+vPacketId]
  1749.         cmp esi, 80800000h      ;INITIAL_PACKET_ID
  1750.         jz  short loc_InitPacketId
  1751.         cmp esi, 80800001h      ;   INITIAL_PACKET_ID_1
  1752.         jnz short loc_SendControlPacketResend
  1753. loc_InitPacketId:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1CCj
  1754.         cmp esi, _KdCompPacketIdExpected
  1755.         jz  short loc_ComputeCheckSum
  1756.         
  1757.         push    esi
  1758. loc_AcknowledgeAndWait:             ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1C1j
  1759.         push    4
  1760.         jmp    loc_sendControlPacketAndWaitAgain
  1761. ; -----------------------------------------------------------------------------------C
  1762. loc_ComputeCheckSum:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1DCj
  1763.         mov eax, [ebp+arg_7+1]
  1764.         movzx   ecx, word ptr [eax]
  1765.         push    ecx
  1766.         push    dword ptr [eax+4]
  1767.         call    KdpComputeChecksum ;    KdpComputeChecksum(x,x)
  1768.         mov ebx, eax
  1769.         movzx   eax, word ptr [edi]
  1770.         push    eax
  1771.         push    dword ptr [edi+4]
  1772.         call    KdpComputeChecksum ;    KdpComputeChecksum(x,x)
  1773.         add ebx, eax
  1774.         cmp ebx, [ebp+varCheckSum]
  1775.         jz  short loc_SendAcknowledgePacket
  1776.         
  1777.         mov ebx, [ebp+arg_C]
  1778. loc_SendControlPacketResend:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+E4j
  1779.                     ; KdReceivePacket(x,x,x,x,x)+15Fj ...
  1780.         push    0
  1781.         push    5   ;PACKET_TYPE_KD_RESEND
  1782.         jmp loc_sendControlPacketAndWaitAgain
  1783. ; -----------------------------------------------------------------------------------C
  1784. loc_GetNoData:              ; CODE XREF: KdReceivePacket(x,x,x,x,x)+6Fj
  1785.                     ; KdReceivePacket(x,x,x,x,x)+9Aj ...
  1786.         xor eax, eax
  1787.         inc eax
  1788.         jmp short loc_return0
  1789. ; -----------------------------------------------------------------------------------C
  1790. loc_returnReSend:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+87j
  1791.         mov eax, esi
  1792.         jmp short loc_return0
  1793. ; -----------------------------------------------------------------------------------C
  1794. loc_vPacketTypeReset:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+11Fj
  1795.         mov eax, 80800000h
  1796.         push    0
  1797.         push    6
  1798.         mov _KdCompNextPacketIdToSend, eax
  1799.         mov _KdCompPacketIdExpected, eax
  1800.         call    KdpSendControlPacket    ; KdpSendControlPacket(x,x)
  1801. loc_vPacketTypeResend:              ; CODE XREF: KdReceivePacket(x,x,x,x,x)+130j
  1802.         push    2
  1803.         pop eax
  1804.         jmp short loc_return0
  1805. ; -----------------------------------------------------------------------------------C
  1806. loc_SendResendControlPacket:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+143j
  1807.         push    0
  1808.         push    5
  1809.         call    KdpSendControlPacket    ; KdpSendControlPacket(x,x)
  1810. loc_PacketTypeAcknowlege:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+115j
  1811.         xor _KdCompNextPacketIdToSend, 1
  1812.         jmp short loc_returnOk
  1813. ; -----------------------------------------------------------------------------------C
  1814. loc_SendAcknowledgePacket:              ; CODE XREF: KdReceivePacket(x,x,x,x,x)+208j
  1815.         push    esi
  1816.         push    4           ;PACKET_TYPE_KD_ACKNOWLEDGE
  1817.         call    KdpSendControlPacket    ; KdpSendControlPacket(x,x)
  1818.         xor _KdCompPacketIdExpected, 1
  1819. loc_returnOk:               ; CODE XREF: KdReceivePacket(x,x,x,x,x)+24Cj
  1820.         xor eax, eax
  1821. loc_return0:                ; CODE XREF: KdReceivePacket(x,x,x,x,x)+59j
  1822.                     ; KdReceivePacket(x,x,x,x,x)+219j ...
  1823.         pop edi
  1824.         pop esi
  1825.         pop ebx
  1826. loc_return:         ; CODE XREF: KdReceivePacket(x,x,x,x,x)+1Dj
  1827.                     ; KdReceivePacket(x,x,x,x,x)+26j
  1828.         leave
  1829.         retn    14h
  1830. KdReceivePacket endp
  1831. ; Exported entry   8. KdSendPacket
  1832. ;------------------------------------------------------------------------ 
  1833. ; Attributes: bp-based frame
  1834. ; _stdcall KdSendPacket(x, x, x, x)
  1835.         public KdSendPacket
  1836. KdSendPacket proc near
  1837. vPacketLeader   = dword ptr -10h
  1838. vPacketType     = word ptr -0Ch
  1839. vByteCount      = word ptr -0Ah
  1840. vPacketId       = dword ptr -8
  1841. vCheckSum       = dword ptr -4
  1842. ArgPacketType   = dword ptr  8
  1843. MessageHeader   = dword ptr  0Ch
  1844. MessageData     = dword ptr  10h
  1845. KdContext       = dword ptr  14h
  1846.         
  1847.     
  1848.         push    ebp
  1849.         mov ebp, esp
  1850.         sub esp, 10h
  1851.         mov eax, [ebp+MessageData]
  1852.         push    ebx
  1853.         xor ebx, ebx
  1854.         cmp eax, ebx
  1855.         push    esi
  1856.         push    edi
  1857.         jz  short loc_noMessageData
  1858.         
  1859.         movzx   ebx, word ptr [eax]
  1860.         push    ebx
  1861.         push    dword ptr [eax+4]
  1862.         call    KdpComputeChecksum ;    KdpComputeChecksum(x,x)
  1863.         
  1864.         mov [ebp+vCheckSum], eax
  1865.         jmp short loc_computeHeaderCheckSum
  1866. ; -----------------------------------------------------------------------------------C
  1867. loc_noMessageData:              ; CODE XREF: KdSendPacket(x,x,x,x)+10j
  1868.         mov [ebp+vCheckSum], ebx
  1869. loc_computeHeaderCheckSum:              ; CODE XREF: KdSendPacket(x,x,x,x)+21j
  1870.         mov esi, [ebp+MessageHeader]
  1871.         mov di, [esi]
  1872.         movzx   eax, di
  1873.         push    eax
  1874.         push    dword ptr [esi+4]
  1875.         call    KdpComputeChecksum ;    KdpComputeChecksum(x,x)
  1876.         add [ebp+vCheckSum], eax
  1877.         mov eax, _KdCompRetryCount
  1878.         add edi, ebx
  1879.         mov [ebp+var_A], di
  1880.         mov edi, [ebp+ArgPacketType]
  1881.         mov [ebp+vPacketLeader], 30303030h
  1882.         mov [ebp+vPacketType], di
  1883.         mov _KdCompNumberRetries, eax
  1884. loc_loopSendData:               ; CODE XREF: KdSendPacket(x,x,x,x)+EAj
  1885.         cmp _KdCompNumberRetries, 0
  1886.         jnz short loc_normalSendString
  1887.         ;
  1888.         ; If the packet is not for reporting exception, we give up
  1889.         ; and declare debugger not present.
  1890.         ;
  1891.         
  1892.         cmp edi, 3          ;cmp edi, PACKET_TYPE_KD_DEBUG_IO
  1893.         jnz short loc_notPacketTypeDebugIo
  1894.     
  1895.         mov eax, [esi+4]            ;DebugIo->ApiNumber 
  1896.         cmp dword ptr [eax], 3230h  ;#define DbgKdPrintStringApi                 0x00003230
  1897.         jmp short loc_checkApiNumber
  1898. ; -----------------------------------------------------------------------------------C
  1899. loc_notPacketTypeDebugIo:               ; CODE XREF: KdSendPacket(x,x,x,x)+65j
  1900.         cmp edi, 7                  ;PACKET_TYPE_KD_STATE_CHANGE64 
  1901.         jnz short loc_notKdstateChange64
  1902.         
  1903.         mov eax, [esi+4]
  1904.         cmp dword ptr [eax], 3031h  ;#define DbgKdLoadSymbolsStateChange         0x00003031
  1905.         jmp short loc_checkApiNumber
  1906. ; -----------------------------------------------------------------------------------C
  1907. loc_notKdstateChange64:             ; CODE XREF: KdSendPacket(x,x,x,x)+75j
  1908.         cmp edi, 0Bh                ; PACKET_TYPE_KD_FILE_IO              11
  1909.         jnz short loc_normalSendString
  1910.         mov eax, [esi+4]
  1911.         cmp dword ptr [eax], 3430h  ;DbgKdCreateFileApi
  1912. loc_checkApiNumber:             ; CODE XREF: KdSendPacket(x,x,x,x)+70j
  1913.                     ; KdSendPacket(x,x,x,x)+80j
  1914.         jz  short loc_MarkDisableDuggerAndReturn
  1915. loc_normalSendString:               ; CODE XREF: KdSendPacket(x,x,x,x)+60j
  1916.                     ; KdSendPacket(x,x,x,x)+85j
  1917.         mov eax, _KdCompNextPacketIdToSend
  1918.         mov [ebp+vPacketId], eax
  1919.         
  1920.         push    10h
  1921.         lea eax, [ebp+vPacketLeader]
  1922.         push    eax
  1923.         call    KdpSendString ; KdpSendString(x,x)
  1924.         
  1925.         movzx   eax, word ptr [esi]
  1926.         push    eax
  1927.         push    dword ptr [esi+4]
  1928.         call    KdpSendString ; KdpSendString(x,x)
  1929.         
  1930.         test    ebx, ebx
  1931.         jz  short loc_sendTailingByte
  1932.         mov eax, [ebp+MessageData]
  1933.         movzx   ecx, word ptr [eax]
  1934.         push    ecx
  1935.         push    dword ptr [eax+4]
  1936.         call    KdpSendString ; KdpSendString(x,x)
  1937. loc_sendTailingByte:                ; CODE XREF: KdSendPacket(x,x,x,x)+B3j
  1938.         push    0AAh
  1939.         call     KdCompPutByte ; KdCompPutByte(x)
  1940.         push    [ebp+KdContext]
  1941.         xor eax, eax
  1942.         push    eax
  1943.         push    eax
  1944.         push    eax
  1945.         push    4
  1946.         call    KdReceivePacket ; KdReceivePacket(x,x,x,x,x)
  1947.         cmp eax, 1
  1948.         jnz short loc_receiveNotTimeOut
  1949.         
  1950.         dec _KdCompNumberRetries
  1951. loc_receiveNotTimeOut:              ; CODE XREF: KdSendPacket(x,x,x,x)+E0j
  1952.         test    eax, eax
  1953.         jnz loc_loopSendData            ;jump upon looOOOOOOp....
  1954.         
  1955.         ;Send Ok
  1956.         ;
  1957.         mov eax, [ebp+KdContext]
  1958.         
  1959.         ;
  1960.         ; Reset Sync bit in packet id.  The packet we sent may have Sync bit set
  1961.         ;
  1962.         ;
  1963.         and byte_MsrLastValue, 0F7h ; KdpNextPacketIdToSend &= ~SYNC_PACKET_ID;
  1964.         mov eax, [eax]
  1965.         mov _KdCompRetryCount, eax
  1966. loc_return:             ; CODE XREF: KdSendPacket(x,x,x,x)+12Bj
  1967.         pop edi
  1968.         pop esi
  1969.         pop ebx
  1970.         leave
  1971.         retn    10h
  1972. ; -----------------------------------------------------------------------------------C
  1973. loc_MarkDisableDuggerAndReturn:             ; CODE XREF: KdSendPacket(x,x,x,x):loc_80011242j
  1974.         mov eax, dword ptr ds:[KdDebuggerNotPresent]
  1975.         mov byte ptr [eax], 1
  1976.         
  1977.         
  1978.         and byte ptr ds:[0FFDF02D4h],   0FDh
  1979.         mov _KdCompNextPacketIdToSend,  80800800h
  1980.         mov _KdCompPacketIdExpected,    80800000h
  1981.         jmp short loc_return
  1982. KdSendPacket endp
  1983. ; -----------------------------------------------------------------------------------C
  1984. PAGEKD      ends
  1985. end DllEntryPoint

另外我结合了win2k的源代和reactos的代码,编译了部分成C语言,下面顺合给出这个文件kdcomio.c以供研究.
你可以使用将C言语实现过的函数从上面的asm代码中出除,然后使用以下命令混合编译ASM和C语言生成一个可用的kdcom.dll,
这个我也已经测试成的.假设你安装了RadAsm和VS或DDK,生成的命令如下:


  1. @rem build.bat
  2. E:/WINDDK/2600/bin/x86/ML.EXE /nologo /c /Gz /coff /I"C:/RadASM/Masm32/Include" "kdcom.asm"
  3. E:/WINDDK/2600/bin/x86/CL.EXE /c /Od /W3 /TC /Gz  "kdcomio.c"
  4. E:/WINDDK/2600/bin/x86/LINK.EXE /nologo /driver /base:0x80010000 /subsystem:native /NODEFAULTLIB:LIBC.lib /NODEFAULTLIB:OLDNAMES.lib  /align:128 /libpath:C:/RadASM/masm32/lib/w2k /entry:DllEntryPoint /DEF:kdcom.Def /out:"kdcom.dll" "kdcom.obj" "kdcomio.obj"
  5. pause

 

 

 

 

  1. /**
  2.     kdcomio.c 
  3.     Create by Aerror
  4. */
  5. #define IN 
  6. #define OUT
  7. #define IN_OUT 
  8. #define OPTIONAL
  9. #define FALSE  0  
  10. #define TRUE   1  
  11. #define NULL 0
  12. #define PACKET_MAX_SIZE           0x0FA0
  13. #define DBGKD_MAXSTREAM                     16
  14. #define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
  15. #define CP_GET_SUCCESS  0
  16. #define CP_GET_NODATA   1
  17. #define CP_GET_ERROR    2
  18. #define KDP_PACKET_RECEIVED 0
  19. #define KDP_PACKET_TIMEOUT 1
  20. #define KDP_PACKET_RESEND  2
  21. #define PACKET_LEADER_BYTE     0x30
  22. #define PACKET_LEADER        0x30303030
  23. #define CONTROL_PACKET_LEADER_BYTE 0x69
  24. #define CONTROL_PACKET_LEADER      0x69696969
  25. #define BREAKIN_PACKET_BYTE     0x62
  26. #define BREAKIN_PACKET             0x62626262
  27. #define PACKET_TRAILING_BYTE    0xAA
  28. #define DbgKdPrintStringApi                 0x00003230
  29. #define DbgKdGetStringApi                   0x00003231
  30. //
  31. // Wait State Change Types
  32. //
  33. #define DbgKdMinimumStateChange             0x00003030
  34. #define DbgKdExceptionStateChange           0x00003030
  35. #define DbgKdLoadSymbolsStateChange         0x00003031
  36. #define DbgKdCommandStringStateChange       0x00003032
  37. #define DbgKdMaximumStateChange             0x00003033
  38. //
  39. // Manipulate Types
  40. //
  41. #define DbgKdMinimumManipulate              0x00003130
  42. #define DbgKdReadVirtualMemoryApi           0x00003130
  43. #define DbgKdWriteVirtualMemoryApi          0x00003131
  44. #define DbgKdGetContextApi                  0x00003132
  45. #define DbgKdSetContextApi                  0x00003133
  46. #define DbgKdWriteBreakPointApi             0x00003134
  47. #define DbgKdRestoreBreakPointApi           0x00003135
  48. #define DbgKdContinueApi                    0x00003136
  49. #define DbgKdReadControlSpaceApi            0x00003137
  50. #define DbgKdWriteControlSpaceApi           0x00003138
  51. #define DbgKdReadIoSpaceApi                 0x00003139
  52. #define DbgKdWriteIoSpaceApi                0x0000313A
  53. #define DbgKdRebootApi                      0x0000313B
  54. #define DbgKdContinueApi2                   0x0000313C
  55. #define DbgKdReadPhysicalMemoryApi          0x0000313D
  56. #define DbgKdWritePhysicalMemoryApi         0x0000313E
  57. #define DbgKdQuerySpecialCallsApi           0x0000313F
  58. #define DbgKdSetSpecialCallApi              0x00003140
  59. #define DbgKdClearSpecialCallsApi           0x00003141
  60. #define DbgKdSetInternalBreakPointApi       0x00003142
  61. #define DbgKdGetInternalBreakPointApi       0x00003143
  62. #define DbgKdReadIoSpaceExtendedApi         0x00003144
  63. #define DbgKdWriteIoSpaceExtendedApi        0x00003145
  64. #define DbgKdGetVersionApi                  0x00003146
  65. #define DbgKdWriteBreakPointExApi           0x00003147
  66. #define DbgKdRestoreBreakPointExApi         0x00003148
  67. #define DbgKdCauseBugCheckApi               0x00003149
  68. #define DbgKdSwitchProcessor                0x00003150
  69. #define DbgKdPageInApi                      0x00003151
  70. #define DbgKdReadMachineSpecificRegister    0x00003152
  71. #define DbgKdWriteMachineSpecificRegister   0x00003153
  72. #define OldVlm1                             0x00003154
  73. #define OldVlm2                             0x00003155
  74. #define DbgKdSearchMemoryApi                0x00003156
  75. #define DbgKdGetBusDataApi                  0x00003157
  76. #define DbgKdSetBusDataApi                  0x00003158
  77. #define DbgKdCheckLowMemoryApi              0x00003159
  78. #define DbgKdClearAllInternalBreakpointsApi 0x0000315A
  79. #define DbgKdFillMemoryApi                  0x0000315B
  80. #define DbgKdQueryMemoryApi                 0x0000315C
  81. #define DbgKdSwitchPartition                0x0000315D
  82. #define DbgKdMaximumManipulate              0x0000315E
  83. //
  84. // Debug I/O Types
  85. //
  86. #define DbgKdPrintStringApi                 0x00003230
  87. #define DbgKdGetStringApi                   0x00003231
  88. //
  89. // Control Report Flags
  90. //
  91. #define REPORT_INCLUDES_SEGS                0x0001
  92. #define REPORT_INCLUDES_CS                  0x0002
  93. #define INITIAL_PACKET_ID      0x80800000
  94. #define INITIAL_PACKET_ID_1     0x80800001
  95. #define SYNC_PACKET_ID      0x0800
  96. #define PACKET_TYPE_UNUSED                  0
  97. #define PACKET_TYPE_KD_STATE_CHANGE32       1
  98. #define PACKET_TYPE_KD_STATE_MANIPULATE     2
  99. #define PACKET_TYPE_KD_DEBUG_IO             3
  100. #define PACKET_TYPE_KD_ACKNOWLEDGE          4
  101. #define PACKET_TYPE_KD_RESEND               5
  102. #define PACKET_TYPE_KD_RESET                6
  103. #define PACKET_TYPE_KD_STATE_CHANGE64       7
  104. #define PACKET_TYPE_KD_POLL_BREAKIN         8
  105. #define PACKET_TYPE_KD_TRACE_IO             9
  106. #define PACKET_TYPE_KD_CONTROL_REQUEST      10
  107. #define PACKET_TYPE_KD_FILE_IO              11
  108. #define PACKET_TYPE_MAX                     12
  109. #define ARGUMENT_PRESENT(ArgumentPointer)    (/
  110.     (CHAR *)(ArgumentPointer) != (CHAR *)(NULL) )
  111.     
  112.                         
  113. typedef   unsigned int   ULONG ;
  114. typedef   ULONG*     PULONG;
  115. typedef   unsigned char  UCHAR;
  116. typedef   UCHAR*     PUCHAR;
  117. typedef   unsigned short  USHORT;
  118. typedef   unsigned shortPUSHORT;
  119. typedef  char*      PCHAR;
  120. typedef  char      CHAR;
  121. typedef   void      VOID;
  122. typedef   void*      PVOID;
  123. typedef  unsigned char  BOOLEAN;
  124. typedef   long LONG_PTR, *PLONG_PTR;
  125. typedef   long ULONG_PTR, *PULONG_PTR;
  126. typedef  unsigned _int64 ULONGLONG;
  127. typedef  ULONGLONG    ULONG64;
  128. typedef struct _STRING {
  129.     USHORT Length;
  130.     USHORT MaximumLength;
  131.     PCHAR Buffer;
  132. } STRING;
  133. typedef STRING *PSTRING;
  134. typedef struct _KD_CONTEXT
  135. {
  136.  ULONG   RetryCount;
  137.  BOOLEAN BreakInRequested;
  138. } KD_CONTEXT, * PKD_CONTEXT;
  139. typedef struct _KSYSTEM_TIME{
  140.  ULONG LowPart           ; //+0x000
  141.  ULONG High1Time ;//       : Int4B
  142.  ULONG High2Time ;//       : Int4B
  143. }KSYSTEM_TIME;
  144. typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
  145. {
  146.    StandardDesign = 0,
  147.    NEC98x86 = 1,
  148.    EndAlternatives = 2
  149. }ALTERNATIVE_ARCHITECTURE_TYPE;
  150.   
  151. typedef enum _NT_PRODUCT_TYPE{
  152.    NtProductWinNt = 1,
  153.    NtProductLanManNt = 2,
  154.    NtProductServer = 3,
  155. }NT_PRODUCT_TYPE;
  156. typedef struct _LARGE_INTEGER{
  157.   ULONG LowPart          ;// Uint4B
  158.   ULONG  HighPart         ;// Int4B
  159. }LARGE_INTEGER;
  160.     
  161.     
  162. #define MAXIMUM_SUPPORTED_EXTENSION     512
  163. #define SIZE_OF_80387_REGISTERS      80
  164. typedef struct _FLOATING_SAVE_AREA {
  165.     ULONG   ControlWord;
  166.     ULONG   StatusWord;
  167.     ULONG   TagWord;
  168.     ULONG   ErrorOffset;
  169.     ULONG   ErrorSelector;
  170.     ULONG   DataOffset;
  171.     ULONG   DataSelector;
  172.     UCHAR    RegisterArea[SIZE_OF_80387_REGISTERS];
  173.     ULONG   Cr0NpxState;
  174. } FLOATING_SAVE_AREA;
  175. typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
  176. typedef struct _CONTEXT {
  177.     //
  178.     // The flags values within this flag control the contents of
  179.     // a CONTEXT record.
  180.     //
  181.     // If the context record is used as an input parameter, then
  182.     // for each portion of the context record controlled by a flag
  183.     // whose value is set, it is assumed that that portion of the
  184.     // context record contains valid context. If the context record
  185.     // is being used to modify a threads context, then only that
  186.     // portion of the threads context will be modified.
  187.     //
  188.     // If the context record is used as an IN OUT parameter to capture
  189.     // the context of a thread, then only those portions of the thread's
  190.     // context corresponding to set flags will be returned.
  191.     //
  192.     // The context record is never used as an OUT only parameter.
  193.     //
  194.     ULONG ContextFlags;
  195.     //
  196.     // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  197.     // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
  198.     // included in CONTEXT_FULL.
  199.     //
  200.     ULONG   Dr0;
  201.     ULONG   Dr1;
  202.     ULONG   Dr2;
  203.     ULONG   Dr3;
  204.     ULONG   Dr6;
  205.     ULONG   Dr7;
  206.     //
  207.     // This section is specified/returned if the
  208.     // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
  209.     //
  210.     FLOATING_SAVE_AREA FloatSave;
  211.     //
  212.     // This section is specified/returned if the
  213.     // ContextFlags word contians the flag CONTEXT_SEGMENTS.
  214.     //
  215.     ULONG   SegGs;
  216.     ULONG   SegFs;
  217.     ULONG   SegEs;
  218.     ULONG   SegDs;
  219.     //
  220.     // This section is specified/returned if the
  221.     // ContextFlags word contians the flag CONTEXT_INTEGER.
  222.     //
  223.     ULONG   Edi;
  224.     ULONG   Esi;
  225.     ULONG   Ebx;
  226.     ULONG   Edx;
  227.     ULONG   Ecx;
  228.     ULONG   Eax;
  229.     //
  230.     // This section is specified/returned if the
  231.     // ContextFlags word contians the flag CONTEXT_CONTROL.
  232.     //
  233.     ULONG   Ebp;
  234.     ULONG   Eip;
  235.     ULONG   SegCs;              // MUST BE SANITIZED
  236.     ULONG   EFlags;             // MUST BE SANITIZED
  237.     ULONG   Esp;
  238.     ULONG   SegSs;
  239.     //
  240.     // This section is specified/returned if the ContextFlags word
  241.     // contains the flag CONTEXT_EXTENDED_REGISTERS.
  242.     // The format and contexts are processor specific
  243.     //
  244.     UCHAR    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
  245. } CONTEXT;
  246.    
  247. typedef struct _EXCEPTION_RECORD64 {
  248.     ULONG    ExceptionCode;
  249.     ULONG ExceptionFlags;
  250.     ULONG64 ExceptionRecord;
  251.     ULONG64 ExceptionAddress;
  252.     ULONG NumberParameters;
  253.     ULONG __unusedAlignment;
  254.     ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
  255. } EXCEPTION_RECORD64, *PEXCEPTION_RECORD64;
  256. //
  257. // DBGKM Structure for Exceptions
  258. //
  259. typedef struct _DBGKM_EXCEPTION64
  260. {
  261.     EXCEPTION_RECORD64 ExceptionRecord;
  262.     ULONG FirstChance;
  263. } DBGKM_EXCEPTION64, *PDBGKM_EXCEPTION64;
  264. //
  265. // DBGKD Structure for State Change
  266. //
  267. typedef struct _DBGKD_CONTROL_REPORT
  268. {
  269.     ULONG Dr6;
  270.     ULONG Dr7;
  271.     USHORT InstructionCount;
  272.     USHORT ReportFlags;
  273.     UCHAR InstructionStream[DBGKD_MAXSTREAM];
  274.     USHORT SegCs;
  275.     USHORT SegDs;
  276.     USHORT SegEs;
  277.     USHORT SegFs;
  278.     ULONG EFlags;
  279. } DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
  280. //
  281. // DBGKD Structure for Debug I/O Type Print String
  282. //
  283. typedef struct _DBGKD_PRINT_STRING
  284. {
  285.     ULONG LengthOfString;
  286. } DBGKD_PRINT_STRING, *PDBGKD_PRINT_STRING;
  287. //
  288. // DBGKD Structure for Debug I/O Type Get String
  289. //
  290. typedef struct _DBGKD_GET_STRING
  291. {
  292.     ULONG LengthOfPromptString;
  293.     ULONG LengthOfStringRead;
  294. } DBGKD_GET_STRING, *PDBGKD_GET_STRING;
  295. //
  296. // DBGKD Structure for Load Symbols
  297. //
  298. typedef struct _DBGKD_LOAD_SYMBOLS64
  299. {
  300.     ULONG PathNameLength;
  301.     ULONG64 BaseOfDll;
  302.     ULONG64 ProcessId;
  303.     ULONG CheckSum;
  304.     ULONG SizeOfImage;
  305.     BOOLEAN UnloadSymbols;
  306. } DBGKD_LOAD_SYMBOLS64, *PDBGKD_LOAD_SYMBOLS64;
  307. typedef struct _KUSER_SHARED_DATA
  308. {
  309. ULONG TickCountLow      ; //+0x000
  310. ULONG TickCountMultiplier  ; //+0x004
  311. KSYSTEM_TIME InterruptTime     ; //+0x008
  312. KSYSTEM_TIME SystemTime        ; //+0x014
  313. KSYSTEM_TIME TimeZoneBias      ; //+0x020
  314. USHORT ImageNumberLow    ; //+0x02c
  315. USHORT ImageNumberHigh   ; //+0x02e
  316.  USHORT NtSystemRoot [260]     ; //+0x030
  317. ULONG MaxStackTraceDepth  ; //+0x238
  318. ULONG CryptoExponent    ; //+0x23c
  319. ULONG TimeZoneId        ; //+0x240
  320. ULONG Reserved2[8]          ; //+0x244
  321. NT_PRODUCT_TYPE NtProductType     ; //+0x264
  322. UCHAR ProductTypeIsValid  ; //+0x268
  323. ULONG NtMajorVersion    ; //+0x26c
  324. ULONG NtMinorVersion    ; //+0x270
  325. UCHAR ProcessorFeatures[64]   ; //+0x274
  326. ULONG Reserved1         ; //+0x2b4
  327. ULONG Reserved3         ; //+0x2b8
  328. ULONG TimeSlip          ; //+0x2bc
  329. ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture  ; //+0x2c0
  330. LARGE_INTEGER SystemExpirationDate  ; //+0x2c8
  331. ULONG SuiteMask         ; //+0x2d0
  332. UCHAR KdDebuggerEnabled  ; //+0x2d4
  333. UCHAR NXSupportPolicy   ; //+0x2d5
  334. ULONG ActiveConsoleId   ; //+0x2d8
  335. ULONG DismountCount     ; //+0x2dc
  336. ULONG ComPlusPackage    ; //+0x2e0
  337. ULONG LastSystemRITEventTickCount  ; //+0x2e4
  338. ULONG NumberOfPhysicalPages  ; //+0x2e8
  339. UCHAR SafeBootMode      ; //+0x2ec
  340. ULONG TraceLogging      ; //+0x2f0
  341. ULONGLONG TestRetInstruction  ; //+0x2f8
  342. ULONG SystemCall        ; //+0x300
  343. ULONG SystemCallReturn  ; //+0x304
  344. ULONGLONG SystemCallPad[3]     ; //+0x308
  345. KSYSTEM_TIME TickCount         ; //+0x320
  346. ULONGLONG TickCountQuad     ; //+0x320
  347. ULONG Cookie            ; //+0x330
  348. }KUSER_SHARED_DATA;
  349. typedef struct _KD_PACKET
  350. {
  351.   ULONG PacketLeader ; 
  352.   USHORT  PacketType ; 
  353.   USHORT byteCount  ;
  354.   ULONG PacketId  ;
  355.   ULONG Checksum  ;
  356. }KD_PACKET;
  357. typedef struct _DBGKD_DEBUG_IO
  358. {
  359.     ULONG ApiNumber;
  360.     USHORT ProcessorLevel;
  361.     USHORT Processor;
  362.     union
  363.     {
  364.         DBGKD_PRINT_STRING PrintString;
  365.         DBGKD_GET_STRING GetString;
  366.     } u;
  367. } DBGKD_DEBUG_IO, *PDBGKD_DEBUG_IO;
  368. typedef struct _DBGKD_WAIT_STATE_CHANGE64
  369. {
  370.     ULONG NewState;
  371.     USHORT ProcessorLevel;
  372.     USHORT Processor;
  373.     ULONG NumberProcessors;
  374.     ULONG64 Thread;
  375.     ULONG64 ProgramCounter;
  376.     union
  377.     {
  378.         DBGKM_EXCEPTION64 Exception;
  379.         DBGKD_LOAD_SYMBOLS64 LoadSymbols;
  380.     } u;
  381.     DBGKD_CONTROL_REPORT ControlReport;
  382.     CONTEXT Context;
  383. } DBGKD_WAIT_STATE_CHANGE64, *PDBGKD_WAIT_STATE_CHANGE64;
  384.  //
  385.  // If the packet type is PACKET_TYPE_KD_FILE_IO, then
  386.  // the format of the packet data is as follows:
  387.  //
  388.  #define DbgKdCreateFileApi 0x00003430L
  389.  #define DbgKdReadFileApi 0x00003431L
  390.  #define DbgKdWriteFileApi 0x00003432L
  391.  #define DbgKdCloseFileApi 0x00003433L
  392.  // Unicode filename follows as additional data.
  393.  typedef struct _DBGKD_CREATE_FILE {
  394.   ULONG DesiredAccess;
  395.   ULONG FileAttributes;
  396.   ULONG ShareAccess;
  397.   ULONG CreateDisposition;
  398.   ULONG CreateOptions;
  399.   // Return values.
  400.   ULONG64 Handle;
  401.   ULONG64 Length;
  402.  } DBGKD_CREATE_FILE, *PDBGKD_CREATE_FILE;
  403.  // Data is returned as additional data in the response.
  404.  typedef struct _DBGKD_READ_FILE {
  405.   ULONG64 Handle;
  406.   ULONG64 Offset;
  407.   ULONG Length;
  408.  } DBGKD_READ_FILE, *PDBGKD_READ_FILE;
  409.  // Data is given as additional data.
  410.  typedef struct _DBGKD_WRITE_FILE {
  411.   ULONG64 Handle;
  412.   ULONG64 Offset;
  413.   ULONG Length;
  414.  } DBGKD_WRITE_FILE, *PDBGKD_WRITE_FILE;
  415.  typedef struct _DBGKD_CLOSE_FILE {
  416.  ULONG64 Handle;
  417.  } DBGKD_CLOSE_FILE, *PDBGKD_CLOSE_FILE;
  418.  typedef struct _DBGKD_FILE_IO {
  419.   ULONG ApiNumber;
  420.   ULONG Status;
  421.   union {
  422.    ULONG64 ReserveSpace[7];
  423.    DBGKD_CREATE_FILE CreateFile;
  424.    DBGKD_READ_FILE ReadFile;
  425.    DBGKD_WRITE_FILE WriteFile;
  426.    DBGKD_CLOSE_FILE CloseFile;
  427.   } u;
  428.  } DBGKD_FILE_IO, *PDBGKD_FILE_IO;
  429. #define KI_USER_SHARED_DATA         0xffdf0000
  430. #define SharedUserData  ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA)
  431. extern BOOLEAN KdDebuggerNotPresent;
  432. BOOLEAN KdpControlCPending    = FALSE;
  433. BOOLEAN KdpControlCPressed    = FALSE;
  434. ULONG KdpRetryCount      = 5;
  435. ULONG KdpNumberRetries     = 5;
  436. ULONG KdpPacketIdExpected   =0;
  437. ULONG KdpNextPacketIdToSend =0;
  438. //ULONG  KdpDefaultRetries   =0;
  439. //--------------------------------
  440. ULONG
  441. KdCompGetByte (
  442.     OUT PUCHAR Input 
  443.     );
  444. ULONG
  445. KdCompPollByte (
  446.     OUT PUCHAR Input
  447.     );
  448. VOID
  449. KdCompPutByte (
  450.     IN UCHAR Output
  451.     );
  452.     
  453. ULONG
  454. KdpComputeChecksum (
  455.     IN PUCHAR Buffer,
  456.     IN ULONG Length
  457.     );
  458. ULONG
  459. KdpReceiveString (
  460.     OUT PCHAR Destination,
  461.     IN ULONG Length
  462.     );
  463. VOID
  464. KdpSendString (
  465.     IN PCHAR Source,
  466.     IN ULONG Length
  467.     );
  468. VOID
  469. KdpSendControlPacket (
  470.     IN USHORT PacketType,
  471.     IN ULONG PacketId OPTIONAL
  472.     );
  473. #ifdef ALLOC_PRAGMA
  474. #pragma alloc_text(PAGEKD, KdpComputeChecksum)
  475. #pragma alloc_text(PAGEKD, KdpReceivePacketLeader)
  476. #pragma alloc_text(PAGEKD, KdpReceiveString)
  477. #pragma alloc_text(PAGEKD, KdpSendString)
  478. #pragma alloc_text(PAGEKD, KdpSendControlPacket)
  479. #pragma alloc_text(PAGEKD, KdReceivePacket)
  480. #pragma alloc_text(PAGEKD, KdSendPacket)
  481. #endif
  482. ULONG
  483. KdpComputeChecksum (
  484.     IN PUCHAR Buffer,
  485.     IN ULONG Length
  486.     )
  487. /*++
  488. Routine Description:
  489.     This routine computes the checksum for the string passed in.
  490. Arguments:
  491.     Buffer - Supplies a pointer to the string.
  492.     Length - Supplies the length of the string.
  493. Return Value:
  494.     A ULONG is return as the checksum for the input string.
  495. --*/
  496. {
  497.     ULONG Checksum = 0;
  498.     while (Length > 0) {
  499.         Checksum = Checksum + (ULONG)*Buffer++;
  500.         Length--;
  501.     }
  502.     return Checksum;
  503. }
  504. USHORT
  505. KdpReceivePacketLeader (
  506.     IN ULONG PacketType,
  507.     OUT PULONG PacketLeader,
  508.     IN_OUT PKD_CONTEXT KdContext OPTIONAL 
  509.     )
  510. /*++
  511. Routine Description:
  512.     This routine waits for a packet header leader.
  513. Arguments:
  514.     PacketType - supplies the type of packet we are expecting.
  515.     PacketLeader - supplies a pointer to a ulong variable to receive
  516.                    packet leader UCHARs.
  517. Return Value:
  518.     KDP_PACKET_RESEND - if resend is required.
  519.     KDP_PAKCET_TIMEOUT - if timeout.
  520.     KDP_PACKET_RECEIVED - if packet received.
  521. --*/
  522. {
  523.     UCHAR Input, PreviousUCHAR = 0;
  524.     ULONG PacketId = 0;
  525.     ULONG Index;
  526.     ULONG ReturnCode;
  527.     BOOLEAN BreakinDetected = FALSE;
  528.     if(KdContext)
  529.     {
  530.   KdContext->BreakInRequested = BreakinDetected;
  531.  }
  532.     //
  533.     // NOTE - With all the interrupts being off, it is very hard
  534.     // to implement the actual timeout code. (Maybe, by reading the CMOS.)
  535.     // Here we use a loop count to wait about 3 seconds.  The CpGetUCHAR
  536.     // will return with error code = CP_GET_NODATA if it cannot find data
  537.     // UCHAR within 1 second. Kernel debugger's timeout period is 5 seconds.
  538.     //
  539.     Index = 0;
  540.     do {
  541.         ReturnCode = KdCompGetByte(&Input);
  542.         
  543.   if (ReturnCode == CP_GET_NODATA) {
  544.             if (BreakinDetected) {
  545.                 KdpControlCPending = TRUE;
  546.                 if(KdContext)
  547.     {
  548.      KdContext->BreakInRequested = BreakinDetected;
  549.     }
  550.                 return KDP_PACKET_RESEND;
  551.             } else {
  552.     if(KdContext)
  553.     {
  554.      KdContext->BreakInRequested = BreakinDetected;
  555.     }
  556.                 return KDP_PACKET_TIMEOUT;
  557.             }
  558.         }
  559.   else if (ReturnCode == CP_GET_ERROR) {
  560.             Index = 0;
  561.             continue;
  562.         } 
  563.   else {                    // if (ReturnCode == CP_GET_SUCCESS)
  564.             if ( Input == PACKET_LEADER_BYTE ||
  565.                  Input == CONTROL_PACKET_LEADER_BYTE ) {
  566.                 if ( Index == 0 ) {
  567.                     PreviousUCHAR = Input;
  568.                     Index++;
  569.                 } else if (Input == PreviousUCHAR ) {
  570.                     Index++;
  571.                 } else {
  572.                     PreviousUCHAR = Input;
  573.                     Index = 1;
  574.                 }
  575.             } else {
  576.                 //
  577.                 // If we detect breakin character, we need to verify it
  578.                 // validity.  (It is possible that we missed a packet leader
  579.                 // and the breakin character is simply a data UCHAR in the
  580.                 // packet.)
  581.                 // Since kernel debugger send out breakin character ONLY
  582.                 // when it is waiting for State Change packet.  The breakin
  583.                 // character should not be followed by any other character
  584.                 // except packet leader UCHAR.
  585.                 //
  586.                 if ( Input == BREAKIN_PACKET_BYTE) {
  587.                     BreakinDetected = TRUE;
  588.                    
  589.                 } else {
  590.                     //
  591.                     // The following statement is ABSOLUTELY necessary.
  592.                     //
  593.                     BreakinDetected = FALSE;
  594.                   
  595.                 }
  596.                 Index = 0;
  597.             }
  598.         }
  599.     } while ( Index < 4 );
  600.     if (BreakinDetected) {
  601.         KdpControlCPending = TRUE;
  602.     }
  603.     //
  604.     // return the packet leader and FALSE to indicate no resend is needed.
  605.     //
  606.     if ( Input == PACKET_LEADER_BYTE ) {
  607.         *PacketLeader = PACKET_LEADER;
  608.     } else {
  609.         *PacketLeader = CONTROL_PACKET_LEADER;
  610.     }
  611.    if(KdContext)
  612.    {
  613.      KdContext->BreakInRequested = BreakinDetected;
  614.   }
  615.   
  616.     KdDebuggerNotPresent = FALSE;
  617.     SharedUserData->KdDebuggerEnabled |= 0x00000002;
  618.     return KDP_PACKET_RECEIVED;
  619. }
  620. ULONG
  621. KdpReceiveString (
  622.     OUT PCHAR Destination,
  623.     IN ULONG Length
  624.     )
  625. /*++
  626. Routine Description:
  627.     This routine reads a string from the kernel debugger port.
  628. Arguments:
  629.     Destination - Supplies a pointer to the input string.
  630.     Length - Supplies the length of the string to be read.
  631. Return Value:
  632.     CP_GET_SUCCESS is returned if string is successfully read from the
  633.         kernel debugger line.
  634.     CP_GET_ERROR is returned if error encountered during reading.
  635.     CP_GET_NODATA is returned if timeout.
  636. --*/
  637. {
  638.     UCHAR Input;
  639.     ULONG ReturnCode;
  640.     //
  641.     // Read UCHARs until either a error is encountered or the entire string
  642.     // has been read.
  643.     //
  644.     while (Length > 0) {
  645.         ReturnCode = KdCompGetByte(&Input);
  646.         if (ReturnCode != CP_GET_SUCCESS) {
  647.             return ReturnCode;
  648.         } else {
  649.             *Destination++ = Input;
  650.             Length -= 1;
  651.         }
  652.     }
  653.     return CP_GET_SUCCESS;
  654. }
  655. VOID
  656. KdpSendString (
  657.     IN PCHAR Source,
  658.     IN ULONG Length
  659.     )
  660. /*++
  661. Routine Description:
  662.     This routine writes a string to the kernel debugger port.
  663. Arguments:
  664.     Source - Supplies a pointer to the output string.
  665.     Length - Supplies the length of the string to be written.
  666. Return Value:
  667.     None.
  668. --*/
  669. {
  670.     UCHAR Output;
  671.     //
  672.     // Write UCHARs to the kernel debugger port.
  673.     //
  674.     while (Length > 0) {
  675.         Output = *Source++;
  676.         KdCompPutByte(Output);
  677.         Length -= 1;
  678.     }
  679.     return;
  680. }
  681. VOID
  682. KdpSendControlPacket (
  683.     IN USHORT PacketType,
  684.     IN ULONG PacketId OPTIONAL
  685.     )
  686. /*++
  687. Routine Description:
  688.     This routine sends a control packet to the host machine that is running the
  689.     kernel debugger and waits for an ACK.
  690. Arguments:
  691.     PacketType - Supplies the type of packet to send.
  692.     PacketId - Supplies packet id, optionally.
  693. Return Value:
  694.     None.
  695. --*/
  696. {
  697.     KD_PACKET PacketHeader;
  698.     //
  699.     // Initialize and send the packet header.
  700.     //
  701.     PacketHeader.PacketLeader = CONTROL_PACKET_LEADER;
  702.     if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR) PacketId )) {
  703.         PacketHeader.PacketId = PacketId;
  704.     }
  705.     PacketHeader.byteCount = 0;
  706.     PacketHeader.Checksum = 0;
  707.     PacketHeader.PacketType = PacketType;
  708.     KdpSendString((PCHAR)&PacketHeader, sizeof(KD_PACKET));
  709.     return;
  710. }
  711. ULONG
  712. KdReceivePacket (
  713.     IN ULONG PacketType,
  714.     OUT PSTRING MessageHeader,
  715.     OUT PSTRING MessageData,
  716.     OUT PULONG DataLength,
  717.     IN_OUT PKD_CONTEXT KdContext OPTIONAL
  718.     )
  719. /*++
  720. Routine Description:
  721.     This routine receives a packet from the host machine that is running
  722.     the kernel debugger UI.  This routine is ALWAYS called after packet being
  723.     sent by caller.  It first waits for ACK packet for the packet sent and
  724.     then waits for the packet desired.
  725.     N.B. If caller is KdPrintString, the parameter PacketType is
  726.        PACKET_TYPE_KD_ACKNOWLEDGE.  In this case, this routine will return
  727.        right after the ack packet is received.
  728. Arguments:
  729.     PacketType - Supplies the type of packet that is excepted.
  730.     MessageHeader - Supplies a pointer to a string descriptor for the input
  731.         message.
  732.     MessageData - Supplies a pointer to a string descriptor for the input data.
  733.     DataLength - Supplies pointer to ULONG to receive length of recv. data.
  734. Return Value:
  735.     KDP_PACKET_RESEND - if resend is required.
  736.     KDP_PAKCET_TIMEOUT - if timeout.
  737.     KDP_PACKET_RECEIVED - if packet received.
  738. --*/
  739. {
  740.     UCHAR Input;
  741.     ULONG MessageLength;
  742.     KD_PACKET PacketHeader;
  743.     ULONG ReturnCode;
  744.     ULONG Checksum;
  745.  if(PacketType==PACKET_TYPE_KD_POLL_BREAKIN)
  746.  {
  747.   ReturnCode= KdCompPollByte(&Input);
  748.   if(ReturnCode==CP_GET_SUCCESS && BREAKIN_PACKET_BYTE==Input)
  749.   {
  750.    return KDP_PACKET_RECEIVED;
  751.   }
  752.   else
  753.   {
  754.    return KDP_PACKET_TIMEOUT;
  755.   }
  756.  }
  757. WaitForPacketLeader:
  758.     //
  759.     // Read Packet Leader
  760.     //
  761.     ReturnCode = KdpReceivePacketLeader(PacketType, &PacketHeader.PacketLeader,KdContext);
  762.     //
  763.     // If we can successfully read packet leader, it has high possibility that
  764.     // kernel debugger is alive.  So reset count.
  765.     //
  766.     if (ReturnCode != KDP_PACKET_TIMEOUT) {
  767.         KdpNumberRetries = KdpRetryCount;
  768.     }
  769.     if (ReturnCode != KDP_PACKET_RECEIVED) {
  770.         return ReturnCode;
  771.     }
  772.     //
  773.     // Read packet type.
  774.     //
  775.     ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketType,
  776.                                   sizeof(PacketHeader.PacketType));
  777.     if (ReturnCode == CP_GET_NODATA) {
  778.         return KDP_PACKET_TIMEOUT;
  779.     } else if (ReturnCode == CP_GET_ERROR) {
  780.         if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
  781.             //
  782.             // If read error and it is for a control packet, simply
  783.             // preptend that we have not seen this packet.  Hopefully
  784.             // we will receive the packet we desire which automatically acks
  785.             // the packet we just sent.
  786.             //
  787.             goto WaitForPacketLeader;
  788.         } else {
  789.             //
  790.             // if read error while reading data packet, we have to ask
  791.             // kernel debugger to resend us the packet.
  792.             //
  793.             goto SendResendPacket;
  794.         }
  795.     }
  796.     //
  797.     // if the packet we received is a resend request, we return true and
  798.     // let caller resend the packet.
  799.     //
  800.     if ( PacketHeader.PacketLeader == CONTROL_PACKET_LEADER &
  801.          PacketHeader.PacketType == PACKET_TYPE_KD_RESEND ) {
  802.         return KDP_PACKET_RESEND;
  803.     }
  804.     //
  805.     // Read data length.
  806.     //
  807.     ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.byteCount,
  808.                                   sizeof(PacketHeader.byteCount));
  809.     if (ReturnCode == CP_GET_NODATA) {
  810.         return KDP_PACKET_TIMEOUT;
  811.     } else if (ReturnCode == CP_GET_ERROR) {
  812.         if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
  813.             goto WaitForPacketLeader;
  814.         } else {
  815.             goto SendResendPacket;
  816.         }
  817.     }
  818.     //
  819.     // Read Packet Id.
  820.     //
  821.     ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketId,
  822.                                   sizeof(PacketHeader.PacketId));
  823.     if (ReturnCode == CP_GET_NODATA) {
  824.         return KDP_PACKET_TIMEOUT;
  825.     } else if (ReturnCode == CP_GET_ERROR) {
  826.         if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
  827.             goto WaitForPacketLeader;
  828.         } else {
  829.             goto SendResendPacket;
  830.         }
  831.     }
  832.     //
  833.     // Read packet checksum.
  834.     //
  835.     ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.Checksum,
  836.                                   sizeof(PacketHeader.Checksum));
  837.     if (ReturnCode == CP_GET_NODATA) {
  838.         return KDP_PACKET_TIMEOUT;
  839.     } else if (ReturnCode == CP_GET_ERROR) {
  840.         if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
  841.             goto WaitForPacketLeader;
  842.         } else {
  843.             goto SendResendPacket;
  844.         }
  845.     }
  846.     //
  847.     // A complete packet header is received.  Check its validity and
  848.     // perform appropriate action depending on packet type.
  849.     //
  850.     if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) {
  851.         if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE /*4*/) {
  852.             //
  853.             // If we received an expected ACK packet and we are not
  854.             // waiting for any new packet, update outgoing packet id
  855.             // and return.  If we are NOT waiting for ACK packet
  856.             // we will keep on waiting.  If the ACK packet
  857.             // is not for the packet we send, ignore it and keep on waiting.
  858.             //
  859.             if (PacketHeader.PacketId !=
  860.                 (KdpNextPacketIdToSend & ~SYNC_PACKET_ID))  {
  861.                 goto WaitForPacketLeader;
  862.             } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
  863.                 KdpNextPacketIdToSend ^= 1;
  864.                 return KDP_PACKET_RECEIVED;
  865.             } else {
  866.                 goto WaitForPacketLeader;
  867.             }
  868.         } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET/*6*/) {
  869.             //
  870.             // if we received Reset packet, reset the packet control variables
  871.             // and resend earlier packet.
  872.             //
  873.             KdpNextPacketIdToSend = INITIAL_PACKET_ID;
  874.             KdpPacketIdExpected = INITIAL_PACKET_ID;
  875.             KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0L);
  876.             return KDP_PACKET_RESEND;
  877.         } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND/*5*/) {
  878.             return KDP_PACKET_RESEND;
  879.         } else {
  880.             //
  881.             // Invalid packet header, ignore it.
  882.             //
  883.             goto WaitForPacketLeader;
  884.         }
  885.     //
  886.     // The packet header is for data packet (not control packet).
  887.     //
  888.     } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
  889.         //
  890.         // if we are waiting for ACK packet ONLY
  891.         // and we receive a data packet header, check if the packet id
  892.         // is what we expected.  If yes, assume the acknowledge is lost (but
  893.         // sent), ask sender to resend and return with PACKET_RECEIVED.
  894.         //
  895.         if (PacketHeader.PacketId == KdpPacketIdExpected) {
  896.             KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  897.             KdpNextPacketIdToSend ^= 1;
  898.             return KDP_PACKET_RECEIVED;
  899.         } else {
  900.             KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  901.                                  PacketHeader.PacketId
  902.                                  );
  903.             goto WaitForPacketLeader;
  904.         }
  905.     }
  906.     //
  907.     // we are waiting for data packet and we received the packet header
  908.     // for data packet. Perform the following checkings to make sure
  909.     // it is the packet we are waiting for.
  910.     //
  911.     //
  912.     // Check byteCount received is valid
  913.     //
  914.     MessageLength = MessageHeader->MaximumLength;
  915.     if ((PacketHeader.byteCount > (USHORT)PACKET_MAX_SIZE) ||
  916.         (PacketHeader.byteCount < (USHORT)MessageLength)) {
  917.         goto SendResendPacket;
  918.     }
  919.     *DataLength = PacketHeader.byteCount - MessageLength;
  920.     //
  921.     // Read the message header.
  922.     //
  923.     ReturnCode = KdpReceiveString(MessageHeader->Buffer, MessageLength);
  924.     if (ReturnCode != CP_GET_SUCCESS) {
  925.         goto SendResendPacket;
  926.     }
  927.     MessageHeader->Length = (USHORT)MessageLength;
  928.     //
  929.     // Read the message data.
  930.     //
  931.     ReturnCode = KdpReceiveString(MessageData->Buffer, *DataLength);
  932.     if (ReturnCode != CP_GET_SUCCESS) {
  933.         goto SendResendPacket;
  934.     }
  935.     MessageData->Length = (USHORT)*DataLength;
  936.     //
  937.     // Read packet trailing byte
  938.     //
  939.     ReturnCode = KdCompGetByte(&Input);
  940.     if (ReturnCode != CP_GET_SUCCESS || Input != PACKET_TRAILING_BYTE/*0AAh*/) {
  941.         goto SendResendPacket;
  942.     }
  943.     //
  944.     // Check PacketType is what we are waiting for.
  945.     //
  946.     if (PacketType != PacketHeader.PacketType) {
  947.         KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  948.                              PacketHeader.PacketId
  949.                              );
  950.         goto WaitForPacketLeader;
  951.     }
  952.     //
  953.     // Check PacketId is valid.
  954.     //
  955.     if (PacketHeader.PacketId == INITIAL_PACKET_ID ||
  956.         PacketHeader.PacketId == (INITIAL_PACKET_ID ^ 1)) {
  957.         if (PacketHeader.PacketId != KdpPacketIdExpected) {
  958.             KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  959.                                  PacketHeader.PacketId
  960.                                  );
  961.             goto WaitForPacketLeader;
  962.         }
  963.     } else {
  964.         goto SendResendPacket;
  965.     }
  966.     //
  967.     // Check checksum is valid.
  968.     //
  969.     Checksum = KdpComputeChecksum(
  970.                             MessageHeader->Buffer,
  971.                             MessageHeader->Length
  972.                             );
  973.     Checksum += KdpComputeChecksum(
  974.                             MessageData->Buffer,
  975.                             MessageData->Length
  976.                             );
  977.     if (Checksum != PacketHeader.Checksum) {
  978.         goto SendResendPacket;
  979.     }
  980.     //
  981.     // Send Acknowledge UCHAR and the Id of the packet received.
  982.     // Then, update the ExpectId for next incoming packet.
  983.     //
  984.     KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  985.                          PacketHeader.PacketId
  986.                          );
  987.     //
  988.     // We have successfully received the packet so update the
  989.     // packet control variables and return sucess.
  990.     //
  991.     KdpPacketIdExpected ^= 1;
  992.     return KDP_PACKET_RECEIVED;
  993. SendResendPacket:
  994.     KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  995.     goto WaitForPacketLeader;
  996. }
  997. void
  998. KdSendPacket (
  999.     IN ULONG PacketType,
  1000.     IN PSTRING MessageHeader,
  1001.     IN PSTRING MessageData OPTIONAL,
  1002.     IN_OUT PKD_CONTEXT KdContext OPTIONAL
  1003.     )
  1004. /*++
  1005. Routine Description:
  1006.     This routine sends a packet to the host machine that is running the
  1007.     kernel debugger and waits for an ACK.
  1008. Arguments:
  1009.     PacketType - Supplies the type of packet to send.
  1010.     MessageHeader - Supplies a pointer to a string descriptor that describes
  1011.         the message information.
  1012.     MessageData - Supplies a pointer to a string descriptor that describes
  1013.         the optional message data.
  1014. Return Value:
  1015.     None.
  1016. --*/
  1017. {
  1018.     KD_PACKET PacketHeader;
  1019.     ULONG MessageDataLength;
  1020.     ULONG ReturnCode;
  1021.     PDBGKD_DEBUG_IO DebugIo;
  1022.  PDBGKD_FILE_IO  FileIo;
  1023.     PDBGKD_WAIT_STATE_CHANGE64 StateChange;
  1024.     if ( ARGUMENT_PRESENT(MessageData) ) {
  1025.         MessageDataLength = MessageData->Length;
  1026.         PacketHeader.Checksum = KdpComputeChecksum(
  1027.                                         MessageData->Buffer,
  1028.                                         MessageData->Length
  1029.                                         );
  1030.     } else {
  1031.         MessageDataLength = 0;
  1032.         PacketHeader.Checksum = 0;
  1033.     }
  1034.     PacketHeader.Checksum += KdpComputeChecksum (
  1035.                                     MessageHeader->Buffer,
  1036.                                     MessageHeader->Length
  1037.                                     );
  1038.     //
  1039.     // Initialize and send the packet header.
  1040.     //
  1041.     PacketHeader.PacketLeader = PACKET_LEADER;
  1042.     PacketHeader.byteCount = (USHORT)(MessageHeader->Length + MessageDataLength);
  1043.     PacketHeader.PacketType = (USHORT)PacketType;
  1044.     KdpNumberRetries = KdpRetryCount;
  1045.     do {
  1046.         if (KdpNumberRetries == 0) {
  1047.             //
  1048.             // If the packet is not for reporting exception, we give up
  1049.             // and declare debugger not present.
  1050.             //
  1051.             if (PacketType == PACKET_TYPE_KD_DEBUG_IO) {
  1052.                 DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer;
  1053.                 if (DebugIo->ApiNumber == DbgKdPrintStringApi) {
  1054.                     KdDebuggerNotPresent = TRUE;
  1055.                     SharedUserData->KdDebuggerEnabled &= ~0x00000002;
  1056.                     KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;//80800000|0800h
  1057.                     KdpPacketIdExpected = INITIAL_PACKET_ID; //80800000h
  1058.                     return;
  1059.                 }
  1060.             } else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64) {
  1061.                 StateChange = (PDBGKD_WAIT_STATE_CHANGE64)MessageHeader->Buffer;
  1062.                 if (StateChange->NewState == DbgKdLoadSymbolsStateChange) {
  1063.                     KdDebuggerNotPresent = TRUE;
  1064.                     SharedUserData->KdDebuggerEnabled &= ~0x00000002;
  1065.                     KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
  1066.                     KdpPacketIdExpected = INITIAL_PACKET_ID;
  1067.                     return;
  1068.                 }
  1069.             }
  1070.    else if (PacketType == PACKET_TYPE_KD_FILE_IO)
  1071.    {
  1072.     FileIo = (PDBGKD_FILE_IO)MessageHeader->Buffer;
  1073.     if (FileIo->ApiNumber== DbgKdCreateFileApi) {
  1074.                     KdDebuggerNotPresent = TRUE;
  1075.                     SharedUserData->KdDebuggerEnabled &= ~0x00000002;
  1076.                     KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
  1077.                     KdpPacketIdExpected = INITIAL_PACKET_ID;
  1078.                     return;
  1079.                 }
  1080.    }
  1081.         }
  1082.         //
  1083.         // Setting PacketId has to be in the do loop in case Packet Id was
  1084.         // reset.
  1085.         //
  1086.         PacketHeader.PacketId = KdpNextPacketIdToSend;
  1087.         KdpSendString((PCHAR)&PacketHeader, sizeof(KD_PACKET));
  1088.         //
  1089.         // Output message header.
  1090.         //
  1091.         KdpSendString(MessageHeader->Buffer, MessageHeader->Length);
  1092.         //
  1093.         // Output message data.
  1094.         //
  1095.         if ( MessageDataLength ) {
  1096.             KdpSendString(MessageData->Buffer, MessageData->Length);
  1097.         }
  1098.         //
  1099.         // Output a packet trailing UCHAR
  1100.         //
  1101.         KdCompPutByte(PACKET_TRAILING_BYTE);
  1102.         //
  1103.         // Wait for the Ack Packet
  1104.         //
  1105.         ReturnCode = KdReceivePacket(
  1106.                          PACKET_TYPE_KD_ACKNOWLEDGE,
  1107.                          NULL,
  1108.                          NULL,
  1109.                          NULL,
  1110.                          KdContext
  1111.                          );
  1112.         if (ReturnCode == KDP_PACKET_TIMEOUT) {
  1113.             KdpNumberRetries--;
  1114.         }
  1115.     } while (ReturnCode != KDP_PACKET_RECEIVED);
  1116.     //
  1117.     // Reset Sync bit in packet id.  The packet we sent may have Sync bit set
  1118.     //
  1119.     KdpNextPacketIdToSend &= ~SYNC_PACKET_ID;
  1120.     //
  1121.     // Since we are able to talk to debugger, the retrycount is set to
  1122.     // maximum value.
  1123.     //
  1124.     KdpRetryCount = KdContext->RetryCount;
  1125. }

另给出我在网上找到的关于串口通信的资料:


 

  1. Serial I/O  
  2. Table of Registers
  3. --------------------------------------------------------------------------------
  4. Base Address DLAB Read/Write  Abr.   Register Name  
  5. + 0   =0 Write  -   Transmitter Holding Buffer  
  6.   =0 Read  -   Receiver Buffer  
  7.   =1 Read/Write  -   Divisor Latch Low Byte  
  8. + 1   =0 Read/Write  IER   Interrupt Enable Register  
  9.   =1 Read/Write  -   Divisor Latch High Byte  
  10. + 2   - Read   IIR   Interrupt Identification Register 
  11.   - Write  FCR   FIFO Control Register  
  12. + 3   - Read/Write  LCR   Line Control Register  
  13. + 4   - Read/Write  MCR   Modem Control Register  
  14. + 5   - Read   LSR   Line Status Register  
  15. + 6   - Read   MSR   Modem Status Register  
  16. + 7   - Read/Write  -   Scratch Register  
  17. -------------------------------------------------------------------------------
  18. Table 5 : Table of Registers
  19. DLAB ?
  20. --------------------------------------------------------------------------------
  21. You will have noticed in the table of registers that there is a DLAB column. When DLAB is set to '0' or '1' some of the 
  22. registers change. This is how the UART is able to have 12 registers (including the scratch register) through only 8 port
  23.  addresses. DLAB stands for Divisor Latch Access Bit. When DLAB is set to '1' via the line control register, two registers 
  24. become available from which you can set your speed of communications measured in bits per second.
  25. The UART will have a crystal which should oscillate around 1.8432 MHZ. The UART incorporates a divide by 16 counter
  26.  which simply divides the incoming clock signal by 16. Assuming we had the 1.8432 MHZ clock signal, that would leave us
  27.  with a maximum, 115,200 hertz signal making the UART capable of transmitting and receiving at 115,200 Bits Per Second (BPS).
  28.  That would be fine for some of the faster modems and devices which can handle that speed, but others just wouldn't communicate 
  29. at all. Therefore the UART is fitted with a Programmable Baud Rate Generator which is controlled by two registers.
  30. Lets say for example we only wanted to communicate at 2400 BPS. We worked out that we would have to divide 115,200 by 48 to 
  31. get a workable 2400 Hertz Clock. The "Divisor", in this case 48, is stored in the two registers controlled by the 
  32. "Divisor Latch Access Bit". This divisor can be any number which can be stored in 16 bits (ie 0 to 65535). The UART only 
  33. has a 8 bit data bus, thus this is where the two registers are used. The first register (Base + 0) when DLAB = 1 stores
  34.  the "Divisor latch low byte" where as the second register (base + 1 when DLAB = 1) stores the "Divisor latch high byte."
  35. Below is a table of some more common speeds and their divisor latch high bytes & low bytes. Note that all the divisors are 
  36. shown in Hexadecimal.
  37. -------------------------------------------------------------------------------
  38. Speed (BPS)  Divisor (Dec)  Divisor Latch High Byte  Divisor Latch Low Byte  
  39. 50    2304     09h     00h  
  40. 300    384     01h     80h  
  41. 600    192     00h     C0h  
  42. 2400      48     00h     30h  
  43. 4800      24     00h     18h  
  44. 9600    12     00h     0Ch  
  45. 19200     6     00h    06h  
  46. 38400     3     00h     03h  
  47. 57600     2     00h     02h  
  48. 115200     1     00h     01h
  49. -------------------------------------------------------------------------------  
  50. Table 6 : Table of Commonly Used Baudrate Divisors 
  51. Interrupt Enable Register (IER)
  52. --------------------------------------------------------------------------------
  53. -------------------------------------------------------------------------------
  54. Bit   Notes 
  55. Bit 7 Reserved 
  56. Bit 6 Reserved 
  57. Bit 5 Enables Low Power Mode (16750) 
  58. Bit 4 Enables Sleep Mode (16750) 
  59. Bit 3 Enable Modem Status Interrupt 
  60. Bit 2 Enable Receiver Line Status Interrupt 
  61. Bit 1 Enable Transmitter Holding Register Empty Interrupt 
  62. Bit 0 Enable Received Data Available Interrupt 
  63. -------------------------------------------------------------------------------
  64. Table 7 : Interrupt Enable Register
  65. The Interrupt Enable Register could possibly be one of the easiest registers on a UART to understand. Setting Bit 0 high enables
  66.  the Received Data Available Interrupt which generates an interrupt when the receiving register/FIFO contains data to be read by 
  67. the CPU. 
  68. Bit 1 enables Transmit Holding Register Empty Interrupt. This interrupts the CPU when the transmitter buffer is empty. Bit 2 
  69. enables the receiver line status interrupt. The UART will interrupt when the receiver line status changes. Likewise for bit 3 
  70. which enables the modem status interrupt. Bits 4 to 7 are the easy ones. They are simply reserved. (If only everything was that
  71.  easy!) 
  72. Interrupt Identification Register (IIR)
  73. -------------------------------------------------------------------------------
  74. Bit   Notes 
  75. Bits 6 and 7  Bit 6  Bit 7   
  76.   0  0  No FIFO  
  77.   0  1  FIFO Enabled but Unusable  
  78.   1  1  FIFO Enabled  
  79. Bit 5   64 Byte Fifo Enabled (16750 only) 
  80. Bit 4   Reserved 
  81. Bit 3   0 Reserved on 8250, 16450 
  82.   1 16550 Time-out Interrupt Pending 
  83. Bits 1 and 2  Bit 2 Bit 1    
  84.   0  0 Modem Status Interrupt  
  85.   0  1 Transmitter Holding Register Empty Interrupt 
  86.   1  0 Received Data Available Interrupt 
  87.   1  1 Receiver Line Status Interrupt 
  88. Bit0   0 Interrupt Pending 
  89.   1 No Interrupt Pending 
  90. Table 8 : Interrupt Identification Register 
  91. The interrupt identification register is a read only register. Bits 6 and 7 give status on the FIFO Buffer. When both bits are '0'
  92.  no FIFO buffers are active. This should be the only result you will get from a 8250 or 16450. If bit 7 is active but bit 6 is not 
  93. active then the UART has it's buffers enabled but are unusable. This occurs on the 16550 UART where a bug in the FIFO buffer made 
  94. the FIFO's unusable. If both bits are '1' then the FIFO buffers are enabled and fully operational. 
  95. Bits 4 and 5 are reserved. Bit 3 shows the status of the time-out interrupt on a 16550 or higher. 
  96. Lets jump to Bit 0 which shows whether an interrupt has occurred. If an interrupt has occurred it's status will shown by bits 1 
  97. and 2. These interrupts work on a priority status. The Line Status Interrupt has the highest Priority, followed by the Data 
  98. Available Interrupt, then the Transmit Register Empty Interrupt and then the Modem Status Interrupt which has the lowest priority. 
  99. First In / First Out Control Register (FCR)
  100. -------------------------------------------------------------------------------
  101. Bit   Notes 
  102. Bits 6 and 7 Bit 7  Bit 6  Interrupt Trigger Level  
  103.   0  0  1 Byte  
  104.   0  1  4 Bytes  
  105.   1  0  8 Bytes  
  106.   1 1  14 Bytes 
  107. Bit 5   Enable 64 Byte FIFO (16750 only) 
  108. Bit 4   Reserved 
  109. Bit 3   DMA Mode Select. Change status of RXRDY & TXRDY pins from mode 1 to mode 2. 
  110. Bit 2   Clear Transmit FIFO 
  111. Bit 1   Clear Receive FIFO 
  112. Bit 0   Enable FIFO's 
  113. -------------------------------------------------------------------------------
  114. Table 9 : FIFO Control Register 
  115. The FIFO register is a write only register. This register is used to control the FIFO (First In / First Out) buffers which are 
  116. found on 16550's and higher. 
  117. Bit 0 enables the operation of the receive and transmit FIFO's. Writing a '0' to this bit will disable the operation of transmit 
  118. and receive FIFO's, thus you will loose all data stored in these FIFO buffers. 
  119. Bit's 1 and 2 control the clearing of the transmit or receive FIFO's. Bit 1 is responsible for the receive buffer while bit 2 is 
  120. responsible for the transmit buffer. Setting these bits to 1 will only clear the contents of the FIFO and will not affect the 
  121. shift registers. These two bits are self resetting, thus you don't need to set the bits to '0' when finished. 
  122. Bit 3 enables the DMA mode select which is found on 16550 UARTs and higher. More on this later. Bits 4 and 5 are those easy type 
  123. again, Reserved. 
  124. Bits 6 and 7 are used to set the triggering level on the Receive FIFO. For example if bit 7 was set to '1' and bit 6 was set to '0' 
  125. then the trigger level is set to 8 bytes. When there is 8 bytes of data in the receive FIFO then the Received Data Available 
  126. interrupt is set. See (IIR) 
  127. Line Control Register (LCR)
  128. ----------------------+---------------------------------------------------------
  129. Bit    Notes 
  130. Bit 7    1 Divisor Latch Access Bit 
  131.    0 Access to Receiver buffer, Transmitter buffer & Interrupt Enable Register 
  132. Bit 6    Set Break Enable 
  133. Bits 3, 4 And 5  Bit 5  Bit 4  Bit 3  Parity Select 
  134.    X  X  0  No Parity  
  135.    0  0  1  Odd Parity  
  136.    0  1  1  Even Parity  
  137.    1  0  1  High Parity (Sticky) 
  138.    1  1  1  Low Parity (Sticky) 
  139. Bit 2   Length of Stop Bit 
  140.    0 One Stop Bit 
  141.    1 2 Stop bits for words of length 6,7 or 8 bits or 1.5 Stop Bits for Word lengths of 5 bits. 
  142. Bits 0 And 1   Bit 1  Bit 0  Word Length 
  143.    0  0  5 Bits  
  144.    0  1  6 Bits  
  145.    1  0  7 Bits  
  146.    1  1  8 Bits  
  147. ----------------------+---------------------------------------------------------
  148. Table 10 : Line Control Register 
  149. The Line Control register sets the basic parameters for communication. Bit 7 is the Divisor Latch Access Bit or DLAB for short
  150. We have already talked about what it does. (See DLAB?) Bit 6 Sets break enable. When active, the TD line goes into "Spacing" 
  151. state which causes a break in the receiving UART. Setting this bit to '0' Disables the Break.
  152. Bits 3,4 and 5 select parity. If you study the 3 bits, you will find that bit 3 controls parity. That is, if it is
  153.  set to '0' then no parity is used, but if it is set to '1' then parity is used. Jumping to bit 5, we can see that it
  154.  controls sticky parity. Sticky parity is simply when the parity bit is always transmitted and checked as a '1' or '0'
  155. This has very little success in checking for errors as if the first 4 bits contain errors but the sticky parity bit contains 
  156. the appropriately set bit, then a parity error will not result. Sticky high parity is the use of a '1' for the parity bit, 
  157. while the opposite, sticky low parity is the use of a '0' for the parity bit. 
  158. If bit 5 controls sticky parity, then turning this bit off must produce normal parity provided bit 3 is still set to '1'.
  159.  Odd parity is when the parity bit is transmitted as a '1' or '0' so that there is a odd number of 1's. Even parity must 
  160. then be the parity bit produces and even number of 1's. This provides better error checking but still is not perfect, 
  161. thus CRC-32 is often used for software error correction. If one bit happens to be inverted with even or odd parity set, 
  162. then a parity error will occur, however if two bits are flipped in such a way that it produces the correct parity bit 
  163. then an parity error will no occur. 
  164. Bit 2 sets the length of the stop bits. Setting this bit to '0' will produce one stop bit, however setting it to '1' will 
  165. produce either 1.5 or 2 stop bits depending upon the word length. Note that the receiver only checks the first stop bit. 
  166. Bits 0 and 1 set the word length. This should be pretty straight forward. A word length of 8 bits is most commonly used today. 
  167. Modem Control Register (MCR)
  168. -----+--------------------------------------------------------------------------
  169. Bit   Notes 
  170. Bit 7 Reserved 
  171. Bit 6 Reserved 
  172. Bit 5 Autoflow Control Enabled (16750 only) 
  173. Bit 4 LoopBack Mode  
  174. Bit 3 Aux Output 2 
  175. Bit 2 Aux Output 1 
  176. Bit 1 Force Request to Send 
  177. Bit 0 Force Data Terminal Ready 
  178. -----+--------------------------------------------------------------------------
  179. Table 11 : Modem Control Register 
  180. The Modem Control Register is a Read/Write Register. Bits 5,6 and 7 are reserved. Bit 4 activates the loopback mode. In Loopback
  181. mode the transmitter serial output is placed into marking state. The receiver serial input is disconnected. The transmitter out 
  182. is looped back to the receiver in. DSR, CTS, RI & DCD are disconnected. DTR, RTS, OUT1 & OUT2 are connected to the modem control 
  183. inputs. The modem control output pins are then place in an inactive state. In this mode any data which is placed in the transmitter 
  184. registers for output is received by the receiver circuitry on the same chip and is available at the receiver buffer. This can be 
  185. used to test the UARTs operation.
  186. Aux Output 2 maybe connected to external circuitry which controls the UART-CPU interrupt process. Aux Output 1 is normally 
  187. disconnected, but on some cards is used to switch between a 1.8432MHZ crystal to a 4MHZ crystal which is used for MIDI. 
  188. Bits 0 and 1 simply control their relevant data lines. For example setting bit 1 to '1' makes the request to send line active. 
  189. Line Status Register (LSR)
  190. -----+--------------------------------------------------------------------------
  191. Bit  |Notes 
  192. -----+--------------------------------------------------------------------------
  193. Bit 7 Error in Received FIFO 
  194. Bit 6 Empty Data Holding Registers  
  195. Bit 5 Empty Transmitter Holding Register 
  196. Bit 4 Break Interrupt  
  197. Bit 3 Framing Error 
  198. Bit 2 Parity Error 
  199. Bit 1 Overrun Error 
  200. Bit 0 Data Ready 
  201. -----+--------------------------------------------------------------------------
  202. Table 12 : Line Status Register 
  203. The line status register is a read only register. Bit 7 is the error in received FIFO bit. This bit is high when at least one break,
  204.  parity or framing error has occurred on a byte which is contained in the FIFO. 
  205. When bit 6 is set, both the transmitter holding register and the shift register are empty. The UART's holding register holds the 
  206. next byte of data to be sent in parallel fashion. The shift register is used to convert the byte to serial, so that it can be 
  207. transmitted over one line. When bit 5 is set, only the transmitter holding register is empty. So what's the difference between the 
  208. two? When bit 6, the transmitter holding and shift registers are empty, no serial conversions are taking place so there should be 
  209. no activity on the transmit data line. When bit 5 is set, the transmitter holding register is empty, thus another byte can be sent 
  210. to the data port, but a serial conversion using the shift register may be taking place. 
  211. The break interrupt (Bit 4) occurs when the received data line is held in a logic state '0' (Space) for more than the time it takes 
  212. to send a full word. That includes the time for the start bit, data bits, parity bits and stop bits. 
  213. A framing error (Bit 3) occurs when the last bit is not a stop bit. This may occur due to a timing error. You will most commonly 
  214. encounter a framing error when using a null modem linking two computers or a protocol analyzer when the speed at which the data 
  215. is being sent is different to that of what you have the UART set to receive it at. 
  216. A overrun error normally occurs when your program can't read from the port fast enough. If you don't get an incoming byte out of 
  217. the register fast enough, and another byte just happens to be received, then the last byte will be lost and a overrun error will 
  218. result. 
  219. Bit 0 shows data ready, which means that a byte has been received by the UART and is at the receiver buffer ready to be read. 
  220. Modem Status Register (MSR)
  221. -----+--------------------------------------------------------------------------
  222. Bit  | Notes 
  223. -----+--------------------------------------------------------------------------
  224. Bit 7 Carrier Detect 
  225. Bit 6 Ring Indicator  
  226. Bit 5 Data Set Ready 
  227. Bit 4 Clear To Send  
  228. Bit 3 Delta Data Carrier Detect 
  229. Bit 2 Trailing Edge Ring Indicator 
  230. Bit 1 Delta Data Set Ready 
  231. Bit 0 Delta Clear to Send 
  232. -----+--------------------------------------------------------------------------
  233. Table 13 : Modem Status Register 
  234. Bit 0 of the modem status register shows delta clear to send, delta meaning a change in, thus delta clear to send means that there 
  235. was a change in the clear to send line, since the last read of this register. This is the same for bits 1 and 3. Bit 1 shows a 
  236. change in the Data Set Ready line where as Bit 3 shows a change in the Data Carrier Detect line. Bit 2 is the Trailing Edge Ring 
  237. Indicator which indicates that there was a transformation from low to high state on the Ring Indicator line. 
  238. Bits 4 to 7 show the current state of the data lines when read. Bit 7 shows Carrier Detect, Bit 6 shows Ring Indicator, Bit 5 shows 
  239. Data Set Ready & Bit 4 shows the status of the Clear To Send line. 
  240. --------------------------------------------------------------------------------
  241. Samples
  242. /* Name       : Sample Comm's Program - Polled Version - termpoll.c     */
  243. #include <dos.h>
  244. #include <stdio.h>
  245. #include <conio.h>
  246. #define PORT1 0x3F8
  247.   /* Defines Serial Ports Base Address */
  248.   /* COM1 0x3F8                        */
  249.   /* COM2 0x2F8          */
  250.   /* COM3 0x3E8          */
  251.   /* COM4 0x2E8          */
  252. void main(void)
  253. {
  254.  int c;
  255.  int ch;
  256.  outportb(PORT1 + 1 , 0);   /* Turn off interrupts - Port1 */
  257.  /*         PORT 1 - Communication Settings         */
  258.  outportb(PORT1 + 3 , 0x80);  /* SET DLAB ON */
  259.  outportb(PORT1 + 0 , 0x03);  /* Set Baud rate - Divisor Latch Low Byte */
  260.          /* Default 0x03 =  38,400 BPS */
  261.          /*         0x01 = 115,200 BPS */
  262.          /*         0x02 =  57,600 BPS */
  263.          /*         0x06 =  19,200 BPS */
  264.          /*         0x0C =   9,600 BPS */
  265.          /*         0x18 =   4,800 BPS */
  266.          /*         0x30 =   2,400 BPS */
  267.  outportb(PORT1 + 1 , 0x00);  /* Set Baud rate - Divisor Latch High Byte */
  268.  outportb(PORT1 + 3 , 0x03);  /* 8 Bits, No Parity, 1 Stop Bit */
  269.  outportb(PORT1 + 2 , 0xC7);  /* FIFO Control Register */
  270.  outportb(PORT1 + 4 , 0x0B);  /* Turn on DTR, RTS, and OUT2 */
  271.  printf("/nSample Comm's Program. Press ESC to quit /n");
  272.  do { c = inportb(PORT1 + 5);          /* Check to see if char has been */
  273.                                        /* received.                     */
  274.       if (c & 1) {ch = inportb(PORT1); /* If so, then get Char          */
  275.                   printf("%c",ch);}    /* Print Char to Screen          */
  276.       if (kbhit()){ch = getch();         /* If key pressed, get Char */
  277.                    outportb(PORT1, ch);} /* Send Char to Serial Port */
  278.     } while (ch !=27); /* Quit when ESC (ASC 27) is pressed */
  279. }
  280. --------------------------------------------------------------------------------
  281. The End

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值