1

I had recently this situation where in a program I was debugging I found:

03CD38D4:  8B15 8C5FF703  MOV EDX, DWORD PTR DS:[3F75F8C]

If I look for these bytes in the physical file I found nothing. I assumed this is because the reference to 3F75F8C, which might change over each instance of the program, is being randomised by Windows. So I could not change the value directly in an hexed - say change 3F75F8C to 3F75F88 (I suppose I can do it with some math involving the base, though).

  • Can someone explain in detail how Windows proceeds when loading the PE file to randomise all these bytes? I have found posts and info on how ASLR works, but I am more thinking on the steps that the OS makes to put the file in memory with the randomised addresses - i.e. how it goes from the actual bytes in the executable "8B15 XXXX" to "8B15 8C5FF703" as in my example.
  • How the OS knows where the bytes that have to be randomised are (which exact addresses), and do it in a timely fashion?
  • Will this OS process breaks if I NOP the whole instruction? (I am asking because I do not know if there is some sort of predefined index table, I only know there is a flag in the PE to mark ASLR)

EDIT

As per the answer, what I undestood is that Windows will look into the .reloc section and will change one by one the references pointed in the section based on the random base. Then, if I modify the bytes of the instruction, since they have been defined in the .reloc section, my new bytes will be modified (probably I am wrong, but this is what I understood)

However, I am not able to find out how Windows "obtains" the instruction:

03CD38D4:  8B15 8C5FF703  MOV EDX, DWORD PTR DS:[3F75F8C]

Which is in file offset 482CD4 stored as:

MOV EDX, DWORD PTR DS:[B25F8C]

The image base is 400000 and base of code 1000.

I cannot find anything in the .reloc section that points to 03CD38D4,482CD4 or similar.

3

ASLR does not peer inside executable
it is a system wide exploit mitigation technique
basically and simply put it assigns a random base address on every load of every executable

that is if you run say calc.exe five times you may see calc.exe load at five different addresses

C:\>cdb -c "lm m calc;q" calc | grep "calc.*deferred
00dd0000 00e90000   calc       (deferred)

C:\>cdb -c "lm m calc;q" calc | grep "calc.*deferred
00250000 00310000   calc       (deferred)

C:\>cdb -c "lm m calc;q" calc | grep "calc.*deferred
00370000 00430000   calc       (deferred)

C:\>cdb -c "lm m calc;q" calc | grep "calc.*deferred
00860000 00920000   calc       (deferred)

C:\>cdb -c "lm m calc;q" calc | grep "calc.*deferred
00110000 001d0000   calc       (deferred)

the information to fix-up lies within your executable under .reloc section

the loader when it loads an executable takes the base address assigned to the load and performs fix-ups based on the details provided in the .reloc section of an executable

you can look at fix-ups using dumpbin and other innumerable pe editors

C:\>dumpbin /relocations c:\Windows\System32\calc.exe | wc -l
7346

C:\>dumpbin /relocations c:\Windows\System32\calc.exe | head -n 20
Microsoft (R) COFF/PE Dumper Version 14.15.26726.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\Windows\System32\calc.exe

File Type: EXECUTABLE IMAGE

BASE RELOCATIONS #4
    1000 RVA,       B4 SizeOfBlock
     641  HIGHLOW            01054064  ___security_cookie
     652  HIGHLOW            01001194  __imp__GetModuleHandleW@4
     6A5  HIGHLOW            010013F4  __imp__LoadStringW@16
     6B3  HIGHLOW            010540AC  ?calcSQM@@3PAVCCalculatorSQM@@A (class CCalculatorSQM * calcSQM)
     6BD  HIGHLOW            01054A70  _Microsoft_Windows_CalculatorHandle
     6C2  HIGHLOW            010551F8  _Microsoft_Windows_Calculator_Context
     6C7  HIGHLOW            010321A3  _McGenControlCallbackV2@36
     6CC  HIGHLOW            01001D5C  _Microsoft_Windows_Calculator
     6D7  HIGHLOW            0105521C
     707  HIGHLOW            01001EDE  ?WndProc@@YGJPAUHWND__@@IIJ@Z (long __stdcall WndProc(struct HWND__ *,unsigned in
t,unsigned int,long))

C:\>

RVA is relative virtual address related to base address

so if base address = 0x10000000 then absolute will be 0x10001000
so the address that needs fixup is 0x10001641 in the dump above

you can find what the preferred base of address is from the headers
most of the static analysis tools will load the pe in this address only

C:\>dumpbin /headers c:\Windows\System32\calc.exe | grep -i "image base"
         1000000 image base (01000000 to 010BFFFF)

you can dump the bytes at some specified position inside executable using any of the hexeditors (using the HIGHLOW of first entry in dump above 0x641) you can see the bytes are a1 0x10054064

using a40 instead of 1640 because the Base of code is 0x400 in physical file

which will be mapped to 0x1000 (Virtual Address) in the process address space

C:\>xxd -s 0xa40 -l 10 -g 5 c:\Windows\System32\calc.exe
0000a40: a164400501 33c58945fc                .d@..3..E.

you can see the disassembly with (using virtual address here as this is a mapped layout not physical file )

C:\>dumpbin /disasm /range:0x1001640,0x1001645 c:\Windows\System32\calc.exe

  01001640: A1 64 40 05 01     mov         eax,dword ptr [___security_cookie]
  01001645: 33

if you now load this in a ASLR enabled machine and look at the disassembly at the same virtual address you will see the 0x1000000 (preferred load address) has been fixed up

C:\>cdb -c "? calc;u calc+1640 l1;q" calc | grep -i -A 3 Reading
0:000> cdb: Reading initial command '? calc;u calc+1640 l1;q'
Evaluate expression: 5177344 = 004f0000
calc!WinMain+0xb:
004f1640 a164405400      mov     eax,dword ptr [calc!__security_cookie (00544064)]

C:\>python -c "print ( \"%x\" % (0x4f0000 + 0x54064) )"
544064
  • Thanks. I am trying to follow your explanation. So Windows uses the .reloc to find all "pointers" that have to be realocated, correct? I have been looking at .reloc with PEview and cannot find where the pointer to the instruction is. Knowing that the instruction is in file offset=482CD4, with original ref value=[B25F8C], being image base=400000` and base of code=1000, how Windows creates the final value [3F75F8C]? – user1156544 Jan 24 at 8:12
  • Iirc the value stored in the binary is a VA with the ImageBase from the header as the base. So generally the relocation function will do value-header.ImageBase+loaded.ImageBase... – mrexodia Jan 27 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.