Mail Archives: djgpp/2007/09/02/15:30:29
Yeah, my idea seems to be working!
The GPF was caused probably by some wrong arguments handlig, see
below. I remove some code and now I can exec HLT ring0 instruction.
my ring0 code is folowing:
//***************** kod s opravnenim ring 0 - precte MSR dle ECX do
promennych na adresach [EBX], [EDI] (Win9x)
void ring0_rdmsr(void) // GCC bohuzel nepodporuje
__attribute__ ((naked)) na x86
{ // takze misto pointeru na
funkci pouzijeme ASM label
asm __volatile__ (
"rdmsr_label:\n" // label at start of pure code
behind C-function prologue
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"hlt\n"
"lret\n" // far return from ring 0
// "rdmsr\n" // read CPU MSR register
value to EDX:EAX
// "movl %eax,(%ebx)\n" // mov dword ptr [ebx],eax
// "movl %edx,(%edi)\n" // mov dword ptr [edi],edx
); // C-function epilogue will be
never reached
}
//***************** vrati adresu zacatku kodu funkce ring0_rdmsr podle
globalniho labelu (Win9x)
DWord ring0_rdmsr_address(void) // adresa plati v ramci CS
{
DWord addr; // address of labeled code
asm __volatile__ ("movl $rdmsr_label,%%eax" : "=a" (addr)); // load
label address to EAX
return(addr); // return address of labeled
code
}
if it is called via my callgate pointing to segment CS:offset with
DPL=3 it crashes. When I use my CS segment alias with DPL=0
it run without crash. Hope I'm near to finish it!
But I need some help with inline AT&T assembly (I really don't like
it) - I need to pass and get back some arguments
(three words: MSR index input, MSRH,MSRL output) I did it this way
(worked in mingw32):
//***************** Pres CallGate zavola kod v ring 0, in ECX, in/out
EDX:EAX (Win9x)
void exec_ring0_code(DWord code_address, DWord ecx, DWord *eax, DWord
*edx)
{
PM_FAR_POINTER ldt_callgate_ptr; // 48-bit pointer na CallGate
p_ldt_callgate_descriptor->offset_low=(Word)code_address; // offset
na ring0 funkci (low)
p_ldt_callgate_descriptor->offset_high=(Word)(code_address>>16); //
offset na ring0 funkci (high)
movedata(_my_ds(),
(DWord)p_ldt_callgate_descriptor,ldt_ldtsel,ldt_callgate_selector.index*8,8); //
zapis do LDT
ldt_callgate_ptr.offset=0; // napln strukturu pointeru,
CallGate offset=0
ldt_callgate_ptr.selector=ldt_callgate_selector; // CallGate
selector do GDT
printf ("\nCALL: %04X:%08lX [%04Xh]\n",*((Word *)(void
*)&ldt_callgate_ptr.selector),ldt_callgate_ptr.offset,ldt_callgate_ptr.selector.index);
asm __volatile__ ( // volani CallGate
"lcall *%0\n" // far call the CallGate to
enter ring 0, require code far return
: // no outputs (readed data
overwrites input arguments)
: "m" (ldt_callgate_ptr) // inputs
);
/* asm __volatile__ ( // volani CallGate
"pushal\n" // store all registers to stack
"cli\n" // disable interrupts
"movl %0,%%ebx\n" // store pointer to low DWord
"movl %1,%%edi\n" // store pointer to high DWord
"movl %2,%%ecx\n" // store MSR index
"lcall *%3\n" // far call the CallGate to
enter ring 0, require code far return
"sti\n" // enable interrupts
"popal\n" // restore all registers from
stack
: // no outputs (readed data
overwrites input arguments)
: "g" (eax), "g" (edx), "g" (ecx), "m" (ldt_callgate_ptr) //
inputs
);*/
}
in main() its called:
setup_ring0_callgate();
exec_ring0_code(ring0_rdmsr_address(),0,&a,&b);
- Raw text -