Skip to content

Instantly share code, notes, and snippets.

@VVX7
Created December 3, 2021 02:21
Show Gist options
  • Save VVX7/6b0b0dc9b28c9a9006ff01b26b07b7f8 to your computer and use it in GitHub Desktop.
Save VVX7/6b0b0dc9b28c9a9006ff01b26b07b7f8 to your computer and use it in GitHub Desktop.
Example of reading exported functions from a DLL using Ward's winim/memlib library.
import winim, strformat
proc `[]`[T](x: T, U: typedesc): U =
cast[U](x)
proc `{}`[T](x: T, U: typedesc): U =
when sizeof(x) == 1: x[uint8][U]
elif sizeof(x) == 2: x[uint16][U]
elif sizeof(x) == 4: x[uint32][U]
elif sizeof(x) == 8: x[uint64][U]
else: {.fatal.}
template `{}`[T](p: T, x: SomeInteger): T =
cast[T]((cast[int](p) +% x{int}))
template `++`[T](p: var ptr T) =
p = cast[ptr T](p[int] +% sizeof(T))
let
dllBase = LoadLibraryA("ntdll")
dosHeader = cast[PIMAGE_DOS_HEADER](dllBase)
imageNTHeaders = cast[PIMAGE_NT_HEADERS](cast[DWORD_PTR](dllBase) + dosHeader.e_lfanew)
exportDirectoryRVA = cast[DWORD](imageNTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
imageExportDirectory = cast[PIMAGE_EXPORT_DIRECTORY](cast[DWORD_PTR](dllBase) + exportDirectoryRVA)
var
nameRef = cast[pointer](dllBase){imageExportDirectory.AddressOfNames}[ptr uint32]
ordinal = cast[pointer](dllBase){imageExportDirectory.AddressOfNameOrdinals}[ptr uint16]
for i in 0 ..< imageExportDirectory.NumberOfNames:
let
name = cast[pointer](dllBase){nameRef[]}[cstring]
index = int ordinal[]
echo name
echo index
++nameRef
++ordinal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment