You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using the iced_x86 crate in rust lang for my shellcode, but receiving the Iced(IcedError { error: "Operand 1: 64-bit addressing can only be used in 64-bit mode : 0x0 mov eax,[2]" }) error. (These funcs were previously meant for 64 bit, but now I need them for 32 bit, obviously they've been ported over) Code:
use crate::{Error, Result};
use exe::{
Address, CCharString, ImageImportByName, ImportDirectory, TLSDirectory, Thunk, ThunkData,
ThunkFunctions, PE,
};
use iced_x86::code_asm::*;
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
use winapi::um::winnt::DLL_PROCESS_ATTACH;
pub(crate) fn generate_importer32<'a>(pe: &'a PE, imagebase: usize) -> Result<Vec<u8>> {
let import_dir = ImportDirectory::parse(pe)?;
let kernel32 = unsafe { GetModuleHandleA("kernel32.dll\0".as_ptr() as _) };
if kernel32.is_null() {
return Err(Error::GetModuleHandle(unsafe { GetLastError() }));
}
let load_library = unsafe { GetProcAddress(kernel32, "LoadLibraryA\0".as_ptr() as _) };
if load_library.is_null() {
return Err(Error::GetProcAddress(unsafe { GetLastError() }));
}
let get_proc_address = unsafe { GetProcAddress(kernel32, "GetProcAddress\0".as_ptr() as _) };
if get_proc_address.is_null() {
return Err(Error::GetProcAddress(unsafe { GetLastError() }));
}
let mut a = CodeAssembler::new(32)?;
a.mov(ebp, esp)?;
a.sub(esp, 0x20)?;
a.mov(esi, load_library as u32)?;
let esi_load_library = esi;
a.mov(edi, get_proc_address as u32)?;
let edi_get_proc_address = edi;
let mut return_label = a.create_label();
let mut string_data = vec![];
let mut create_string = |a: &mut CodeAssembler, s: &'a str| {
let label = a.create_label();
string_data.push((label, s));
dword_ptr(label)
};
for desc in import_dir.descriptors {
let s = create_string(&mut a, desc.get_name(pe)?.as_str());
a.lea(eax, s)?;
a.push(eax)?;
a.call(esi_load_library)?;
a.test(eax, eax)?;
let mut success_label = a.create_label();
a.jnz(success_label)?;
a.inc(eax)?;
a.jmp(return_label)?;
a.set_label(&mut success_label)?;
a.mov(ebx, eax)?;
for (thunk, rva) in desc
.get_lookup_thunks(pe)?
.into_iter()
.zip((desc.first_thunk.0..).step_by(4))
{
let thunk = if let Thunk::Thunk32(inner) = thunk {
inner
} else {
panic!("Unexpected thunk type")
};
match thunk.parse_import() {
ThunkData::ImportByName(v) => {
let s = create_string(&mut a, ImageImportByName::parse(pe, v)?.name.as_str());
a.lea(eax, s)?;
a.push(eax)?;
}
ThunkData::Ordinal(v) => {
assert!(v <= 0xffff, "Ordinal value too large");
a.mov(eax, v as u32)?;
a.push(eax)?;
}
_ => return Err(Error::from(exe::Error::CorruptDataDirectory)),
}
a.push(ebx)?;
a.call(edi_get_proc_address)?;
a.test(eax, eax)?;
let mut success_label = a.create_label();
a.jnz(success_label)?;
a.inc(eax)?;
a.jmp(return_label)?;
a.set_label(&mut success_label)?;
a.mov(dword_ptr(imagebase + rva as usize), eax)?;
}
}
a.xor(eax, eax)?;
a.set_label(&mut return_label)?;
a.mov(esp, ebp)?;
a.ret()?;
for (mut label, s) in string_data {
a.set_label(&mut label)?;
a.db(s.as_bytes())?;
a.db(&[0])?;
}
Ok(a.assemble(0)?)
}
pub(crate) fn generate_caller32(pe: &PE, imagebase: usize) -> Result<Vec<u8>> {
let nt_headers = pe.get_valid_nt_headers_32()?;
let entry = imagebase as u32 + nt_headers.optional_header.address_of_entry_point.0 as u32;
let tls_dir = if let TLSDirectory::TLS32(inner) = TLSDirectory::parse(pe)? {
inner
} else {
panic!("Unexpected TLS directory type");
};
let mut a = CodeAssembler::new(32)?;
a.mov(ebp, esp)?;
a.sub(esp, 0x20)?;
for callback in tls_dir.get_callbacks(pe)? {
a.push(0)?; // lpvReserved
a.push(DLL_PROCESS_ATTACH as u32)?; // fdwReason
a.push(imagebase as u32)?; // hinstDLL
let callback_addr = imagebase as u32 + callback.as_rva(pe)?.0 as u32;
a.mov(eax, callback_addr)?;
a.call(eax)?;
}
a.push(0)?; // lpvReserved
a.push(DLL_PROCESS_ATTACH as u32)?; // fdwReason
a.push(imagebase as u32)?; // hinstDLL
a.mov(eax, entry)?;
a.call(eax)?;
a.xor(eax, eax)?; // Return 0
a.mov(esp, ebp)?;
a.ret()?;
Ok(a.assemble(0)?)
}
I have tried using CodeAssembler::new(32)?; to specify 32 bit mode, tried using different memory operands syntaxes with the lea instruction, such as dword reference, dword ptr reference, direct reference. But still receiving the said error. I am compiling in 32 bit using target = "i686-pc-windows-msvc", and I am using this for a dll injector with manual mapping, the dll is 32 bit, the I'm trying to inject into is 32 bit. Also using 2024 stable rust, alongside the latest version of iced_x86. How could I go on about fixing this?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I'm using the iced_x86 crate in rust lang for my shellcode, but receiving the
Iced(IcedError { error: "Operand 1: 64-bit addressing can only be used in 64-bit mode : 0x0 mov eax,[2]" })error. (These funcs were previously meant for 64 bit, but now I need them for 32 bit, obviously they've been ported over) Code:I have tried using
CodeAssembler::new(32)?;to specify 32 bit mode, tried using different memory operands syntaxes with the lea instruction, such as dword reference, dword ptr reference, direct reference. But still receiving the said error. I am compiling in 32 bit usingtarget = "i686-pc-windows-msvc", and I am using this for a dll injector with manual mapping, the dll is 32 bit, the I'm trying to inject into is 32 bit. Also using 2024 stable rust, alongside the latest version of iced_x86. How could I go on about fixing this?Beta Was this translation helpful? Give feedback.
All reactions