Computing.Net > Forums > Programming > How to read MSR or PhysMem in Win9x

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

How to read MSR or PhysMem in Win9x

Reply to Message Icon

Name: RayeR
Date: February 27, 2007 at 09:44:26 Pacific
OS: Win9x
CPU/Ram: 386+
Comment:

Hi,
I need in my low-level sysinfo win32 app to read MSR register under w9x. It's privileged instructions so my app crashes. As I read the only oficial way is to write own VXD (just for one instruction?) which I dont understand even mingw32 linker cannot produce LE format needed for VXD.

So other way - I found some hack using a callgate. I understand that I need to alloc new segment descriptor with RPL0 pointing to my ring0 function. I can use SGDT SLDT instruction in ring3, fine but what to do with physical address of GDT when I cannot access physical memory? I know how to do it under DPMI but it's not supported in win32 program. Any idea?



Sponsored Link
Ads by Google

Response Number 1
Name: Mechanix2Go
Date: February 28, 2007 at 02:32:23 Pacific
Reply:

in-line ASM?


=====================================
If at first you don't succeed, you're about average.

M2



0

Response Number 2
Name: RayeR
Date: February 28, 2007 at 03:08:09 Pacific
Reply:

I use MinGW32 GCC port for win32. It supports inlined assembler but with that crappy AT&T syntax so I'd like to minimize ASM code.

Well I succed to setup a callgate in GDT. I did't know that the mem maping of GDT is so simle. I readed something about segmentation nightmare but in other example I saw they makes simply a pointer from returned GDTR base and it works. So I can read/write GDT entries and setup my own.

But I still missing something:
1) I read that my ring0 function have to be __attribute__ ((naked)) and have some special prolog/epilog but compiler give me warning that attribute will be ingnored, why?

2) what exactly I should do in ring0 func before executing my code? such some registers save, cli etc...?

3) Need to find how to exec FAR CALL in AT&T ASM.

4) I saw hardcoded callgate selector 28h in that example, why? It gives GDT index 5 with CPL=0. As I see from GDT, index 5 seems to be special with range: base=0 and limit=FFFFFFFFh is it right for all win9x?


0

Response Number 3
Name: RayeR
Date: March 1, 2007 at 19:11:33 Pacific
Reply:

Yeeah, I found a working code for win9x (MSVC) - this is a part of CrystalCPUID OpenSource:
//so now i try it to translate for gcc and found where i made mistake in my code...

=================================================
msr9x.c:
-------------------*/
// Author : hiyohiyo
// Mail : hiyohiyo^crystalmark*info
// Web : http://crystalmark.info/
// License : The modified BSD license
//
// Copyright 2002-2005 hiyohiyo, All rights reserved.
-------------------*/
#include <stdio.h>
#include "msr9x.h"

//////////////////////////////////////////////////////////////////////
// RDMSR
//////////////////////////////////////////////////////////////////////
__declspec(naked) void Ring0ReadMSR()
{
_asm
{
rdmsr
mov [ebx],eax
mov [edi],edx
retf
}
}

//////////////////////////////////////////////////////////////////////
// WRMSR
//////////////////////////////////////////////////////////////////////
__declspec(naked) void Ring0WriteMSR()
{
_asm
{
mov eax,[ebx]
mov edx,[edi]
wrmsr
retf
}
}

//////////////////////////////////////////////////////////////////////
// This function makes it possible to call ring 0 code from a ring 3
// application.
//////////////////////////////////////////////////////////////////////
int CallRing0(PVOID pvRing0FuncAddr,ULONG ulECX,ULONG* pulEAX,ULONG* pulEDX)
{
GDT_DESCRIPTOR *pGDTDescriptor;
GDTR gdtr;
_asm sgdt [gdtr]

// Skip the null descriptor
pGDTDescriptor = (GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
// Search for a free GDT descriptor
for (WORD wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
{
if (pGDTDescriptor->Type == 0 &&
pGDTDescriptor->System == 0 &&
pGDTDescriptor->DPL == 0 &&
pGDTDescriptor->Present == 0)
{
// Found one !
// Now we need to transform this descriptor into a callgate.
// Note that we're using selector 0x28 since it corresponds
// to a ring 0 segment which spans the entire linear address
// space of the processor (0-4GB).
CALLGATE_DESCRIPTOR *pCallgate;
pCallgate = (CALLGATE_DESCRIPTOR *) pGDTDescriptor;
pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
pCallgate->Selector = 0x28;
pCallgate->ParamCount = 0;
pCallgate->Unused = 0;
pCallgate->Type = 0xc;
pCallgate->System = 0;
pCallgate->DPL = 3;
pCallgate->Present = 1;
pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
// Prepare the far call parameters
WORD CallgateAddr[3];
CallgateAddr[0] = 0x0;
CallgateAddr[1] = 0x0;
CallgateAddr[2] = (wGDTIndex << 3) | 3;
// Please fasten your seat belts!
// We're about to make a hyperspace jump into RING 0.
// MessageBox(NULL,"CallGate","START",MB_OK);
_asm mov ebx,pulEAX
_asm mov edi,pulEDX
_asm mov ecx,ulECX
_asm call fword ptr [CallgateAddr]
// We have made it !
// Now free the GDT descriptor
memset(pGDTDescriptor, 0, 8);
// Our journey was successful. Seeya.
return true;
}
// Advance to the next GDT descriptor
pGDTDescriptor++;
}
// Whoops, the GDT is full
return false;
}

BOOL ReadMSR(ULONG ulECX,ULONG* pulEAX,ULONG* pulEDX)
{
CallRing0(Ring0ReadMSR,ulECX,pulEAX,pulEDX);
return TRUE;
}

BOOL WriteMSR(ULONG ulECX,ULONG* pulEAX,ULONG* pulEDX)
{
CallRing0(Ring0WriteMSR,ulECX,pulEAX,pulEDX);
return TRUE;
}

int main(void)
{
ULONG index=0x10, lo, hi;
ReadMSR(index,&lo,&hi);
printf("MSR[10h] = %X%Xh\n",hi,lo);
return(0);
}


0

Sponsored Link
Ads by Google
Reply to Message Icon

Related Posts

See More







Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Programming Forum Home


Sponsored links

Ads by Google


Results for: How to read MSR or PhysMem in Win9x

How to read sector of FAT 32 www.computing.net/answers/programming/how-to-read-sector-of-fat-32-/15189.html

How to read/write data in UNIX Format (.NET) www.computing.net/answers/programming/how-to-readwrite-data-in-unix-format-net/19942.html

How to read bit in C www.computing.net/answers/programming/how-to-read-bit-in-c/10123.html