mirror of
https://github.com/Kudaes/ADPT
synced 2026-06-06 16:04:33 +00:00
Functions exported only by ordinal are now correctly handled
This includes, for example, ntdll's ordinal 8, which is not exported by name.
This commit is contained in:
+38
-8
@@ -116,8 +116,14 @@ fn print_usage(program: &str, opts: Options) {
|
||||
print!("{}", opts.usage(&brief));
|
||||
}
|
||||
|
||||
fn demangle_name(mangled_name: &String) -> String
|
||||
fn demangle_name(mangled_name: &String, ordinal: u32) -> String
|
||||
{
|
||||
|
||||
if mangled_name.is_empty() {
|
||||
let placeholder = format!("{}{}", "OrdinalPlaceholder", ordinal);
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
let demangled: String = mangled_name
|
||||
.replace("?", "1")
|
||||
.replace("!", "2")
|
||||
@@ -149,15 +155,21 @@ fn generate_tracer_dll(original_dll_path: String, log_path: String, link_runtime
|
||||
|
||||
for (i,name) in names_info.iter().enumerate()
|
||||
{
|
||||
let demangled_name = demangle_name(&name.0);
|
||||
let demangled_name = demangle_name(&name.0, name.1);
|
||||
let template1 = TEMPLATE1.replace("{FUNC_NAME}", &demangled_name).replace("{INDEX}", &i.to_string());
|
||||
first_string.push_str(&template1);
|
||||
let template2 = TEMPLATE2.replace("{NUM}", &i.to_string()).replace("{NAME}", &demangled_name);
|
||||
second_string.push_str("\n\t\t");
|
||||
second_string.push_str(&template2);
|
||||
|
||||
let export_string = format!("{}={} @{}\n",&name.0, demangled_name, name.1);
|
||||
def_file_string.push_str(&export_string);
|
||||
if name.0.is_empty() {
|
||||
let export_string = format!("{}={} @{}\n",demangled_name, demangled_name, name.1);
|
||||
def_file_string.push_str(&export_string);
|
||||
} else {
|
||||
let export_string = format!("{}={} @{}\n",&name.0, demangled_name, name.1);
|
||||
def_file_string.push_str(&export_string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let ending = "\n\t\t_ => {String::new()}\n\t}\n} ";
|
||||
@@ -225,14 +237,14 @@ fn generate_proxy_dll(original_dll_path: String, hijacked_exports: Vec<&str>, na
|
||||
let mut index = 0u32;
|
||||
for (_, name) in names_info.iter().enumerate()
|
||||
{
|
||||
let demangled_name = demangle_name(&name.0);
|
||||
if !mangled_names_detected && (demangled_name != name.0)
|
||||
let demangled_name = demangle_name(&name.0, name.1);
|
||||
if !mangled_names_detected && (demangled_name != name.0) && !demangled_name.contains("OrdinalPlaceholder")
|
||||
{
|
||||
mangled_names_detected = true;
|
||||
println!("[!] Exported functions with mangled names detected in the source DLL. Proxying will be disabled for those symbols.");
|
||||
}
|
||||
|
||||
if hijacked_exports.contains(&name.0.as_str())
|
||||
if !&name.0.is_empty() && hijacked_exports.contains(&name.0.as_str())
|
||||
{
|
||||
println!("[+] Exported function {} found.", &name.0);
|
||||
let template4 = TEMPLATE4.replace("{FUNC_NAME}", &demangled_name).replace("{INDEX}", &index.to_string());
|
||||
@@ -262,7 +274,11 @@ fn generate_proxy_dll(original_dll_path: String, hijacked_exports: Vec<&str>, na
|
||||
|
||||
let export_string;
|
||||
if demangled_name != name.0 {
|
||||
export_string = format!("{}={} @{}\n",&name.0, demangled_name, name.1);
|
||||
if demangled_name.contains("OrdinalPlaceholder") {
|
||||
export_string = format!("{}={}.#{} @{}\n", demangled_name, module_name, name.1, name.1);
|
||||
} else {
|
||||
export_string = format!("{}={} @{}\n",&name.0, demangled_name, name.1);
|
||||
}
|
||||
} else {
|
||||
export_string = format!("{}={}.{} @{}\n", &name.0, module_name, &name.0, name.1);
|
||||
}
|
||||
@@ -333,6 +349,7 @@ pub fn get_function_info(module_base_address: usize) -> Vec<(String,u32)> {
|
||||
|
||||
let export_rva = *(p_export as *mut i32);
|
||||
let ordinal_base = *((module_base_address + export_rva as usize + 0x10) as *mut u32);
|
||||
let number_of_exports = *((module_base_address + export_rva as usize + 0x14) as *mut u32);
|
||||
let number_of_names = *((module_base_address + export_rva as usize + 0x18) as *mut u32);
|
||||
let names_rva = *((module_base_address + export_rva as usize + 0x20) as *mut u32);
|
||||
let ordinals_rva = *((module_base_address + export_rva as usize + 0x24) as *mut u32);
|
||||
@@ -355,6 +372,19 @@ pub fn get_function_info(module_base_address: usize) -> Vec<(String,u32)> {
|
||||
|
||||
}
|
||||
|
||||
let ordinals_list: Vec<u32> = functions_info.iter().map(|(_, num)| *num).collect();
|
||||
|
||||
if number_of_exports > number_of_names
|
||||
{
|
||||
for i in 0..number_of_exports
|
||||
{
|
||||
let current_ordinal = ordinal_base + i as u32;
|
||||
if !ordinals_list.contains(¤t_ordinal) {
|
||||
functions_info.push((String::new(),current_ordinal)); // This takes care of those functions exported exclusively by ordinal, like ntdll's ordinal 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
functions_info
|
||||
|
||||
}
|
||||
|
||||
+30
-10
@@ -7,10 +7,7 @@ const LOG_NAME: &str = r"{LOG_PATH}";
|
||||
|
||||
static mut ADDRESSES: [usize;{NUM_FUNCTIONS}] = [0;{NUM_FUNCTIONS}];
|
||||
|
||||
fn terminate_process()
|
||||
{
|
||||
let mut file = fs::OpenOptions::new().create(true).append(true).open(LOG_NAME).unwrap();
|
||||
file.write_all(b"\nError ocurred!").unwrap();
|
||||
fn terminate_process() {
|
||||
process::exit(-1);
|
||||
}
|
||||
|
||||
@@ -18,15 +15,19 @@ fn gateway(index: i32) -> usize
|
||||
{
|
||||
|
||||
let func_name = get_function_name(index);
|
||||
if func_name.is_empty() {
|
||||
let mut file = fs::OpenOptions::new().create(true).append(true).open(LOG_NAME).unwrap();
|
||||
|
||||
if func_name.is_empty()
|
||||
{
|
||||
file.write_all(b"[x] Error ocurred, empty function name detected.").unwrap();
|
||||
return (terminate_process as *const()) as usize;
|
||||
}
|
||||
|
||||
|
||||
unsafe
|
||||
{
|
||||
if ADDRESSES[index as usize] != 0
|
||||
{
|
||||
let mut file = fs::OpenOptions::new().create(true).append(true).open(LOG_NAME).unwrap();
|
||||
file.write_all(func_name.as_bytes()).unwrap();
|
||||
file.write_all(b"\n").unwrap();
|
||||
return ADDRESSES[index as usize];
|
||||
@@ -37,17 +38,36 @@ fn gateway(index: i32) -> usize
|
||||
file.write_all(func_name.as_bytes()).unwrap();
|
||||
file.write_all(b"\n").unwrap();
|
||||
|
||||
|
||||
let dll_address = dinvoke_rs::dinvoke::load_library_a(DLL_NAME);
|
||||
if dll_address == 0 {
|
||||
if dll_address == 0
|
||||
{
|
||||
let error_message = format!("[x] Error trying to load the dll {}.", DLL_NAME);
|
||||
file.write_all(error_message.as_bytes()).unwrap();
|
||||
return (terminate_process as *const()) as usize;
|
||||
}
|
||||
|
||||
let mut func_address = dinvoke_rs::dinvoke::get_function_address(dll_address, &func_name);
|
||||
if func_address == 0 && func_name.contains("OrdinalPlaceholder")
|
||||
{
|
||||
let ordinal = func_name.replace("OrdinalPlaceholder", "");
|
||||
let ordinal: u32 = ordinal.parse().unwrap();
|
||||
func_address = dinvoke_rs::dinvoke::get_function_address_by_ordinal(dll_address, ordinal);
|
||||
}
|
||||
|
||||
if func_address == 0
|
||||
{
|
||||
let error_message = format!("[x] Error trying to locate the function {}.", func_name);
|
||||
file.write_all(error_message.as_bytes()).unwrap();
|
||||
return (terminate_process as *const()) as usize;
|
||||
}
|
||||
|
||||
let func_address = dinvoke_rs::dinvoke::get_function_address(dll_address, &func_name);
|
||||
|
||||
unsafe {
|
||||
ADDRESSES[index as usize] = func_address;
|
||||
}
|
||||
|
||||
file.write_all(func_name.as_bytes()).unwrap();
|
||||
file.write_all(b"\n").unwrap();
|
||||
|
||||
func_address
|
||||
}
|
||||
|
||||
|
||||
@@ -70,20 +70,17 @@ fn gateway(arg1:u64, arg2:u64, arg3:u64, arg4:u64, arg5:u64, arg6:u64, arg7:u64,
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
if func_name.is_empty()
|
||||
{
|
||||
if func_name.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let dll_address = dinvoke_rs::dinvoke::load_library_a(DLL_NAME);
|
||||
if dll_address == 0
|
||||
{
|
||||
if dll_address == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let func_address = dinvoke_rs::dinvoke::get_function_address(dll_address, &func_name);
|
||||
if func_address == 0
|
||||
{
|
||||
if func_address == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user