Newbie HvHer
- User ID
- 144975
- Messages
- 1
- Reactions
- 0
- Level
- 0
This is freeed code from silv loader for resolving your exports when you forward it (for your cheat loader, it s required to have) It s from commit history free I will release more code of this later It s in rust not cpp or something but u can
translate this to another language yes (chatgpt can translate it)
Probably the good public export forwarding
translate this to another language yes (chatgpt can translate it)
Probably the good public export forwarding
+ fn resolve_forwarded_export(module: &Module, proc_name: &str) -> anyhow::Result<String> {
let module_info = module.info()?;
let module_base = module_info.lpBaseOfDll as usize;
let module_size = module_info.SizeOfImage as usize;
if module_base == 0 || module_size == 0 {
return Err(anyhow!("bad module base address"));
}
if proc_name.is_empty() {
return Err(anyhow!("no procedure name"));
}
let dos_header: IMAGE_DOS_HEADER = unsafe {
std:tr::read(module_base as *const IMAGE_DOS_HEADER)
};
if dos_header.e_magic != 0x5A4D {
return Err(anyhow!("bad dos header sig"));
}
let nt_headers_offset = dos_header.e_lfanew as usize;
if nt_headers_offset >= module_size || nt_headers_offset < 0x40 {
return Err(anyhow!("bad nt header offset"));
}
let nt_headers_addr = module_base + nt_headers_offset;
+ let pe_signature = unsafe { *(nt_headers_addr as *const DWORD) };
if pe_signature != 0x00004550 {
return Err(anyhow!("bad pe sig"));
}
let is_32bit = unsafe {
let machine = *((nt_headers_addr + 4) as *const WORD);
machine == 0x014c
};
let (export_dir_rva, export_dir_size) = if is_32bit {
let nt_headers = unsafe {
&*(nt_headers_addr as *const IMAGE_NT_HEADERS32)
};
(
nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT as usize].VirtualAddress as usize,
nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT as usize].Size as usize
)
} else {
let nt_headers = unsafe {
&*(nt_headers_addr as *const IMAGE_NT_HEADERS64)
};
(
nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT as usize].VirtualAddress as usize,
nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT as usize].Size as usize
)
};
if export_dir_rva == 0 || export_dir_size == 0 {
return Err(anyhow!("module has no export dir")); // GET MODULE NAME!!
}
if export_dir_rva >= module_size || export_dir_rva + export_dir_size > module_size {
return Err(anyhow!("expoirt dir out of bounds"));
}
let export_dir_addr = module_base + export_dir_rva;
let export_dir = unsafe {
&*(export_dir_addr as *const IMAGE_EXPORT_DIRECTORY)
};
if export_dir.NumberOfFunctions == 0 || export_dir.NumberOfNames == 0 {
return Err(anyhow!("module has empty export dir"));
}
let name_table_rva = export_dir.AddressOfNames as usize;
let ordinal_table_rva = export_dir.AddressOfNameOrdinals as usize;
let func_table_rva = export_dir.AddressOfFunctions as usize;
if name_table_rva == 0 || ordinal_table_rva == 0 || func_table_rva == 0 ||
name_table_rva >= module_size || ordinal_table_rva >= module_size || func_table_rva >= module_size {
return Err(anyhow!("bad export dir rva"));
}
let name_table_addr = module_base + name_table_rva;
let ordinal_table_addr = module_base + ordinal_table_rva;
let func_table_addr = module_base + func_table_rva;
let num_named_exports = export_dir.NumberOfNames as usize;
let mut export_rva = 0;
let mut found = false;
for i in 0..num_named_exports {
let name_rva = unsafe {
*((name_table_addr + i * std::mem::size_of::<DWORD>()) as *const DWORD)
} as usize;
if name_rva == 0 || name_rva >= module_size {
continue;
}
let export_name = unsafe {
let name_addr = module_base + name_rva;
match std::ffi::CStr::from_ptr(name_addr as *const i8).to_str() {
Ok(s) => s,
Err(_) => continue,
}
};
if export_name == proc_name {
let ordinal = unsafe {
*((ordinal_table_addr + i * std::mem::size_of::<WORD>()) as *const WORD)
} as usize;
if ordinal >= export_dir.NumberOfFunctions as usize {
return Err(anyhow!("ordinal oor {}", proc_name));
}
export_rva = unsafe {
*((func_table_addr + ordinal * std::mem::size_of::<DWORD>()) as *const DWORD)
} as usize;
found = true;
break;
}
}
if !found || export_rva == 0 {
return Err(anyhow!("export not found: {}", proc_name));
}
if export_rva >= export_dir_rva && export_rva < (export_dir_rva + export_dir_size) {
let forward_addr = module_base + export_rva;
let forward_string = unsafe {
match std::ffi::CStr::from_ptr(forward_addr as *const i8).to_str() {
Ok(s) => s,
Err(_) => return Err(anyhow!("bad fwd string for: {}", proc_name)),
}
};
if !forward_string.is_empty() {
if !forward_string.contains('.') {
return Err(anyhow!("bad fwd export format: {}", forward_string));
}
return Ok(forward_string.to_string());
}
}
Err(anyhow!("no fwd export: {}", proc_name))
}