2011年4月21日 星期四

以IO的方式,掃瞄PCI bus device。(透過CF8、CFC port)

Dos debug32.com
-a
mov eax, 80000000  #bus0_dev0_fun0
mov dx, cf8  #IO port cf8(Index)
out dx, eax  #寫入eax的值到cf8這個port
mov dx, cfc  #IO port cfc(Data)
in eax, dx  #到cfc這個port去讀值,放到eax暫存器


image

  1. 準備一隻可開機至dos的隨身碟,
    裡面放好debug32.exe這隻檔案,
    不確定debug32.exe是不是免費的,版權自理,
    開機進入DOS,執行debug32.exe。
  2. 這是debug32的選項
    詳見小木偶的網頁
    -D, dump – dump記憶體內容
    -E, Edit – 編輯記憶體內容
    -A, Assembly - 寫簡單的組語
    -U, Un-assembly - 反組譯
    -R, Register - 看暫存器
    -T, Trace - 可以Trace指令(Instruction),單步等。
    -G, Go - 直接執行指令(Instruction)
    -S, Search – 在某段記憶體中,搜尋某字串or某值
    以上是我有用過的幾種選項,其他的就要另外再查。
    這裡要先用到-A,寫簡單的組語
  3. Segment: Offset,詳見小木偶的網頁
  4. 編輯組合語言,
    我們要到用到IN、OUT,詳見IN、OUT指令

    OUT 指令
    out      dx,al
    #out     輸出入埠編號,欲送至此埠的資料

    IN 指令
    in       al,dx
    #in      存放讀出來的資料,輸出入埠編號

    第1行—>mov eax, 80000000
    第2行—>mov dx, cf8
    第3行—>out dx, eax
  5. code只有5行, 主要目的是第3行的out這個動作, 透過IO port cf8,去偵測 Bus_0, Device_0, Function_0, 那為甚麼80000000h就是Bus_0, Dev0, Fun_0? 詳見PCI Bus spec。

  6. 第四行—>mov dx, cfc
    第五行—>in eax, dx
    其實就是這樣,
    去cfc把資料(Data)讀出來。
image

  1. -u 100
    反組譯,從offset 100的地方開始。
    如果打得是-u 10b,那就會從offset 10b的地方開始反組譯。
  2. 30D5: 0100 ~ 30D5: 010e,
    這幾行的記憶體位址,就是我們剛剛寫的code。
  3. 像第一行的mov指令,佔了6個Byte,(0100 ~ 0105)
    第二行的mov指令,佔了3個Byte,(0106 ~ 0108)
    …以此類推
image
  1. -r ip 0100
    主要目的是要執行我們剛剛寫的code,
    所以要寫入 ip 這個暫存器,0100的值,
    0100,就是我們的第一行指令。
    若像下一行一樣只單打一個 –r
    就是顯示目前暫存器的值。

    IP, Instruction Pointer, 指令指標,
    這個暫存器是一個指標,指向下一條指令。
  2. -t
    就是trace,目前就是單步執行。
image
可以看到執行了幾次單步之後,
我們最後一行從 port cfc in 回來的值會放在 AX 這個暫存器,
然後看得到 AX = 8086,
也就是 Bus_0, Dev_0, Fun_0 的 Vendor ID,
也就是 Intel。
如果要掃瞄整個PCI bus,
就把這幾行寫成一個迴圈,
只要掃回來的值不是 ffffh,
那就是有Device。

沒有留言:

張貼留言