Windbg - PEB Paged Out (Virtual Page Size Confusion) - numbers

Can someone please explain to me what this means. (I've bolded the specific part in question).
The "Start VPN" field – in this case, 0x37D9BD30 – indicates the starting virtual page number. This must be converted to an actual address, by multiplying it by the page size. You can use the ? (Evaluate Expression) command to multiply this value by 0x2000, which is the page size for the Itanium-based machine the example comes from.
kd> ? 37d9bd3e*2000
Evaluate expression: 7676040298496 = 000006fb`37a7c000
Then the size of the range can be converted to bytes:
kd> ? 37d9bd3e-37d9bd30+1 <-- computes the number of pages
Evaluate expression: 15 = 00000000`0000000f
kd> ? f*2000
Evaluate expression: 122880 = 00000000`0001e000
So ExplorerFrame.dll starts at address 0x000006Fb37A7C000 and is 0x1E000 bytes large. You can load its symbols with:
kd> .reload /f ExplorerFrame.dll=6fb`37a7c000,1e000

The page size depends on the processor. Calling GetSystemInfo() [MSDN] gives you the page size in the field SYSTEM_INFO.dwPageSize. Wikipedia provides code that does it:
#include <stdio.h>
#include <windows.h>
int main(void) {
SYSTEM_INFO si;
GetSystemInfo(&si);
printf("The page size for this system is %u bytes.\n", si.dwPageSize);
return 0;
}
For the possible page sizes, refer to an Intel CPU manual.
x86 CPUs may have 4k (most common), 2M (PAE supported) or 4M (no PAE support)
x64 CPUs may have 4k (most common), 2M or even have 1G pages. It does not have 4M, since all x64 CPUs support PAE
Itanium may have 4k, 8k, 64k, 256k, 1M, 4M, 16M or 256M pages

Related

How does a microprocessor process an instruction set

For example if I have an 8085 microprocessor.
And below are the instructions.
MVI A, 52H : Store 32H in the accumulator
STA 4000H : Copy accumulator contents at address 4000H
HLT : Terminate program execution
How does the microprocessor understand the commands MVI, STA, HLT.
If I am correct, HLT has 76 as an opcode. In that case, how does a microprocessor recognize 76 as instruction rather than data?
It depends on the processor. Some have fixed-length instructions, in which case the instruction bytes are at every <n> locations, whereas some have variable-length instructions, so that which words/bytes are opcodes and which are arguments depends on what came before. To further complicate this, some processors have certain instructions which must be aligned or padded to certain addresses. Yikes.
The 8085 has variable length instructions. So you have to start at the PC and interpret each instruction based on its length to know where the next begins, and which bytes are data/arguments as opposed to opcodes.
A value of 76 can represent anything, it depends on how it is being interpreted.
In the case of a micro processor, there is a special register that contains the memory address of the next instruction to execute. This data is then loaded and interpreted as an instruction to execute. If the address of the next instruction contains the value 76, this will be interpreted as HLT (in your case). Obviously a different processor might interpret 76 as a different instruction.
On the other hand, if the data from this address is interpreted as a numerical value, it will just mean 76.
It's just that when the processor finds 76 as a part of a program that it is executing, that is, its "program counter" points to the place in memory where the 76 is, it will interpret it as an instruction.
If the processor is then told by its program to load that same 76, from some other place in memory or even from the same place in memory, into a register and use it for calculations, it is interpeted as data.
This is the so called Von Neumann architecture, where program and data are stored in the same computer memory. It all looks the same, but the processor is told by its program which content to treat as data.

Intel Reset Vector

Possible duplicate: Software initialization code at 0xFFFFFFF0H
When the system boots up (Intel), reset vector is at address 0xFFFFFFF0 (16 bytes less than 4G) (as mentioned in above link). That address contains FAR JUMP to where the BIOS is. I read the answer, comments and referenced link, also did some searching, but still cannot understand how 32-bit address can be map to 16-bit (Real Mode)?
My confusion is that in this link: http://www.starman.vertcomp.com/asm/bios/index.html, author mentioned that address F000:FFF0 (16 bytes less than 1MB) contains JUMP to where the BIOS is.
How 0xFFFFFFF0 gets mapped to F000:FFF0? Does it even gets mapped?
If the computer doesn't have physical 4G of memory, let say it has only 1G, where is the 0xFFFFFFF0 address?
Thanks in advance for help.
When I have a chance I will edit this with references.
The 386 manual states that the address lines 31-20 are high on reset until a JMP is encountered, then they are low again. The mapping isn't really there its more of a hack.
The top if the address space where there is no RAM (in a system with say 1GB of RAM) the chipset will map ROM code rather than RAM to that address. It doesn't make sense to have RAM there since on first power on there would be no code there to execute, so it must be non volatile.

Why Does the BIOS INT 0x19 Load Bootloader at "0x7C00"?

As we know the BIOS Interrupt (INT) 0x19 which searches for a boot signature (0xAA55). Loads and executes our bootloader at 0x7C00 if it found.
My Question : Why 0x7C00? What is the reason ? How to evaluate it through some methods?
Maybe because the MBR is loaded into the memory (by the BIOS) into the 0x7c00 address then int 0x19 searches for the MBR sector signature 0xAA55 on sector 0x7c00
about 0xAA55:
Not a checksum, but more of a signature. It does provide some simple
evidence that some MBR is present.
0xAA55 is also an alternating bit pattern: 1010101001010101
It's often used to help determine if you are on a little-endian or
big-endian system, because it will read as either AA55 or 55AA. I
suspect that is part of why it is put on the end of the MBR.
about 0x7c00:
Check this website out (this might help u in finding the answer): https://www.glamenv-septzen.net/en/view/6
This probably dead but I'm going to answer.
At the start of any bootloader when you set the origin of the segment to 0x7c00 then the registers jump address to that as well. So ideally if you check out some online resources that tell you how to use the int 0x19 command they will guide you on how to jump to another address.
To fix this you would ideally, reset the stack to 0 at the start of every jump to an new address.
( It seems like this duplicates following questions:
What is significance of memory at 0000:7c00 to booting sequence?
Does the BIOS copy the 512-byte bootloader to 0x7c00 )
Inspired by an answer to the former, I would quote two sources:
[Notes] Why is the MBR loaded to 0x7C00 on x86? (Full Edition)
So, first answer the question about the 16KB model from David Bradley's reply:
It had to boot on a 32KB machine. DOS 1.0 required a minimum of 32KB,
so we weren't concerned about attempting a boot in 16KB.
To execute DOS 1.0, at least 32KB is required, so the 16KB model has
not been considered.
Followed by the answer to "Why 32KB-1024B?":
We wanted to leave as much room as possible for the OS to load itself
within the 32KB. The 808x Intel architecture used up the first portion
of the memory range for software interrupts, and the BIOS data area
was after it. So we put the bootstrap load at 0x7C00 (32KB-1KB) to
leave all the room in between for the OS to load. The boot sector was
512 bytes, and when it executes it'll need some room for data and a
stack, so that's the other 512 bytes . So the memory map looks like
this after INT 19H executes:
Why BIOS loads MBR into 0x7C00 in x86 ?
No, that case was out of consideration. One of IBM PC 5150 ROM BIOS
Developer Team Members, Dr. David Bradley says:
"DOS 1.0 required a minimum of 32KB, so we weren't concerned about
attempting a boot in 16KB."
(Note: DOS 1.0 required 16KiB minimum ? or 32KiB ? I couldn't find out
which correct. But, at least, in 1981's early BIOS development, they
supposed that 32KiB is DOS minimum requirements.)
BIOS developer team decided 0x7C00 because:
They wanted to leave as much room as possible for the OS to load
itself within the 32KiB.
8086/8088 used 0x0 - 0x3FF for interrupts vector, and BIOS data area
was after it.
The boot sector was 512 bytes, and stack/data area for boot program
needed more 512 bytes.
So, 0x7C00, the last 1024B of 32KiB was chosen.
Once OS loaded and started, boot sector is never used until power reset.
So, OS and application can use the last 1024B of 32KiB freely.
I hope this answer is based enough to be sure why / how it happened so.

Why does Git.pm on cygwin complain about 'Out of memory during "large" request?

I'm getting this error while doing a git svn rebase in cygwin
Out of memory during "large" request for 268439552 bytes, total sbrk() is 140652544 bytes at /usr/lib/perl5/site_perl/Git.pm line 898, <GEN1> line 3.
268439552 is 256MB. Cygwin's maxium memory size is set to 1024MB so I'm guessing that it has a different maximum memory size for perl?
How can I increase the maximum memory size that perl programs can use?
update:
This is where the error occurs (in Git.pm):
while (1) {
my $bytesLeft = $size - $bytesRead;
last unless $bytesLeft;
my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
my $read = read($in, $blob, $bytesToRead, $bytesRead); //line 898
unless (defined($read)) {
$self->_close_cat_blob();
throw Error::Simple("in pipe went bad");
}
$bytesRead += $read;
}
I've added a print before line 898 to print out $bytesToRead and $bytesRead and the result was 1024 for $bytesToRead, and 134220800 for $bytesRead, so it's reading 1024 bytes at a time and it has already read 128MB. Perl's 'read' function must be out of memory and is trying to request for double it's memory size...is there a way to specify how much memory to request? or is that implementation dependent?
UPDATE2:
While testing memory allocation in cygwin:
This C program's output was 1536MB
int main() {
unsigned int bit=0x40000000, sum=0;
char *x;
while (bit > 4096) {
x = malloc(bit);
if (x)
sum += bit;
bit >>= 1;
}
printf("%08x bytes (%.1fMb)\n", sum, sum/1024.0/1024.0);
return 0;
}
While this perl program crashed if the file size is greater than 384MB (but succeeded if the file size was less).
open(F, "<400") or die("can't read\n");
$size = -s "400";
$read = read(F, $s, $size);
The error is similar
Out of memory during "large" request for 536875008 bytes, total sbrk() is 217088 bytes at mem.pl line 6.
This is a problem that has been solved in the latest version of msysgit by Gregor Uhlenheuer. There is a patch available. The problem is that in Git.pm, the file is read in one go. The solution is to read it in small chunks. I'm not sure if the fix has made it into any released versions, but the fix is easy to apply locally.
You need to change C:\Program Files\Git\lib\perl5\site_perl\Git.pm (about 8 lines change). Make sure you back it up first.
For the details of what to do, see Git.pm: Use stream-like writing in cat_blob().
The original discussion is Problems with larger files "Out of memory".
Have you tried increasing overall Cygwin's usable memory?
That message shows Perl was already up to 130 MiB (total sbrk()) and then tried to request a further 256MiB which failed.
From http://www.perlmonks.org/?node_id=541750
By default no Cygwin program can allocate more than 384 MB of memory
(program+data). You should not need to change this default in most
circumstances. However, if you need to use more real or virtual
memory in your machine you may add an entry in the either the
HKEY_LOCAL_MACHINE (to change the limit for all users) or
HKEY_CURRENT_USER (for just the current user) section of the registry.
Add the DWORD value heap_chunk_in_mb and set it to the desired
memory limit in decimal MB. It is preferred to do this in Cygwin
using the regtool program included in the Cygwin package. (For
more information about regtool or the other Cygwin utilities,
see the Section called Cygwin Utilities in Chapter 3 or use
each the --help option of each util.) You should always be
careful when using regtool since damaging your system registry
can result in an unusable system.
This is not a Perl-specific issue, but rather one related to cygwin. You can raise memory allocation with ulimit.
What version of git are you using? If you're not on the latest version, this might be an inefficiency that has been fixed with the latest version (e.g. looping through a very large file with foreach rather than while, as google suggests when I did a quick search.)
Solution with maximizing Cygwin memory actually does not work.
Currently there are two problems with Git on Windows:
Packs more than 2G are hardly
supported by either MsysGit and
Cygwin git
Cygwin default memory
amount is too small
32bit Git is problemistic
What have I done step by step:
I moved my git repo to Unix machine, set next configs:
[pack]
threads = 2
packSizeLimit = 2G
windowMemory = 512M
After that I made git gc and all packs were rebuilded to 2G ones.
Double checked that MsysGit is not installed on Windows machine, other way perl from MsysGit may be used.
Moved this repo back to windows machine and raised Cygwin memory limit:
regtool -i set /HKLM/Software/Cygwin/heap_chunk_in_mb 1536
It was important to set Cygwin memory higher than pack.windowMemory×pack.threads and not higher than 1.5G
So the first two problems are now solved. But the third is not.
Unfortunally it does not work on windows. During some repacks it sometimes crashes with out of memory. Even with threads = 1 and pack.windowMemory = 16M and max depth and delta set to 250.

Mixing 32 bit and 16 bit code with nasm

This is a low-level systems question.
I need to mix 32 bit and 16 bit code because I'm trying to return to real-mode from protected mode. As a bit of background information, my code is doing this just after GRUB boots so I don't have any pesky operating system to tell me what I can and can't do.
Anyway, I use [BITS 32] and [BITS 16] with my assembly to tell nasm which types of operations it should use, but when I test my code use bochs it looks like the for some operations bochs isn't executing the code that I wrote. It looks like the assembler is sticking in extras 0x66 and 0x67's which confuses bochs.
So, how do I get nasm to successfully assemble code where I mix 32 bit and 16 bit code in the same file? Is there some kind of trick?
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
The problem turned out to be that I wasn't setting up my descriptor tables correctly. I had one bit flipped wrong so instead of going to 16-bit mode I was going to 32-bit mode (with segments that happened to have a limit of one meg).
Thanks for the suggestions!
Terry
The 0x66 and 0x67 are opcodes that are used to indicate that the following opcode should be interpreted as a non-default bitness. More specifically, (and according to this link),
"When NASM is in BITS 16 mode, instructions which use 32-bit data are prefixed with an 0x66 byte, and those referring to 32-bit addresses have an 0x67 prefix. In BITS 32 mode, the reverse is true: 32-bit instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and those working on 16-bit addresses need an 0x67."
This suggests that it's bochs that at fault.
You weren't kidding about this being low-level!
Have you checked the generated opcodes / operands to make sure that nasm is honoring your BITS directives correctly? Also check to make sure the jump targets are correct - maybe nasm is using the wrong offsets.
If it's not a bug in nasm, maybe there is a bug in bochs. I can't imagine that people switch back to 16-bit mode from 32-bit mode very often anymore.
If you're in real mode your default size is implicitly 16 bits, so you should use BITS 16 mode. This way if you need a 32-bit operand size you add the 0x66 prefix, and for a 32-bit address size you add the 0x67 prefix.
Look at the Intel IA-32 Software Developer's Guide, Volume 3, Chapter 16 (MIXING 16-BIT AND 32-BIT CODE; the chapter number might change according to the edition of the book):
Real-address mode, virtual-8086 mode, and SMM are native 16-bit modes.
The BITS 32 directive will only confuse the assembler if you use it outside of Protected Mode or Long Mode.