?? parsecrash.pl
字號:
for (my $cs= struct('THREAD.pcstkTop', $addr) ; $cs ; $cs = struct('CALLSTACK.pcstkNext', $cs)) { printf("CALLSTACK proc=%08lx addr=%08lx sp=%08lx\n", struct('CALLSTACK.pprcLast',$cs)?struct('PROCESS.hProc',struct('CALLSTACK.pprcLast',$cs)):0, struct('CALLSTACK.retAddr',$cs), struct('CALLSTACK.dwPrevSP',$cs)); } }}package PhysicalMemory;use Carp;sub new { my ($class)= @_; return bless {}, $class;}sub Load { my ($self, $fn, $base)= @_; my $fh= IO::File->new($fn, "r") or croak "Physmem::Load $fn: $!\n"; binmode $fh; $self->{$base}= $fh;}sub FindFile { my ($self, $pofs)= @_; for (keys %$self) { if ($_ <= $pofs && $pofs < $_ + -s $self->{$_}) { return ($_, $self->{$_}); } } croak sprintf("PhysicalMemory::FileFile(%08lx) address is not mapped\n", $pofs);}sub ReadData { my ($self, $addr, $size)= @_; my @chunks; while ($size>0) { my ($base, $fh)= $self->FindFile($addr); if (!$fh) { croak sprintf("PhysicalMemory::ReadData(%08lx) address is not mapped\n", $addr); } $fh->seek($addr-$base, 0) or croak sprintf("PhysicalMemory::ReadData(%08lx): seek %08lx: %s\n", $addr, $addr-$base, $!); my $data; $fh->read($data, $size) or croak sprintf("PhysicalMemory::ReadData(%08lx): read %08lx: %s\n", $addr, $size, $!); push @chunks, $data; $size -= length($data); $addr += length($addr); } return join("", @chunks);}sub ReadByte { my ($self, $addr)= @_; return unpack("C", $self->ReadData($addr, 1));}sub ReadWord { my ($self, $addr)= @_; return unpack("v", $self->ReadData($addr, 2));}sub ReadDword { my ($self, $addr)= @_; return unpack("V", $self->ReadData($addr, 4));}sub ReadString { my ($self, $addr)= @_; my $data= $self->ReadData($addr, 64); $data =~ s/\x00.*//; return $data;}sub ReadWString { my ($self, $addr)= @_; if ($addr==0) { return "(pnull)"; } my $data= $self->ReadData($addr, 128); $data= substr($data, 0, index($data, "\x00\x00\x00")+1); $data= pack("C*", unpack("v*", $data)); return "\"".$data."\"";}package VirtualMemory;use Carp;# fedcba9876543210fedcba9876543210# .ssssssbbbbbbbbbpppp............sub VA_SECTION { 25 }sub SECTION_MASK { 0x3f }sub VA_BLOCK { 16 }sub BLOCK_MASK { 0x1ff }sub VA_PAGE { 12 }sub PAGE_MASK { 0xf }sub BAD_PAGE { ~0xf }sub NULL_BLOCK { 0 }sub RESERVED_BLOCK { 1 }sub new { my ($class, $img, $physTLBOfs, $virtSectionsOfs)= @_; my $self= bless { img=>$img, physTLBOfs=>$physTLBOfs, }, $class; return $self;}sub SetSectionTable { my ($self, $vofs)= @_; $self->{virtSectionsOfs}= $vofs;}sub PhysicalToVirtual {}sub VirtualToPhysical { my ($self, $vofs)= @_; if ($vofs<0x80000000 || ($vofs>=0xc2000000 && $vofs<0xc4000000)) { return $self->SectionVirtualToPhysical($vofs); } else { return $self->TLBVirtualToPhysical($vofs); }}sub SectionVirtualToPhysical { my ($self, $vofs)= @_; my $ixSection= ($vofs >> VA_SECTION); $ixSection= 0xb3 if ($ixSection==0x62); # SECURE_SECTION -> KINX_NKSECTION my $ixBlock = ($vofs >> VA_BLOCK) & BLOCK_MASK; my $ixPage = ($vofs >> VA_PAGE) & PAGE_MASK; my $pscn = $self->ReadDword($self->{virtSectionsOfs} + 4*$ixSection); my $pmb = $self->ReadDword($pscn+4*$ixBlock); if ($pmb==NULL_BLOCK) { croak sprintf("SectionVirtualToPhysical(%08lx) : NULL_BLOCK", $vofs); } if ($pmb==RESERVED_BLOCK) { croak sprintf("SectionVirtualToPhysical(%08lx) : RESERVED_BLOCK", $vofs); } my $apages= main::struct("MemBlock.aPages", $pmb); my $dwPageentry= $self->ReadDword($apages+4*$ixPage); if ($dwPageentry==BAD_PAGE) { croak sprintf("SectionVirtualToPhysical(%08lx) : BAD_PAGE", $vofs); } if ($dwPageentry==0 ) { croak sprintf("SectionVirtualToPhysical(%08lx) : NULL_PAGE", $vofs); } if (($dwPageentry&0xfff00000)==0xfff00000) { croak sprintf("SectionVirtualToPhysical(%08lx) : invalid memory", $vofs); } return ($vofs&0xfff)|($dwPageentry&0xfffff000);}sub isValidPtr { my ($self, $vofs)= @_; return 0 if ($vofs<0x10000); return 0 if ($vofs&3); eval { $self->VirtualToPhysical($vofs); }; return (!$@);}sub TLBVirtualToPhysical { my ($self, $vofs)= @_; my $firstLevelIndex= $vofs>>20; my $firstLevelDescriptor= $self->{img}->ReadDword($self->{physTLBOfs}+$firstLevelIndex*4); for ($firstLevelDescriptor&3) { if ($_==0) { croak sprintf("v2p1 %08lx : %08lx -> ignore entry\n", $vofs, $firstLevelDescriptor); } elsif ($_==1) { return $self->CoarseEntry($vofs, $firstLevelDescriptor); } elsif ($_==2) { return $self->SectionEntry($vofs, $firstLevelDescriptor); } elsif ($_==3) { return $self->FineEntry($vofs, $firstLevelDescriptor); } }}sub CoarseEntry { my ($self, $vofs, $firstLevelDescriptor)= @_; my $secondLevelIndex= ($vofs>>12)&0xff; my $pagetable= $firstLevelDescriptor&0xfffffc00; my $secondLevelDescriptor= $self->{img}->ReadDword($pagetable+$secondLevelIndex*4); return $self->SecondLevelPagetable($vofs, $secondLevelDescriptor);}sub SectionEntry { my ($self, $vofs, $firstLevelDescriptor)= @_; my $sectionbase= $firstLevelDescriptor&0xfff00000; return $sectionbase | ($vofs&0xfffff);}sub FineEntry { my ($self, $vofs, $firstLevelDescriptor)= @_; my $secondLevelIndex= ($vofs>>10)&0x3ff; my $pagetable= $firstLevelDescriptor&0xfffff000; my $secondLevelDescriptor= $self->{img}->ReadDword($pagetable+$secondLevelIndex*4); return $self->SecondLevelPagetable($vofs, $secondLevelDescriptor);}sub SecondLevelPagetable { my ($self, $vofs, $secondLevelDescriptor)= @_; for ($secondLevelDescriptor&3) { if ($_==0) { croak sprintf("v2p2: %08lx : %08lx -> ignore entry\n", $vofs, $secondLevelDescriptor); } elsif ($_==1) { return $self->LargePage($vofs, $secondLevelDescriptor); } elsif ($_==2) { return $self->SmallPage($vofs, $secondLevelDescriptor); } elsif ($_==3) { return $self->TinyPage($vofs, $secondLevelDescriptor); } }}sub LargePage { my ($self, $vofs, $secondLevelDescriptor)= @_; return ($secondLevelDescriptor&0xffff0000) | ($vofs&0xffff);}sub SmallPage { my ($self, $vofs, $secondLevelDescriptor)= @_; return ($secondLevelDescriptor&0xfffff000) | ($vofs&0xfff);}sub TinyPage { my ($self, $vofs, $secondLevelDescriptor)= @_; return ($secondLevelDescriptor&0xfffffc00) | ($vofs&0x3ff);}################################ todo: these functions don't handle page boundaries.sub ReadData { my ($self, $vofs, @args)= @_; return $self->{img}->ReadData($self->VirtualToPhysical($vofs), @args);}sub ReadByte { my ($self, $vofs, @args)= @_; return $self->{img}->ReadByte($self->VirtualToPhysical($vofs), @args);}sub ReadWord { my ($self, $vofs, @args)= @_; return $self->{img}->ReadWord($self->VirtualToPhysical($vofs), @args);}sub ReadDword { my ($self, $vofs, @args)= @_; return $self->{img}->ReadDword($self->VirtualToPhysical($vofs), @args);}sub ReadString { my ($self, $vofs, @args)= @_; return $self->{img}->ReadString($self->VirtualToPhysical($vofs), @args);}sub ReadWString { my ($self, $vofs, @args)= @_; if ($vofs==0) { return "(vnull)"; } my $str; eval { $str= $self->{img}->ReadWString($self->VirtualToPhysical($vofs), @args); }; if ($@) { return "(invalid)"; } return $str;}package main;__DATA__# z:/sources/wince500/PRIVATE/WINCEOS/COREOS/NK/INC/nkarm.h!kdata0xFFFD0000 firstpagetabel# 0xFFFD4000 - disabled for protection0xFFFE0000 secondpagetabel# 0xFFFE4000 - disabled for protection0xFFFF0000 exceptionvectors# 0xFFFF0400 - not used (r/o)# 0xFFFF1000 - disabled for protection# 0xFFFF2000 - r/o (physical overlaps with vectors)# 0xFFFF2400 - Interrupt stack (1k)# 0xFFFF2800 - r/o (physical overlaps with Abort stack & FIQ stack)# 0xFFFF3000 - disabled for protection# 0xFFFF4000 - r/o (physical memory overlaps with vectors & intr. stack & FIQ stack)# 0xFFFF4900 - Abort stack (2k - 256 bytes)# 0xFFFF5000 - disabled for protection# 0xFFFF6000 - r/o (physical memory overlaps with vectors & intr. stack)# 0xFFFF6800 - FIQ stack (256 bytes)# 0xFFFF6900 - r/o (physical memory overlaps with Abort stack)# 0xFFFF7000 - disabled# 0xFFFFC000 - kernel stack# 0xFFFFC800 - KDataStruct0xFFFFC800 lpvTls Current thread local storage pointer0xFFFFC804 ahSys_W320xFFFFC808 hCurThread0xFFFFC80C hCurProc0xFFFFC810 ahSys_KW320xFFFFC884 bResched reschedule flag0xFFFFC885 cNest kernel exception nesting0xFFFFC886 bPowerOff TRUE during "power off" processing0xFFFFC887 bProfileOn TRUE if profiling enabled0xFFFFC888 unused0xFFFFC88C rsvd2 was DiffMSec0xFFFFC890 pCurPrc ptr to current PROCESS struct0xFFFFC894 pCurThd ptr to current THREAD struct0xFFFFC898 dwKCRes0xFFFFC89C handleBase handle table base address0xFFFFC8A0 aSections section table for virutal memory0xFFFFC9A0 alpeIntrEvents0xFFFFCA20 alpvIntrData0xFFFFCAA0 pAPIReturn direct API return address for kernel mode0xFFFFCAA4 pMap ptr to MemoryMap array0xFFFFCAA8 dwInDebugger !0 when in debugger0xFFFFCAAC pCurFPUOwner current FPU owner0xFFFFCAB0 pCpuASIDPrc current ASID proc0xFFFFCAB4 nMemForPT Memory used for PageTables0xFFFFCAB8 aPend10xFFFFCABC aPend20xFFFFCAC0 alPad# z:/sources/wince500/PUBLIC/COMMON/OAK/INC/pkfuncs.h0xFFFFCB00 KINX_PROCARRAY address of process array0xFFFFCB04 KINX_PAGESIZE system page size0xFFFFCB08 KINX_PFN_SHIFT shift for page # in PTE0xFFFFCB0C KINX_PFN_MASK mask for page # in PTE0xFFFFCB10 KINX_PAGEFREE # of free physical pages0xFFFFCB14 KINX_SYSPAGES # of pages used by kernel0xFFFFCB18 KINX_KHEAP ptr to kernel heap array0xFFFFCB1C KINX_SECTIONS ptr to SectionTable array0xFFFFCB20 KINX_MEMINFO ptr to system MemoryInfo struct0xFFFFCB24 KINX_MODULES ptr to module list0xFFFFCB28 KINX_DLL_LOW lower bound of DLL shared space0xFFFFCB2C KINX_NUMPAGES total # of RAM pages0xFFFFCB30 KINX_PTOC ptr to ROM table of contents points to ROMHDR struct0xFFFFCB34 KINX_KDATA_ADDR kernel mode version of KData0xFFFFCB38 KINX_GWESHEAPINFO Current amount of gwes heap in use0xFFFFCB3C KINX_TIMEZONEBIAS Fast timezone bias info0xFFFFCB40 KINX_PENDEVENTS bit mask for pending interrupt events0xFFFFCB44 KINX_KERNRESERVE number of kernel reserved pages0xFFFFCB48 KINX_API_MASK bit mask for registered api sets0xFFFFCB4C KINX_NLS_CP hiword OEM code page, loword ANSI code page0xFFFFCB50 KINX_NLS_SYSLOC Default System locale0xFFFFCB54 KINX_NLS_USERLOC Default User locale0xFFFFCB58 KINX_HEAP_WASTE Kernel heap wasted space0xFFFFCB5C KINX_DEBUGGER For use by debugger for protocol communication
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -