Porting pice. Fixed bug in interrupt handling.

svn path=/trunk/; revision=2554
This commit is contained in:
Eugene Ingerman 2002-01-26 05:17:45 +00:00
parent 12359f4a27
commit 6c0fa06e39
11 changed files with 143 additions and 73 deletions

View file

@ -15,7 +15,7 @@ Environment:
LINUX 2.2.X
Kernel mode only
Author:
Author:
Klaus P. Gerlicher
@ -34,8 +34,8 @@ Copyright notice:
#define LEAVE_FUNC() DPRINT((0,"leave "__FUNCTION__"()\n"))
VOID Pice_dprintf(ULONG DebugLevel, PCHAR DebugMessage, ...);
#define DPRINT(arg) Pice_dprintf arg
VOID Pice_dprintf(ULONG DebugLevel, PCHAR DebugMessage, ...);
#define DPRINT(arg) Pice_dprintf arg
#else // DEBUG

View file

@ -52,7 +52,7 @@ char tempGP[1024];
//*************************************************************************
void HandleGPFault(FRAME* ptr)
{
DPRINT((0,"HandleGPFault(): ptr = %x\n",ptr));
DPRINT((2,"HandleGPFault(): ptr = %x at eip: %x\n",ptr, ptr->eip));
}
//*************************************************************************

View file

