What is an Access Violation?

An access violation (AV) occurs when the program performs and action on a memory address that does not align with the page protection for that memory.

3 common types:

  • Read
  • Write
  • Execute from non-executable

In order to determine the cause for the AV, you first need to know which type you are dealing with. With both the read and write scenario, you evaluate the address that is referenced and try to figure out why the address got to be in such a state that would cause an AV.

Address Zero

The most common AV pattern will be a read or write to address 0 (zero). A common programming issue involves several scenarios where the programmer expects a value to be a valid address, but for whatever reason it did not get set properly (e.g. a function failed and returned 0 instead of the expected value). In order to address this common mistake, the OS sets the first page of memory in each process up as a trap (think big metal thing to catch an animal) to catch this issue. The trap is created by marking the first page of memory in each process, address 0, to be NO_ACCESS.

Reference: Reserved Virtual Address Ranges

0:001> !address 0

Usage:                  Free
Base Address:           00000000
End Address:            00010000
Region Size:            00010000
State:                  00010000 MEM_FREE
Protect:                00000001 PAGE_NOACCESS <--- We can see the page protection on this address is NO ACCESS

Type:                   <info not present at the target>

Execute from non-executable (DEP - Data Execution Prevention)

Another AV can occur if the instruction pointer is ever set to memory that does not include the option to enable execution.

Reference: Data Execution Prevention (Wikipedia)

If we look at the exception record, we see it was a DEP access violation

0:034> .exr -1
ExceptionAddress: 00610524
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000008
   Parameter[1]: 00610524
Attempt to execute non-executable address 00610524

In this case, we don't look at the failing instruction, we focus on the fact that EIP was set to a value that did not have the execute flag.

0:034> r
eax=00000000 ebx=00610000 ecx=0182ffb4 edx=7c82ed54 esi=00000000 edi=00000000
eip=00610524 esp=0182ffbc ebp=0182ffec iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
00610524 55              push    ebp

0:034> kvL
ChildEBP RetAddr  Args to Child             
WARNING: Frame IP not in any known module. Following frames may be wrong.
0182ffb8 77e6608b 00610000 00000000 00000000 0x610524
0182ffec 00000000 00610524 00610000 00000000 kernel32!BaseThreadStart+0x34

0:034> !address 00610524

Usage:                  <unknown>
Base Address:           00610000
End Address:            00611000
Region Size:            00001000
State:                  00001000 MEM_COMMIT
Protect:                00000004 PAGE_READWRITE <-- does not include execute
Type:                   00020000 MEM_PRIVATE
Allocation Base:        00610000
Allocation Protect:     00000004 PAGE_READWRITE

Compare this page protect to that of a Windows function

0:034> !x kernel32!ReportEventW
77ec0285 kernel32!ReportEventW

0:034> !address 77ec0285

Usage:                  Image
Base Address:           77e41000
End Address:            77ecb000
Region Size:            0008a000
State:                  00001000 MEM_COMMIT
Protect:                00000020 PAGE_EXECUTE_READ <-- does include execute
Type:                   01000000 MEM_IMAGE
Allocation Base:        77e40000
Allocation Protect:     00000080 PAGE_EXECUTE_WRITECOPY
Image Path:             C:\WINDOWS\system32\kernel32.dll
Module Name:            kernel32
Loaded Image Name:      kernel32.dll