2

I just used DUMPBIN for the first time and I see the term HIGHLOW repeatedly in the output file:

BASE RELOCATIONS #7
   11000 RVA,       E0 SizeOfBlock
    ...
         3B5  HIGHLOW            2001753D  ___onexitbegin
         3C1  HIGHLOW            2001753D  ___onexitbegin
    ...

I'm curious what this term stands for. I didn't find anything on Google or Stackoverflow about it.

Paul R
  • 208,748
  • 37
  • 389
  • 560

2 Answers2

6

To apply a fixup, a delta is calculated as the difference between the preferred base address, and the base where the image is actually loaded.

The basic idea is that when doing a fixup at some address, we must know

  1. what memory must be changed ("offset" field)
  2. what value is needed for its relocation ("delta" value)
  3. which parts of relocated data and delta value to use ("type" field)

Here are some possible values of the "type" field

  • HIGH - add higher word (16 bits) of delta to the 16-bit value at "offset"
  • LOW - add lower word of delta to the value at "offset"
  • HIGHLOW - add full delta to the 32-bit value at "offset"

In other words, HIGHLOW type tells the program that it's doing a fix-up on offset "offset" from the page of this relocation block*, and that there is a doubleword that needs to be modified in order to have properly working executable.

* all of the relocation entries are grouped into blocks, and every block has a page on which its entries are applied

Let's say that you have this instruction in your code:

section .data
message: "Hello World!", 0

section .code
...
mov eax, message
...

You run assembler and immediately after it you run disassembler. Now your code looks like this:

mov eax, dword [0x702000]

You're now curious why is it 0x700000, and when you look into file dump, you see that

ImageBase:      0x00700000

Now you understand where did this number come from and you'e ready to run the executable. Loader which loads executable files into memory and creates address space for them finds out, that memory 0x700000 is unavailable and it needs to place that file somewhere else. It decides that 0xf00000 will be OK and copies the file contents there.

But, your program was linked to work only with data on 0x700000 and there was no way for linker to know that its output would be relocated. Because of this, loader must do its magic. It

  1. calculates delta value - the old address (image base) is 0x700000 but it wants 0xf00000 (preferred address). It subtracts one from another and gets 0x800000 as result.
  2. gets to the .reloc section of the file
  3. checks if there is still another page (4KB of data) to be relocated. If no, it continues toward calling file“s entry point. 4.for every relocation for the current page, it
  4. gets data at relocation offset
  5. adds the delta value (in the way as type field states)
  6. places the new value at relocation offset
  7. continues on step 3

There are also more types of relocation entry and some of them are architecture-specific. To see a full list, read the "Microsoft Portable Executable and Common Object File Format, section 6.6.2. Fixup Types".

user35443
  • 6,309
  • 12
  • 52
  • 75
2

What you see here is the content of the "Base relocation table" in Microsoft Windows executable files.

Base relocation tables are necessary in Windows for DLL files and they are optional for executable files; they contain information about the location of address information in the EXE/DLL file that must be updated when the actual address of the DLL file in memory is known (when loading the DLL into memory). Windows uses the information stored in this table to update the address information.

The table supports different types of addresses while the naming is Microsoft-specific: ABSOLUTE (= dummy), HIGH, LOW, HIGHLOW, HIGHADJ and MIPS_JMPADDR.

The full name of the constant is "IMAGE_REL_BASED_HIGHLOW".

The "ABSOLUTE" type is typically a dummy entry inserted to ensure the parts of the table are a multiple of 4 (or 8) bytes long.

On x86 CPUs only the "HIGHLOW" type is used: It tells Windows about the location of an absolute (32-bit) address in the file.

Some background info:

In your example the "Image Base" could be 0x20000000 which means that the EXE/DLL file has been compiled to be loaded into address 0x20000000. At the addresses 0x200113B5 (0x20000000 + 0x11000 + 0x3B5) and 0x200113C1 there are absolute addresses.

Let's say the memory at location 0x200113B5 contains the value 0x20012345 which is the address of a function or variable in the program.

Maybe the memory at address 0x20000000 cannot be used and Windows decides to load the DLL into the memory at 0x50000000 instead. Then the 0x20012345 must be replaced by 0x50012345.

The information in the base relocation table is used by Windows to find all addresses that must be replaced.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38