Skip to content

Instantly share code, notes, and snippets.

@playday3008
Last active May 13, 2024 19:37
Show Gist options
  • Select an option

  • Save playday3008/db98a668244ceff733f90f60208ec0bd to your computer and use it in GitHub Desktop.

Select an option

Save playday3008/db98a668244ceff733f90f60208ec0bd to your computer and use it in GitHub Desktop.
Enumerate exports for specified dll using CheatEngine
---@diagnostic disable: undefined-global
resetLuaState()
-- Get the address of a module in the process memory
local base_addr = getAddressSafe("[DLL-NAME-HERE].dll")
if base_addr == nil or process == nil then
print("Module not found")
return
end
-- Read the DOS header, get the NT header address
local nt_offset = readInteger(base_addr + 0x3C) -- e_lfanew
local nt_addr = base_addr + nt_offset
-- Read the NT header, get the optional header address
local optional_header_addr = nt_addr + 0x18 -- OptionalHeader
-- Read the optional header, get the export data directory address
local export_data_directory_addr = optional_header_addr + 0x70 -- DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
local export_directory_addr = base_addr + readInteger(export_data_directory_addr)
-- Read the export data directory, get the number of functions, names, addresses, and name ordinals
local name_rva = readInteger(export_directory_addr + 0x0C) -- Name
local base_ordinal_rva = readInteger(export_directory_addr + 0x10) -- Base
local number_of_functions = readInteger(export_directory_addr + 0x14) -- NumberOfFunctions
local number_of_names = readInteger(export_directory_addr + 0x18) -- NumberOfNames
local rva_of_functions = readInteger(export_directory_addr + 0x1C) -- AddressOfFunctions
local rva_of_names = readInteger(export_directory_addr + 0x20) -- AddressOfNames
local rva_of_name_ordinals = readInteger(export_directory_addr + 0x24) -- AddressOfNameOrdinals
local functions_array = {}
for i = 0, number_of_functions - 1 do
functions_array[i] = base_addr + readInteger(base_addr + rva_of_functions + i * 4)
end
local function_names_array = {}
local function_name_ordinals_array = {}
for i = 0, number_of_names - 1 do
local ordinal = readSmallInteger(base_addr + rva_of_name_ordinals + i * 2)
function_name_ordinals_array[ordinal] = ordinal
function_names_array[ordinal] = readString(base_addr + readInteger(base_addr + rva_of_names + i * 4))
end
-- For each function, read the name and address
print(string.format("Module: %s (0x%X)", readString(base_addr + name_rva), base_addr))
print("\tOrdinal\tAddress\t\tName")
for i = 0, number_of_functions - 1 do
local function_address = functions_array[i]
local function_name = function_names_array[i]
local function_ordinal = function_name_ordinals_array[i]
if function_name == nil then
function_name = "[no name]"
end
if function_ordinal == nil then
function_ordinal = -1
end
print(string.format("\t%d\t0x%0X:\t%s", function_ordinal + base_ordinal_rva, function_address, function_name))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment