Skip to main content

ffi.detour

C-level inline hook (detour) creation using MinHook and TCC-compiled C code. A detour redirects execution at a target address to a user-supplied C function, writing the original-function trampoline back into the C program so callers can invoke the original. The returned detour object manages the hook lifecycle.

Functions

ffi.detour.create(target, code)

Compiles code with TCC and installs an inline hook at target using MinHook.

The C source must define exactly two symbols:

  • detour — the replacement function that MinHook will redirect execution to.
  • original — a pointer variable (e.g. void *original; or a typed function pointer) into which the MinHook trampoline address is written automatically after hook creation. Call through original to invoke the real function.

The hook is enabled immediately after creation. On failure, nil is returned along with an error string describing what went wrong.

Parameters

NameTypeDescription
targetnumber

Address of the function to hook, as a Lua number.

codestring

C source code to compile with TCC. Must define a detour function symbol and an original pointer symbol.

Returns

TypeDescription
userdata?

A detour object on success. nil on failure.

string?

Error message when the first return value is nil.

Errors

  • MinHook failed to initialize
  • code is nil or empty
  • target address is already hooked by another detour
  • TCC compilation failed (error string returned as second value)
  • compiled program is missing the required 'detour' or 'original' symbol
  • MinHook failed to create the hook
  • MinHook failed to enable the hook after creation

Classes

Detour

The object returned by lje.detour.create. It owns the MinHook hook and the compiled TCC program for the lifetime of the detour, and exposes methods to inspect the compiled program and to control the hook. The detour is garbage-collected: when the object is collected it is automatically removed, but you can also tear it down deterministically with remove.

detour:get(name)

Looks up a symbol by name from the TCC program compiled during create. This can be used to read or write data symbols inside the detour program (for example, a call counter or configuration variable). Returns the symbol's address as a number, or nil if the symbol does not exist or the detour has been removed.

Parameters
NameTypeDescription
namestring

Name of the symbol to look up in the compiled TCC program.

Returns
TypeDescription
number?

Address of the symbol as a Lua number, or nil if not found or the detour is destroyed.

detour:enable()

Re-enables a previously disabled detour hook via MinHook. Returns false without doing anything if the hook is already marked enabled or if the detour has been removed.

Returns
TypeDescription
boolean

true if MinHook successfully enabled the hook, false if already enabled, if the detour is destroyed, or if MinHook reported an error.

detour:disable()

Disables a detour hook via MinHook, restoring execution to the original function at the target address. The detour object remains valid and the hook can be re-enabled with enable. Returns false without doing anything if the hook is already marked disabled or if the detour has been removed.

Returns
TypeDescription
boolean

true if MinHook successfully disabled the hook, false if already disabled, if the detour is destroyed, or if MinHook reported an error.

detour:remove()

Permanently removes the detour: disables the hook, unregisters it from MinHook, releases the target address claim, and frees the TCC program. After calling remove, all further method calls on the same object return false or nil. The garbage collector also performs this cleanup automatically when the object is collected, so calling remove is optional but allows deterministic teardown.

Returns
TypeDescription
boolean

true if the detour was successfully removed, false if it had already been removed.