wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2064回复:19

pjf 请进,我有重要的问题请教

楼主#
更多 发布于:2002-06-07 16:21
我现在有一段代码,只能专门用来检测,获取硬盘的256个字.不管我的硬盘是挂在Primary Bus Master IDE, Primary Bus Slave IDE,
Secondary Bus Master IDE, Secondary Bus Slave IDE四个控制器的哪一个上面.反正这段程序的功能就只能测硬盘的情况.现在我想让你帮我改一下程序.使其能够检测全部四个IDE控制器的情况,然后能够获取硬盘和光驱的256个字.以及他们分别是挂在哪个IDE控制器上面?(应该不算难吧,对于你来说 :-) )下面是代码:
#include <windows.h>
#include <stdio.h>

WORD pw[256];

static DWORD idt, int_idt;
static DWORD Base;
static WORD Entry;

#pragma warning (disable:4035)
static int inp(WORD rdx)
{
_asm xor eax, eax
_asm mov dx, rdx
_asm in al, dx
}

static WORD inpw(WORD rdx)
{
_asm xor eax, eax
_asm mov dx, rdx
_asm in ax, dx
}

static void outp(WORD rdx, int ral)
{
_asm mov dx, rdx
_asm mov eax, ral
_asm out dx, al
}

static int WaitIde()
{
int al;

while ((al=inp(0x1F7))>=0x80) ;
return al;
}

static void ReadIDE()
{
int al;
int i;

WaitIde();
outp(0x1F6,0xA0);
al = WaitIde();
if ((al&0x50)!=0x50) return;

outp(0x1F6,0xA0);
outp(0x1F7,0xEC);
al = WaitIde();
if ((al&0x58)!=0x58) return;

for (i=0;i<256;i++) {
pw = inpw(0x1F0);
}
}

static void __declspec( naked ) NowInRing0()
{
_asm {
push ebp
mov ebp,esp

call ReadIDE

cli
mov ebx, int_idt
mov ax, Entry
mov word ptr [ebx-4], ax
mov eax, Base
shr eax, 16
mov [ebx+2], ax
sti
leave
iretd
}
}

void GetIDEInfo()
{
DWORD dwExcept;

dwExcept = (DWORD)NowInRing0;

_asm {
mov eax, fs:[0]
push eax
sidt [esp-02h]
pop ebx
mov idt, ebx
add ebx, 0x1C
mov int_idt, ebx

mov eax, [ebx]
mov [Base], eax
mov ax, [ebx-4]
mov [Entry], ax

cli
mov esi, dwExcept
push esi
mov [ebx-4], si
shr esi, 16
mov [ebx+2], si
pop esi
sti

int 3
}
}

main()
{
char s[80];
register i,j;

GetIDEInfo();

for (i=0,j=0;i<10;i++) {
s[j++]=pw[10+i]>>8;
s[j++]=pw[10+i]&0xFF;
}
s[j] = 0;

printf(\"Serial=%s\\n\", s);

return 0;
}


最新喜欢:

ameiamei
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-08 11:41
为了找98,烦死我了。

老进不了邮箱,稍候发给你
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-08 13:51
发了,收到没?
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-08 15:28
收到了.但是运行什么信息也写不出.不过我自己先看看到底哪里出了问题.非常感谢你.
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-08 16:05
你给我的程序里面,在我的main()函数里.加上了
for(i=0;i<512;i++)
   printf(\"%02x \",((BYTE*)pw));
但是你不要忘了,由于上面有这样一条语句,pw[27+i]>>8;
pw[]数组里面的每一个字高字节和第字节交换了.,所以你在后面列出来的所有的字节,是错误的吧.
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-08 16:23
收到了.但是运行什么信息也写不出.
------------------------------------------------------------------------------
结果是什么?我这儿挺好的,你把等待时间设长一点吧。

pw[]数组里面的每一个字高字节和第字节交换了.,所以你在后面列出来的所有的字节,是错误的吧
------------------------------------------------------------------------------
我加的目的只是自己看看有没有读出来,没别的意思。
你这样运行的结果是什么:
comm 0
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-06-08 21:50
我觉得还有一个严重的问题,注意
for (i=0,j=0;i<10;i++) {
s[j++]=pw[10+i]>>8;
s[j++]=pw[10+i]&0xFF;
}
这一段是读出 10-19号字节的信息吧.
按理说如果我改成 for (i=0,j=0;i<20;i++) {
s[j++]=pw[27+i]>>8;
s[j++]=pw[27+i]&0xFF;
}
那就是读出27-46号字节的信息,但是你试一下,结果一点都没有变,还是原来的信息. 这个是什么回事?
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-06-08 23:31
pfj,我搞定了,那个问题是我自己的问题,你的程序一点问题都没有.
现在可以得到光驱的信息了.最后一个问题了,这些256个字,通过哪些字可以算出我的硬盘的容量? 我的是15g

wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-06-09 07:46
我读了256个字,哪些字表示该设备是硬盘,哪些字表示是光驱?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-06-09 08:50
字0的位6即是“硬驱动器位”
咦?那个程序中不是判断了不是硬驱才用0xA1命令的么?
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-06-09 14:47
但是不为硬驱动器还有可能是其他的驱动器啊?
不一定就是光驱吧.
所以是不是该有一个位判断是不是光驱?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-06-09 16:07
你判定非硬盘后,用A1命令读256字。其中字0的高字节低5位是类型字段,对CD-ROM此段值为5。
比如我的光驱得到的字:0x85C0
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-06-15 01:06
能不能给我讲讲这段汇编是干什么用的?答辩和写论文的时候不能讲不出吧。
_asm {
mov eax, fs:[0]
push eax
sidt [esp-02h]
pop ebx
mov idt, ebx
add ebx, 0x1C
mov int_idt, ebx

mov eax, [ebx]
mov [Base], eax
mov ax, [ebx-4]
mov [Entry], ax

cli
mov esi, dwExcept
push esi
mov [ebx-4], si
shr esi, 16
mov [ebx+2], si
pop esi
sti

int 3
}
}
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-06-15 02:06
这里还有一段,务必告诉我啊!拜托了!

static void __declspec( naked ) NowInRing0()
{
_asm {
push ebp
mov ebp,esp

call ReadIDE

cli
mov ebx, int_idt
mov ax, Entry
mov word ptr [ebx-4], ax
mov eax, Base
shr eax, 16
mov [ebx+2], ax
sti
leave
iretd
}
}
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-06-15 09:26
摘自Cih:

push    eax             ;                                
                        sidt    [esp-02h]       ; Get IDT Base Address ?;获得中断描述符表的基址到ebx          
                        pop     ebx             ;                                
                                                                                
                        add     ebx, HookExceptionNumber*08h+04h ; ZF = 0 ;计算要用中断的基址到ebx      
                                                                                
                        cli                                      ;在改表项前关中断?              
                                                                                
                        mov     ebp, [ebx]      ; Get Exception Base            
                        mov     bp, [ebx-04h]   ; Entry Point    ?;取得中断基址到ebp                
                                                                                
                        lea     esi, MyExceptionHook-@1[ecx]                    
                                                                                
                        push    esi                                ?;esi为病毒中断例程地址              
                                                                                
                        mov     [ebx-04h], si           ;                        
                        shr     esi, 16                 ; Modify Exception      
                        mov     [ebx+02h], si           ; Entry Point Address;修改中断基址使指向病毒中断例程  
                                                                                
                        pop  esi                                              
                                                                                

                        int     3     ; GenerateException;以中断的方式进入0级      
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-06-15 14:39
你虽然告诉我了每句话的意思,但是整个函数什么意思,以及放在整个程序中的作用。我还是弄不懂。

下面的这两个函数。
static void __declspec( naked ) NowInRing0()
void GetIDEInfo()


[编辑 -  6/15/02 by  wuqixuan]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-06-15 15:14
NowInRing0()就是你新安装的int3处理程序地址,对应于MyExceptionHook-@1[ecx]

GetIDEInfo()通过设置中断描述符表(以NowInRing0的地址做int3处理例程地址),并用int 3指令切入ring0,执行NowInRing0。
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-06-15 15:46
这两段汇编必要吗?我看没有什么必要吧。直接发命令读取端口不就行了吗?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-06-15 17:58
9x体系下虽说很多端口未屏蔽,但仍屏了一些。IDE端口访问可以在ring3进行,但是不能保证其正确性。比如我这儿ring3下读取硬盘数据只能取得低字节(一次读一个字么,高字总为0)。
ring0访问较为妥当
wuqixuan
驱动牛犊
驱动牛犊
  • 注册日期2002-05-25
  • 最后登录2002-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-06-15 18:08
哦。对了,我还有一个帖子,你没有回呢!
游客

返回顶部