# Finding VMAs

In the last section we were able to find functions in a module by name, this is only the first step in resolving the Virtual Memory Address (VMA) of a function. In order to call a function we need to know its VMA.

A VMA is a concept used in computer systems, particularly in the context of virtual memory management. It refers to a unique address or location in the virtual memory space of a process.

Virtual memory allows programs to operate on a larger address space than the physical memory (RAM) available in the system.

The Export Address Table (EAT) contains three lists:

<div align="left"><figure><img src="/files/QawqRvkPFxu4XJYhSm8c" alt=""><figcaption><p>Export Address Table lists</p></figcaption></figure></div>

When we looped over the `AddressOfNames` table we found a match for our function name that we wanted to resolve. We can now find that index in the `AddressOfNameOrdinals` which will point to the `AddressOfFunctions` table which contains pointers to the VMA of that function.

## WinDbg

We can continue from where we left off in the previous section (the addresses may have changed but the offsets are the same). We can see in the output below that third entry in the EAT is `ActivateActCtx` at offset `0x9e3e5` in the `AddressOfNames` table:

{% code lineNumbers="true" %}

```
0:006> dd kernel32+9a370+20 L1
00007ffc`ebf4a390  0009bd20

0:006> dd kernel32+0009bd20
00007ffc`ebf4bd20  0009e379 0009e3b2 0009e3e5 0009e3f4
00007ffc`ebf4bd30  0009e409 0009e412 0009e41b 0009e42c
00007ffc`ebf4bd40  0009e43d 0009e482 0009e4a8 0009e4c7
00007ffc`ebf4bd50  0009e4e6 0009e4f3 0009e506 0009e51e
00007ffc`ebf4bd60  0009e539 0009e54e 0009e56b 0009e5aa
00007ffc`ebf4bd70  0009e5eb 0009e5fe 0009e60b 0009e625
00007ffc`ebf4bd80  0009e643 0009e67a 0009e6bf 0009e70a
00007ffc`ebf4bd90  0009e765 0009e7ba 0009e80d 0009e862

0:006> da kernel32+9e3e5
00007ffc`ebf4e3e5  "ActivateActCtx"
```

{% endcode %}

Next we can take a look at the `AddressOfNameOrdinals` table. We can see that the third entry is the same index that the `ActivateActCtx` is located at, so this is easy to resolve:

{% code lineNumbers="true" %}

```
0:006> dd kernel32+9a370+24 L1
00007ffc`ebf4a394  0009d6a8

0:006> dw kernel32+9d6a8
00007ffc`ebf4d6a8  0000 0001 0002 0003 0004 0005 0006 0007
00007ffc`ebf4d6b8  0008 0009 000a 000b 000c 000d 000e 000f
00007ffc`ebf4d6c8  0010 0011 0012 0013 0014 0015 0016 0017
00007ffc`ebf4d6d8  0018 0019 001a 001b 001c 001d 001e 001f
00007ffc`ebf4d6e8  0020 0021 0022 0023 0024 0025 0026 0027
00007ffc`ebf4d6f8  0028 0029 002a 002b 002c 002d 002e 002f
00007ffc`ebf4d708  0030 0031 0032 0033 0034 0035 0036 0037
00007ffc`ebf4d718  0038 0039 003a 003b 003c 003d 003e 003f
```

{% endcode %}

Finally we can look at the `AddressOfFunctions` table at offset `0x1c`. We can then look at the third entry to get the offset address of `0x1be90`. If we uncompile this we find that we now have the VMA of `KERNEL32!ActivateActCtxWorker`:

{% code lineNumbers="true" %}

```
0:006> dd kernel32+9a370+1c L1
00007ffc`ebf4a38c  0009a398

0:006> dd kernel32+9a398+0c L1
00007ffc`ebf4a3a4  0001be90

0:006> u kernel32+0001be90
KERNEL32!ActivateActCtxWorker:
00007ffc`ebecbe90 4883ec28        sub     rsp,28h
00007ffc`ebecbe94 4883f9ff        cmp     rcx,0FFFFFFFFFFFFFFFFh
00007ffc`ebecbe98 0f846a940100    je      KERNEL32!ActivateActCtxWorker+0x19478 (00007ffc`ebee5308)
00007ffc`ebecbe9e 4c8bc2          mov     r8,rdx
00007ffc`ebecbea1 488bd1          mov     rdx,rcx
00007ffc`ebecbea4 33c9            xor     ecx,ecx
00007ffc`ebecbea6 48ff157b790600  call    qword ptr [KERNEL32!_imp_RtlActivateActivationContext (00007ffc`ebf33828)]
00007ffc`ebecbead 0f1f440000      nop     dword ptr [rax+rax]
```

{% endcode %}

Now that we have resolved a VMA manually we can write some shellcode to do this automatically and on demand.

## Shellcode

The shellcode to resolve the VMA of a function is shown below:

{% code title="Found function" lineNumbers="true" %}

```nasm
; RCX contains the ordinal of the function we want to resolve
; RBX = Base address of KERNEL32
; R8 = VMA of the Export Address Table
found_function:
    xor rsi, rsi                    ; RSI = 0
    mov esi, [r8 + 0x24]            ; ESI = Offset to AddressOfNameOrdinals
    add rsi, rbx                    ; RSI = VMA of AddressOfNameOrdinals
    
    mov cx, [rsi + rcx * 2]         ; The number of the function
    
    xor rsi, rsi                    ; RSI = 0
    mov esi, [r8 + 0x1c]            ; Offset to AddressOfFunctions
    add rsi, rbx                    ; RSI = VMA of AddressOfFunctions
    
    xor rdx, rdx                    ; RDX = 0
    mov edx, [rsi + rcx * 4]        ; EDX = Index of the function VMA needed
    add rdx, rbx                    ; RDX = Function Address
    mov rdi, rdx                    ; Save Function Address in RDI
    ret                             ;
```

{% endcode %}

The shellcode corresponds to what we carried out manually using Windbg, it:

* Locates the `AddressOfNamesOrdinals` on lines `5` through `7`.
* Uses the table to find the number of the function on line `9`. Notice that the table entries are 2 bytes in size.
* Lines `11` through `13` are used to locate the `AddressOfFunctions` table.
* Uses the table to locate the offset of the function on line `16`.
* Adds this offset to the base address of `kernel32.dll` on line `17`.
* Finally the address is stored in `rdi` and the function returns.

In the next section we will put everything we have learned together to create shellcode that displays a message box.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://open-advanced-windows-exploitati.gitbook.io/open-advanced-windows-exploitation/custom-shellcode/writing-shellcode/finding-vmas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