@ -129,7 +129,7 @@ BOOLEAN InitPICE(void)
DPRINT((0,"InitPICE(): trace step 7\n"));
ScanExports("_KernelAddressSpace", &ulAddr);
my_init_mm = (PEPROCESS) ulAddr;
my_init_mm = (PMADDRESS_SPACE) ulAddr;
DPRINT((0,"init_mm %x @ %x\n",&my_init_mm,my_init_mm));
if(!my_init_mm)
{
@ -282,7 +282,6 @@ BOOLEAN InitPICE(void)
InstallDblFltHook();
InstallGPFaultHook();
InstallIntEHook();
//__asm__("int3");
InstallPrintkHook();
DPRINT((0,"InitPICE(): trace step 16\n"));

View file

@ -247,6 +247,7 @@ void InstallPrintkHook(void)
{
ENTER_FUNC();
//ei disabled for now
return;
if( bIsPrintkPatched )
return;

View file

@ -1941,13 +1941,14 @@ COMMAND_PROTOTYPE(ShowVirtualMemory)
{
PEPROCESS my_current = IoGetCurrentProcess();
PLIST_ENTRY current_entry;
PMADDRESS_SPACE vma;
PMADDRESS_SPACE vma = NULL;
MEMORY_AREA* current;
char filename[64];
DPRINT((0,"ShowVirtualMemory()\n"));
if( my_current )
vma = &(my_current->AddressSpace);
vma = &(my_current->AddressSpace);
if(vma)
{
if(pArgs->Count == 0)
@ -2475,8 +2476,9 @@ COMMAND_PROTOTYPE(SwitchTables)
char temp[DEBUG_MODULE_NAME_LEN];
CopyWideToAnsi(temp,pMod->name);
pCurrentSymbols = (PICE_SYMBOLFILE_HEADER*)pArgs->Value[0];
pCurrentSymbols = FindModuleSymbolsByModuleName( temp );
DPRINT((2,"TableSwitchSym: pCurrentSymbols: %x, Name: %S\n", pCurrentSymbols, pCurrentSymbols->name));
pTempMod = IsModuleLoaded(temp);
if( pTempMod )
pCurrentMod = pTempMod;

View file

@ -82,13 +82,14 @@ BOOLEAN PiceKbdIsr (
UCHAR ucKey = *pByte & 0x7f;
ENTER_FUNC();
// BUG!! should protect with spinlock since bControl is static.
DPRINT((5,"PiceKbdIsr(pByte: %x, val: %x,%u)\n",pByte,*pByte,isDown));
DPRINT((5,"PiceKbdIsr(1): bControl = %u bForward = %u bEnterNow = %u\n",bControl,bForward,bEnterNow));
// BUG?? should protect with spinlock since bControl is static.
DPRINT((0,"PiceKbdIsr(pByte: %x, val: %x,%u)\n",pByte,*pByte,isDown));
DPRINT((0,"PiceKbdIsr(1): bControl = %u bForward = %u bEnterNow = %u\n",bControl,bForward,bEnterNow));
if(isDown)
{
DPRINT((2,"bControl: %x, ucKey: %x, breakkey: %x\n", bControl, ucKey, AsciiToScan(ucBreakKey)));
DPRINT((0,"bControl: %x, ucKey: %x, breakkey: %x\n", bControl, ucKey, AsciiToScan(ucBreakKey)));
// CTRL pressed
if(ucKey==0x1d)
{

View file

@ -46,6 +46,8 @@ extern void NewInt31Handler(void);
ULONG OldIntEHandler=0;
ULONG error_code;
BOOLEAN bInPageFaultHandler = FALSE;
static ULONG PCR_SEL = PCR_SELECTOR;
static ULONG OLD_PCR;
////////////////////////////////////////////////////
// FUNCTIONS
@ -61,15 +63,14 @@ ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address)
ENTER_FUNC();
DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while inside debugger\n",address));
DPRINT((2,"HandleInDebuggerFault(): ###### page fault @ %.8X while inside debugger, eip: %x\n",address, ptr->eip));
// fault in this page fault handler
if(bInPageFaultHandler)
{
DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while in page fault handler\n",address));
DPRINT((0,"!!! machine is halted !!!\n"));
DPRINT((2,"HandleInDebuggerFault(): ###### page fault @ %.8X while in page fault handler\n",address));
DPRINT((2,"!!! machine is halted !!!\n"));
__asm__ __volatile__ ("hlt");
LEAVE_FUNC();
@ -82,7 +83,7 @@ ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address)
// so the current task is different as well
tsk = IoGetCurrentProcess();
DPRINT((0,"%.8X (%.4X:%.8X %.8X %s %s %s task=%.8X )\n",
DPRINT((2,"%.8X (%.4X:%.8X %.8X %s %s %s task=%.8X )\n",
address,
ptr->cs,
ptr->eip,
@ -127,7 +128,6 @@ ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address)
IntelStackWalk(ptr->eip,CurrentEBP,ulRealStackPtr);
DPRINT((0,"!!! machine is halted !!!\n"));
__asm__ __volatile__ ("hlt");
LEAVE_FUNC();
@ -146,31 +146,32 @@ ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address)
ULONG HandlePageFault(FRAME* ptr)
{
PVOID address;
PEPROCESS tsk;
PEPROCESS tsk, tsk1;
PMADDRESS_SPACE vma;
PLIST_ENTRY current_entry;
MEMORY_AREA* current;
ULONG value;
PKTHREAD CurrentThread;
PETHREAD CurrentEThread;
//for some reason stack is corrupted. disable for now.
return 0;
// get linear address of page fault
__asm__ __volatile__("movl %%cr2,%0"
:"=r" (address));
// get linear address of page fault
__asm__("movl %%cr2,%0":"=r" (address));
// current process
tsk = IoGetCurrentProcess();
DPRINT((2,"\nPageFault: Name: %s, bInDebShell: %d, error: %d, addr: %x\n", tsk->ImageFileName, bInDebuggerShell, ptr->error_code, address));
DPRINT((0,"\nPageFault: bInDebShell: %d, error: %d, addr: %x\n", bInDebuggerShell, ptr->error_code, address));
// there's something terribly wrong if we get a fault in our command handler
if(bInDebuggerShell)
{
DPRINT((2,"return handleindebuggerfault\n"));
return HandleInDebuggerFault(ptr,(ULONG)address);
}
ASSERT(IsAddressValid((ULONG)ptr));
// remember error code so we can push it back on the stack
error_code = ptr->error_code;
// interrupt handlers can't have page faults
//ei Check IRQL here!!!
/*
if(in_interrupt())
{
@ -178,16 +179,32 @@ ULONG HandlePageFault(FRAME* ptr)
return 1;
}
*/
// lookup VMA for this address
// current process
tsk = IoGetCurrentProcess();
if( !tsk || !(IsAddressValid((ULONG)tsk))){
DPRINT((0,"tsk address not valid: tsk: %x\n", tsk));
return 0;
}
// lookup VMA for this address
vma = &(tsk->AddressSpace);
if( !vma || !(IsAddressValid((ULONG)vma))){
DPRINT((0,"vma not valid: vma: %x\n", vma));
return 0;
}
current_entry = vma->MAreaListHead.Flink;
ASSERT(current_entry);
DPRINT((0,"vma: %x, current_entry: %x, kernel arena: %x\n", vma, current_entry, my_init_mm));
while(current_entry != &vma->MAreaListHead)
{
ASSERT(current_entry);
ASSERT(IsAddressValid((ULONG)current_entry));
current = CONTAINING_RECORD(current_entry,
MEMORY_AREA,
Entry);
DPRINT((2,"address: %x %x - %x Attrib: %x, Type: %x\n", address, current->BaseAddress, current->BaseAddress + current->Length, current->Attributes, current->Type));
return 0;
DPRINT((0,"address: %x %x - %x Attrib: %x, Type: %x\n", address, current->BaseAddress, current->BaseAddress + current->Length, current->Attributes, current->Type));
if( (address >= current->BaseAddress) && (address <= current->BaseAddress + current->Length ))
{
//page not present
@ -196,12 +213,15 @@ ULONG HandlePageFault(FRAME* ptr)
if( current->Type == MEMORY_AREA_SECTION_VIEW_COMMIT ||
current->Type == MEMORY_AREA_SECTION_VIEW_RESERVE ||
current->Type == MEMORY_AREA_VIRTUAL_MEMORY ||
current->Type == MEMORY_AREA_PAGED_POOL
current->Type == MEMORY_AREA_PAGED_POOL ||
current->Type == MEMORY_AREA_SHARED_DATA
){
Print(OUTPUT_WINDOW,"pICE: VMA Pageable Section.\n");
//Print(OUTPUT_WINDOW,"pICE: VMA Pageable Section.\n");
DPRINT((2,"return 0 1\n"));
return 0; //let the system handle this
}
Print(OUTPUT_WINDOW,"pICE: VMA Page not present in non-pageable Section!\n");
DPRINT((2,"Type: currenttype: %x return 1 2\n", current->Type));
return 1;
}
else{ //access violation
@ -211,8 +231,10 @@ ULONG HandlePageFault(FRAME* ptr)
if( (ULONG)address >= KERNEL_BASE )
{
Print(OUTPUT_WINDOW,"pICE: User mode program trying to access kernel memory!\n");
DPRINT((2,"return 1 3\n"));
return 1;
}
DPRINT((2,"return 0 4\n"));
return 0;
}
/*
@ -245,6 +267,7 @@ ULONG HandlePageFault(FRAME* ptr)
*/
// let the system handle it
DPRINT((2,"return 0 5\n"));
return 0;
}
}
@ -252,7 +275,8 @@ ULONG HandlePageFault(FRAME* ptr)
}
Print(OUTPUT_WINDOW,"pICE: no virtual memory arena at this address!\n");
return 0;
DPRINT((2,"return 0 6\n"));
return 0;
// let the system handle it
// return 0;
@ -274,12 +298,25 @@ NewIntEHandler:
movw %ss,%ax
movw %ax,%ds
/*
* Load the PCR selector.
*/
movl %fs, %eax
movl %eax, _OLD_PCR
movl _PCR_SEL, %eax
movl %eax, %fs
// get frame ptr
lea 40(%esp),%eax
pushl %eax
call _HandlePageFault
addl $4,%esp
pushl %eax
movl _OLD_PCR, %eax
movl %eax, %fs
popl %eax
cmpl $0,%eax
je call_old_inte_handler
@ -330,7 +367,7 @@ void InstallIntEHook(void)
MaskIrqs();
if(!OldIntEHandler)
{
__asm__("mov $NewIntEHandler,%0"
__asm__ __volatile__("mov $NewIntEHandler,%0"
:"=r" (LocalIntEHandler)
:
:"eax");

View file

@ -82,6 +82,8 @@ volatile BOOLEAN bInDebuggerShell=FALSE; // TRUE while in DebuggerShell()
BOOLEAN bIrqStateAtBreak;
ULONG ulRealStackPtr;
static ULONG PCR_SEL = PCR_SELECTOR;
static ULONG OLD_PCR;
char tempShell[256]; // temporary string container
@ -1038,8 +1040,8 @@ void RealIsr(ULONG dwReasonForBreak)
bIrqStateAtBreak = ((CurrentEFL&(1<<9))!=0);
DPRINT((2,"\nbInDebuggerShell %x, dwReasonForBreak: %x, bIrqStateAtBreak: %d\n", bInDebuggerShell, dwReasonForBreak, bIrqStateAtBreak));
DPRINT((2,"CurrentEIP: %x, CurrentESP: %x\n", CurrentEIP, CurrentESP));
DPRINT((0,"\nbInDebuggerShell %x, dwReasonForBreak: %x, bIrqStateAtBreak: %d\n", bInDebuggerShell, dwReasonForBreak, bIrqStateAtBreak));
DPRINT((0,"CurrentEIP: %x, CurrentESP: %x\n", CurrentEIP, CurrentESP));
// came in because TF flag was set
if(dwReasonForBreak == REASON_SINGLESTEP)
@ -1527,6 +1529,15 @@ afterswitch:
// get reason code
mov 0x28(%esp),%ebx
/*
* Load the PCR selector.
*/
movl %fs, %eax
movl %eax, _OLD_PCR
movl _PCR_SEL, %eax
movl %eax, %fs
// setup a large work stack
movl %esp,%eax
movl %eax,_ulRealStackPtr
@ -1535,7 +1546,12 @@ afterswitch:
call _RealIsr
addl $4,%esp
// restore all regs
pushl %eax
movl _OLD_PCR, %eax
movl %eax, %fs
popl %eax
// restore all regs
popal
// do an EOI to IRQ controller (because we definitely pressed some key)

View file

@ -152,29 +152,33 @@ BOOLEAN ListUserModules( PPEB peb )
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_MODULE Module;
PPEB_LDR_DATA Ldr;
ENTER_FUNC();
ModuleListHead = &peb->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
//DbgPrint("Module: %x, BaseAddress: %x\n", Module, Module->BaseAddress);
Ldr = peb->Ldr;
if( Ldr && IsAddressValid((ULONG)Ldr)){
ModuleListHead = &Ldr->InLoadOrderModuleList;
ASSERT(IsAddressValid((ULONG)ModuleListHead));
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
//DbgPrint("Module: %x, BaseAddress: %x\n", Module, Module->BaseAddress);
DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x, BaseAddress: %x\n", Module->FullDllName.Buffer,
Module->BaseDllName.Buffer, Module->SizeOfImage, Module->EntryPoint, Module->BaseAddress ));
DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x, BaseAddress: %x\n", Module->FullDllName.Buffer,
Module->BaseDllName.Buffer, Module->SizeOfImage, Module->EntryPoint, Module->BaseAddress ));
pdebug_module_tail->size = Module->SizeOfImage;
pdebug_module_tail->BaseAddress = Module->BaseAddress;
pdebug_module_tail->EntryPoint = (PVOID)(Module->EntryPoint);
ASSERT(Module->BaseDllName.Length<DEBUG_MODULE_NAME_LEN); //name length is limited
PICE_wcscpy( pdebug_module_tail->name, Module->BaseDllName.Buffer );
pdebug_module_tail = pdebug_module_tail->next;
pdebug_module_tail->size = Module->SizeOfImage;
pdebug_module_tail->BaseAddress = Module->BaseAddress;
pdebug_module_tail->EntryPoint = (PVOID)(Module->EntryPoint);
ASSERT(Module->BaseDllName.Length<DEBUG_MODULE_NAME_LEN); //name length is limited
PICE_wcscpy( pdebug_module_tail->name, Module->BaseDllName.Buffer );
pdebug_module_tail = pdebug_module_tail->next;
Entry = Entry->Flink;
Entry = Entry->Flink;
}
}
LEAVE_FUNC();
return TRUE;
}
@ -248,15 +252,21 @@ BOOLEAN ListDriverModules( void )
BOOLEAN BuildModuleList( void )
{
PPEB peb;
PEPROCESS tsk;
ENTER_FUNC();
pdebug_module_tail = pdebug_module_head;
peb = IoGetCurrentProcess()->Peb;
if( peb ){
if( !ListUserModules( peb ) ){
LEAVE_FUNC();
return FALSE;
tsk = IoGetCurrentProcess();
ASSERT(IsAddressValid((ULONG)tsk));
if( tsk ){
peb = tsk->Peb;
ASSERT(IsAddressValid((ULONG)peb));
if( peb ){
if( !ListUserModules( peb ) ){
LEAVE_FUNC();
return FALSE;
}
}
}
if( !ListDriverModules() ){
@ -450,6 +460,7 @@ PICE_SYMBOLFILE_HEADER* FindModuleSymbols(ULONG addr)
pd = pdebug_module_head;
do
{
DPRINT((0,"pd: %x\n", pd));
if(pd->size)
{
start = (ULONG)pd->BaseAddress;
@ -591,8 +602,11 @@ BOOLEAN ScanExportsByAddress(LPSTR *pFind,ULONG ulValue)
LPSTR pName;
ENTER_FUNC();
DPRINT((0,"In ScanExportsByAddress:\n"));
pSymbols = FindModuleSymbols(ulValue);
DPRINT((0,"pSymbols: %x\n", pSymbols));
if(BuildModuleList()){
if(pSymbols && pdebug_module_head)
{
@ -1961,37 +1975,37 @@ PICE_SYMBOLFILE_HEADER* LoadSymbols(LPSTR filename)
if( !( conv = PICE_MultiByteToWideChar(CP_ACP, NULL, filename, -1, tempstr, 256 ) ) )
{
DPRINT((2,"Can't convert module name.\n"));
DPRINT((0,"Can't convert module name.\n"));
return NULL;
}
DPRINT((2,"LoadSymbols: filename %s, tempstr %S, conv: %d\n", filename, tempstr, conv));
DPRINT((0,"LoadSymbols: filename %s, tempstr %S, conv: %d\n", filename, tempstr, conv));
if(ulNumSymbolsLoaded<DIM(apSymbols))
{
hf = PICE_open(tempstr,OF_READ);
DPRINT((2,"LoadSymbols: hf: %x, file: %S\n",hf, tempstr));
DPRINT((0,"LoadSymbols: hf: %x, file: %S\n",hf, tempstr));
if(hf)
{
//mm_segment_t oldfs;
size_t len;
DPRINT((2,"hf = %x\n",hf));
DPRINT((0,"hf = %x\n",hf));
len = PICE_len(hf);
DPRINT((2,"file len = %d\n",len));
DPRINT((0,"file len = %d\n",len));
if(len)
{
pSymbols = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
DPRINT((2,"pSymbols = %x\n",pSymbols));
DPRINT((0,"pSymbols = %x\n",pSymbols));
if(pSymbols)
{
//oldfs = get_fs(); set_fs(KERNEL_DS);
if(len == PICE_read(hf,(PVOID)pSymbols,len))
{
DPRINT((2,"LoadSymbols(): success reading symbols!\n"));
DPRINT((2,"LoadSymbols(): pSymbols->magic = %X\n",pSymbols->magic));
DPRINT((0,"LoadSymbols(): success reading symbols!\n"));
DPRINT((0,"LoadSymbols(): pSymbols->magic = %X\n",pSymbols->magic));
}
//set_fs(oldfs);
@ -2022,7 +2036,7 @@ PICE_SYMBOLFILE_HEADER* LoadSymbols(LPSTR filename)
}
else
{
DPRINT((2,"pICE: could not load symbols for %s...\n",filename));
DPRINT((0,"pICE: could not load symbols for %s...\n",filename));
}
}
@ -2183,7 +2197,7 @@ BOOLEAN LoadSymbolsFromConfig(BOOLEAN bIgnoreBootParams)
{
DPRINT((0,"Load symbols from file %s\n", temp));
pSymbols = LoadSymbols(temp);
DPRINT((2,"Load symbols from file %s, pSymbols: %x\n", temp, pSymbols));
DPRINT((0,"Load symbols from file %s, pSymbols: %x\n", temp, pSymbols));
if(pSymbols)
{
PICE_SYMBOLFILE_SOURCE* pSrc;

View file

@ -1622,7 +1622,7 @@ size_t PICE_strnlen(const char * s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
for (sc = s; count-- && IsAddressValid((ULONG)sc) && *sc != '\0'; ++sc)
/* nothing */;
return sc - s;
}
@ -2187,7 +2187,7 @@ int PICE_close (HANDLE hFile)
{
return 0;
}
DPRINT((2,"ZwClose failed:\n"));
DPRINT((0,"ZwClose failed:\n"));
return -1;
}

View file

@ -272,7 +272,7 @@ ULONG inl(PULONG port);
//struct mm_struct *GetInitMm(void);
PEPROCESS my_init_mm;
PMADDRESS_SPACE my_init_mm;
LIST_ENTRY* pPsProcessListHead;
void EnablePassThrough(void);