Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ CMakeLists.txt.user
*.obj
*.iobj
*.idb
*.aps
*.aps__pycache__/
4 changes: 2 additions & 2 deletions CMakeLists.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions include/plib/pe/export_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static inline const void *to_address(T p)
}
else
{
static_assert(std::is_integral_v<T>, "Use ponteiro de funcao ou inteiro pointer-sized.");
static_assert(std::is_integral_v<T>, "Use function pointer or pointer-sized integer.");
return reinterpret_cast<const void *>(static_cast<std::uintptr_t>(p));
}
}
Expand Down Expand Up @@ -59,11 +59,11 @@ namespace plib::pe::export_utils
auto va = reinterpret_cast<std::uintptr_t>(addr);
std::uintptr_t rva = va - base;

// Sanidade: confirme que o RVA cai dentro do image
// Sanity check: confirm that the RVA falls within the image
const std::uintptr_t sizeOfImage = nt->OptionalHeader.SizeOfImage;
if (rva >= sizeOfImage)
{
// Pode ser um trampolim fora das seções do image (ex.: hook/jit).
// May be a trampoline outside the image sections (e.g.: hook/jit).
return std::nullopt;
}

Expand All @@ -90,11 +90,11 @@ namespace plib::pe::export_utils
auto va = reinterpret_cast<std::uintptr_t>(addr);
std::uintptr_t rva = va - base;

// Sanidade: confirme que o RVA cai dentro do image
// Sanity check: confirm that the RVA falls within the image
const std::uintptr_t sizeOfImage = nt->OptionalHeader.SizeOfImage;
if (rva >= sizeOfImage)
{
// Pode ser um trampolim fora das seções do image (ex.: hook/jit).
// May be a trampoline outside the image sections (e.g.: hook/jit).
return std::nullopt;
}

Expand Down
12 changes: 6 additions & 6 deletions include/plib/rl/rl_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ extern "C" {
#endif

typedef struct RL_TLS_STATE {
BOOL has_tls; // existe diretório TLS?
DWORD tls_index; // índice alocado via TlsAlloc (process-scope)
BOOL has_tls; // does TLS directory exist?
DWORD tls_index; // index allocated via TlsAlloc (process-scope)
SIZE_T template_size; // (End - Start) + SizeOfZeroFill
SIZE_T align; // alinhamento desejado (opcional: >= 8/16)
PVOID raw_start_va; // VA (relocado) StartAddressOfRawData
SIZE_T align; // desired alignment (optional: >= 8/16)
PVOID raw_start_va; // VA (relocated) StartAddressOfRawData
PVOID raw_end_va; // VA EndAddressOfRawData
SIZE_T zero_fill; // SizeOfZeroFill
PVOID* p_index_va; // VA onde escrever o índice (AddressOfIndex)
PVOID* callbacks_va; // VA do array NULL-terminated de callbacks
PVOID* p_index_va; // VA where to write the index (AddressOfIndex)
PVOID* callbacks_va; // VA of NULL-terminated array of callbacks
} RL_TLS_STATE;

typedef struct RL_IMG_INFO {
Expand Down
8 changes: 4 additions & 4 deletions include/plib/rl/rl_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ extern "C" {
#endif


// 0) Descoberta: parse do TLS directory e preenchimento do RL_TLS_STATE
// 0) Discovery: parse TLS directory and fill RL_TLS_STATE
NTSTATUS RlTlsDiscover(RL_IMAGE* img);

// 1) Processo: ligar o módulo ao TLS global do Windows
// 1) Process: link module to Windows global TLS
NTSTATUS RlTlsProcessAttach(RL_IMAGE* img);

// 2) Thread: preparar/desmontar bloco TLS deste módulo para threads que usarão a DLL
// 2) Thread: prepare/dismantle TLS block of this module for threads that will use the DLL
NTSTATUS RlTlsThreadAttach(RL_IMAGE* img);
NTSTATUS RlTlsThreadDetach(RL_IMAGE* img);

// 3) Processo: detach final (callbacks + liberar índice)
// 3) Process: final detach (callbacks + free index)
NTSTATUS RlTlsProcessDetach(RL_IMAGE* img);

NTSTATUS RlTlsInvokeCallbacks(const RL_IMAGE* img,
Expand Down
10 changes: 5 additions & 5 deletions lib/src/rl/rl_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ NTSTATUS RlInitImageFromKnownDll(LPCSTR dllName, RL_IMAGE* img_out) {

auto& src_image = img_out->src_image;

src_image.base.image = mod; // será liberado por FreeLibrary
src_image.base.image = mod; // will be freed by FreeLibrary
src_image.is_image = true;
src_image.info.size = nt->OptionalHeader.SizeOfImage;
src_image.info.reserved_size = nt->OptionalHeader.SizeOfImage;
Expand All @@ -168,7 +168,7 @@ NTSTATUS RlInitImageFromKnownDll(LPCSTR dllName, RL_IMAGE* img_out) {
NTSTATUS RlMapImageAt(RL_IMAGE* img, void* target_base, size_t target_size) {
RL_RETURN_IF_NOT(img && img->src_image.nt && target_base, STATUS_INVALID_PARAMETER);

// Base da origem (única)
// Source base (unique)
const BYTE* const src_bytes = img->src_image.base.raw;
if (!src_bytes) return STATUS_INVALID_PARAMETER;

Expand All @@ -192,7 +192,7 @@ NTSTATUS RlMapImageAt(RL_IMAGE* img, void* target_base, size_t target_size) {
const DWORD raw = sec->SizeOfRawData;
const DWORD virt = sec->Misc.VirtualSize ? sec->Misc.VirtualSize : raw;

// bound por imagem (não por blob; o blob já foi validado)
// bound by image (not by blob; the blob was already validated)
RL_ASSERT((SIZE_T)va + (SIZE_T)virt <= size_image);

BYTE* dst = dst_base + va;
Expand All @@ -201,14 +201,14 @@ NTSTATUS RlMapImageAt(RL_IMAGE* img, void* target_base, size_t target_size) {

if (src_img.is_image)
{
// origem em layout de imagem (VA)
// source in image layout (VA)
src = src_bytes + va; // <<< usa a base correta
SIZE_T raw_aligned = AlignUp((SIZE_T)raw, (SIZE_T)file_align);
ncopy_bytes = raw ? std::min<SIZE_T>(virt, raw_aligned) : 0;
}
else
{
// origem em layout de arquivo (RAW)
// source in file layout (RAW)
src = (raw && sec->PointerToRawData)
? (src_bytes + sec->PointerToRawData)
: nullptr;
Expand Down
30 changes: 15 additions & 15 deletions lib/src/rl/rl_tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ NTSTATUS RlTlsDiscover(RL_IMAGE *img)

RL_TLS_STATE* const out = &img->tls;

// 1) Localizar diretório TLS
// 1) Locate TLS directory
auto &dd = img->nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
if (!dd.VirtualAddress || !dd.Size)
{
out->has_tls = FALSE;
return STATUS_SUCCESS; // nada a fazer
return STATUS_SUCCESS; // nothing to do
}
out->has_tls = TRUE;

// 2) Ler IMAGE_TLS_DIRECTORY (endereços já estão relocados, pois você já aplicou relocs)
// 2) Read IMAGE_TLS_DIRECTORY (addresses are already relocated, since you already applied relocs)
#ifdef _WIN64
auto tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY64>(img->base + dd.VirtualAddress);
#else
Expand All @@ -32,14 +32,14 @@ NTSTATUS RlTlsDiscover(RL_IMAGE *img)
out->p_index_va = reinterpret_cast<PVOID *>(tls->AddressOfIndex);
out->callbacks_va = reinterpret_cast<PVOID *>(tls->AddressOfCallBacks);

// 3) Tamanho do template (+ zero fill) e alinhamento (use algo seguro, p.ex. 16 em x64)s
// 3) Template size (+ zero fill) and alignment (use something safe, e.g. 16 on x64)s
SIZE_T tpl = 0;
if (out->raw_end_va >= out->raw_start_va)
{
tpl = (SIZE_T)((BYTE *)out->raw_end_va - (BYTE *)out->raw_start_va);
}
out->template_size = tpl + out->zero_fill;
out->align = sizeof(void *) >= 8 ? 16 : 8; // ajuste se quiser ler de Characteristics/section
out->align = sizeof(void *) >= 8 ? 16 : 8; // adjust if you want to read from Characteristics/section

return STATUS_SUCCESS;
}
Expand All @@ -52,13 +52,13 @@ NTSTATUS RlTlsProcessAttach(RL_IMAGE *img)

RL_TLS_STATE* const st = &img->tls;

// 1) Alocar índice TLS do Windows
// 1) Allocate Windows TLS index
DWORD idx = TlsAlloc();
if (idx == TLS_OUT_OF_INDEXES)
return STATUS_INSUFFICIENT_RESOURCES;
st->tls_index = idx;

// 2) Escrever índice em AddressOfIndex (é um DWORD mesmo em x64)
// 2) Write index to AddressOfIndex (it's a DWORD even on x64)
DWORD oldProt = 0;
if (st->p_index_va)
{
Expand All @@ -67,11 +67,11 @@ NTSTATUS RlTlsProcessAttach(RL_IMAGE *img)
VirtualProtect(st->p_index_va, sizeof(DWORD), oldProt, &oldProt);
}

// 3) Criar bloco TLS para o THREAD ATUAL e setar no slot
// 3) Create TLS block for CURRENT THREAD and set in slot
if (st->template_size)
{
SIZE_T size = st->template_size;
// Alocar com alinhamento desejado (pode ser HeapAlloc simples; alinhe manualmente se precisar)
// Allocate with desired alignment (can be simple HeapAlloc; align manually if needed)
BYTE *block = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + st->align);
if (!block)
return STATUS_INSUFFICIENT_RESOURCES;
Expand All @@ -81,7 +81,7 @@ NTSTATUS RlTlsProcessAttach(RL_IMAGE *img)
if (tpl && st->raw_start_va)
{
memcpy(block, st->raw_start_va, tpl);
// resto já está zerado pelo HEAP_ZERO_MEMORY
// rest is already zeroed by HEAP_ZERO_MEMORY
}
if (!TlsSetValue(idx, block))
{
Expand Down Expand Up @@ -110,7 +110,7 @@ NTSTATUS RlTlsThreadAttach(RL_IMAGE* img)

const RL_TLS_STATE* const st = &img->tls;

// 1) Alocar + copiar template para ESTE thread
// 1) Allocate + copy template for THIS thread
BYTE *block = nullptr;
if (st->template_size)
{
Expand Down Expand Up @@ -157,8 +157,8 @@ NTSTATUS RlTlsThreadDetach(RL_IMAGE *img)
}
}

// 2) Liberar bloco TLS do thread (se houver) e limpar o slot
void *block = TlsGetValue(st->tls_index); // ok mesmo se falhar; ERROR_INVALID_INDEX não se aplica
// 2) Free TLS block from thread and clean slot
void *block = TlsGetValue(st->tls_index); // ok even if it fails; ERROR_INVALID_INDEX doesn't apply
if (block)
HeapFree(GetProcessHeap(), 0, block);
TlsSetValue(st->tls_index, nullptr);
Expand All @@ -182,10 +182,10 @@ NTSTATUS RlTlsProcessDetach(RL_IMAGE *img)
}
}

// 2) Liberar índice TLS
// 2) Free TLS index
if (st->tls_index != TLS_OUT_OF_INDEXES)
{
// (Qualquer bloco remanescente por thread deveria ter sido limpo em ThreadDetach)
// (Any remaining block per thread should have been cleaned in ThreadDetach)
TlsFree(st->tls_index);
st->tls_index = TLS_OUT_OF_INDEXES;
}
Expand Down
26 changes: 13 additions & 13 deletions tools/gen_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def write_line(self, s: str = ""):
self._buf.write(s)
self._buf.write(self._newline)

# alias com o nome que você pediu
# alias with the name you requested
def write_line_ident(self, s: str = ""):
return self.write_line_indent(s)

Expand Down Expand Up @@ -257,15 +257,15 @@ def emit_asm_thunks_x86(path: Path, dialect: AsmDialect,
# ---------------------------

def main(argv: list[str]) -> int:
ap = argparse.ArgumentParser(description="Gera .def e stubs referenciando um símbolo de blob (sem stage-1).")
ap = argparse.ArgumentParser(description="Generate .def and stubs referencing a blob symbol (without stage-1).")
ap.add_argument("--debug", action="store_true", help="Wait for debugger")
ap.add_argument("source_dll", help="DLL de origem (ex: version.dll ou caminho absoluto).")
ap.add_argument("out_def", help="Caminho do .def a ser gerado.")
ap.add_argument("--out-asm", required=True, help="Caminho do .asm (stubs) a ser gerado.")
ap.add_argument("--out-json", default=None, help="(Opcional) Dump JSON do mapa de RVAs.")
ap.add_argument("--libname", default=None, help="Nome de biblioteca no .def (padrão: nome base do source_dll).")
ap.add_argument("--blob-symbol", default="g_reflect_blob", help="Símbolo do blob na DLL proxy (default: g_reflect_blob).")
ap.add_argument("--asm-dialect", default="masm", choices=["masm", "nasm"], help="Dialeto ASM a ser usado (padrão: masm).")
ap.add_argument("source_dll", help="Source DLL (e.g.: version.dll or absolute path).")
ap.add_argument("out_def", help="Path of .def file to be generated.")
ap.add_argument("--out-asm", required=True, help="Path of .asm (stubs) file to be generated.")
ap.add_argument("--out-json", default=None, help="(Optional) JSON dump of RVA mapping.")
ap.add_argument("--libname", default=None, help="Library name in .def (default: base name of source_dll).")
ap.add_argument("--blob-symbol", default="g_reflect_blob", help="Blob symbol in proxy DLL (default: g_reflect_blob).")
ap.add_argument("--asm-dialect", default="masm", choices=["masm", "nasm"], help="ASM dialect to be used (default: masm).")
args = ap.parse_args(argv)

if args.debug:
Expand All @@ -287,7 +287,7 @@ def main(argv: list[str]) -> int:
if not source_dll.is_absolute() and source_dll.exists() is False:
source_dll = get_known_dll(args.source_dll)
if not source_dll or not source_dll.exists():
raise FileNotFoundError(f"Não foi possível encontrar a DLL de origem: {args.source_dll}")
raise FileNotFoundError(f"Could not find the source DLL: {args.source_dll}")
src_pe = pefile.PE(source_dll)
machine = get_machine(src_pe)
exports = read_exports(src_pe)
Expand Down Expand Up @@ -315,13 +315,13 @@ def main(argv: list[str]) -> int:
base = f"thunk_{e.ordinal}"
internal_sym_for[key] = sanitize_internal(base)

# Nome da LIB no .def
# LIB name in .def
if args.libname:
libname = args.libname
else:
libname = Path(args.source_dll).stem

# Emitir arquivos
# Emit files
out_def = Path(args.out_def)
out_asm = Path(args.out_asm)

Expand All @@ -332,7 +332,7 @@ def main(argv: list[str]) -> int:
elif machine == "x86":
emit_asm_thunks_x86(out_asm, args.asm_dialect, args.blob_symbol, new_rvas, internal_sym_for)
else:
raise SystemExit(f"Arquitetura {machine} ainda não suportada.")
raise SystemExit(f"Architecture {machine} not yet supported.")

if args.out_json:
j = {
Expand Down
Loading