Retrieves the address of an exported function from the specified module. This functions is analogous to GetProcAddress from Win32. The exported function's address is obtained by walking and parsing the EAT of the specified module. In case that the function's address can't be retrieved, it will return 0. # Examples ``` let ntdll = dinvoke::get_module_base_address("ntdll.dll"); if ntdll != 0 {
(module_base_address: isize, function: &str)
| 63 | /// } |
| 64 | /// ``` |
| 65 | pub fn get_function_address(module_base_address: isize, function: &str) -> isize { |
| 66 | |
| 67 | unsafe |
| 68 | { |
| 69 | |
| 70 | let mut function_ptr:*mut i32 = ptr::null_mut(); |
| 71 | let pe_header = *((module_base_address + 0x3C) as *mut i32); |
| 72 | let opt_header: isize = module_base_address + (pe_header as isize) + 0x18; |
| 73 | let magic = *(opt_header as *mut i16); |
| 74 | let p_export: isize; |
| 75 | |
| 76 | if magic == 0x010b |
| 77 | { |
| 78 | p_export = opt_header + 0x60; |
| 79 | } |
| 80 | else |
| 81 | { |
| 82 | p_export = opt_header + 0x70; |
| 83 | } |
| 84 | |
| 85 | let export_rva = *(p_export as *mut i32); |
| 86 | let ordinal_base = *((module_base_address + export_rva as isize + 0x10) as *mut i32); |
| 87 | let number_of_names = *((module_base_address + export_rva as isize + 0x18) as *mut i32); |
| 88 | let functions_rva = *((module_base_address + export_rva as isize + 0x1C) as *mut i32); |
| 89 | let names_rva = *((module_base_address + export_rva as isize + 0x20) as *mut i32); |
| 90 | let ordinals_rva = *((module_base_address + export_rva as isize + 0x24) as *mut i32); |
| 91 | |
| 92 | for x in 0..number_of_names |
| 93 | { |
| 94 | |
| 95 | let address = *((module_base_address + names_rva as isize + x as isize * 4) as *mut i32); |
| 96 | let mut function_name_ptr = (module_base_address + address as isize) as *mut u8; |
| 97 | let mut function_name: String = "".to_string(); |
| 98 | |
| 99 | while *function_name_ptr as char != '\0' // null byte |
| 100 | { |
| 101 | function_name.push(*function_name_ptr as char); |
| 102 | function_name_ptr = function_name_ptr.add(1); |
| 103 | } |
| 104 | |
| 105 | if function_name.to_lowercase() == function.to_lowercase() |
| 106 | { |
| 107 | let function_ordinal = *((module_base_address + ordinals_rva as isize + x as isize * 2) as *mut i16) as i32 + ordinal_base; |
| 108 | let function_rva = *(((module_base_address + functions_rva as isize + (4 * (function_ordinal - ordinal_base)) as isize )) as *mut i32); |
| 109 | function_ptr = (module_base_address + function_rva as isize) as *mut i32; |
| 110 | |
| 111 | break; |
| 112 | } |
| 113 | |
| 114 | } |
| 115 | |
| 116 | let mut ret: isize = 0; |
| 117 | |
| 118 | if function_ptr != ptr::null_mut() |
| 119 | { |
| 120 | ret = function_ptr as isize; |
| 121 | } |
| 122 |
no outgoing calls
no test coverage detected