Segmentation, Pages and DPP# ExampleYou will need to do some reverse math to locate references to maps within code.
Remember I mentioned you need to think like the CPU and understand the segmentation?
For the MS43... It uses 1MB of linear address space.
In 1MB of memory there are 16 x 64kB segments.
Each segment has 4 - 16kB pages.
Therefore in 1MB of memory you will have 64 pages.
In code a DPP# is used to assist accessing linear memory and it contains a page reference or index.
You need 21 bits to address up to 1MB of memory.
When forming an address the CPU uses a word operand.
The top two bits 14 & 15 of the word is the DPP#.
i.e.:
00 = DPP0
01 = DPP1
10 = DPP2
11 = DPP3
The lower bits 0 - 13 is the offset within a page.
Each DPP is loaded with a value which is then combined with the page offset to form the linear memory address.
Attachment:
addressing.png
Now the math...
The map axis/data segment is from 0x70000 - 0x7FFFF. Converted to pages this is:
0x70000/0x4000 = 0x1C
0x74000/0x4000 = 0x1D
0x78000/0x4000 = 0x1E
0x7C000/0x4000 = 0x1F
Assuming the code uses DPP0 in the operand the top two bits of the word will be 00.
Therefore in binary:
00xx xxxx xxxx xxxx
Remember the xxxx's are the offset within a page.
For example, assume an axis at 0x74AD4 and data at 0x7581E, these are both within the 0x74000 (0x1D) page.
One thing to remember about the axis is that the code reference is to the axis size value not the axis values so you need to subtract 1 for byte or two for word. Let's assume the axis is word data, therefore 0x74AD4 - 2 = 0x74AD2
0x74AD2 in binary:
0111 0100 1010 1101 0010
Attachment:
calc1.png
Now remove the 0x1D page reference from the binary (remember 1D starts at bit 14 and up):
0000 0000 1010 1101 0010
Attachment:
calc2.png
In the Calculator you can toggle bits by clicking them, where I underscored in red.
You are left with 0xAD2.
Since we are assuming DPP0 then we can leave bits 14 & 15 at 00, otherwise we would toggle these bits on/off depending on the DPP# in the code.For the data address 0x7581E with 0x1D removed you are left with 0x181E.
Since IDA has no idea that this is a memory reference (
since the values are loaded in a register and then a sub_ is called to process them) you will need to search for the offset and tell IDA how to view it.
Initially IDA will show the offset as a word value. In this example #0AD2 and #181E. You can Text search for those strings assuming all subroutines have been defined as code or hex search for 0AD2 and 181E.
Attachment:
search.png
In the results you can see the code line below the reference has a value of #1Dh which is the value to be loaded into DPP0 within the sub_. At the code reference to your search value you press alt-g and set DPP0 to 1D. Then at the code reference to your search value right click on the operand and set the Offset to the 0x7xxxx item.
Attachment:
setDPP.png
Rinse and repeat...