Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong address size populated for win32 x86 process #116

Open
AlexDoh opened this issue Apr 3, 2024 · 5 comments
Open

Wrong address size populated for win32 x86 process #116

AlexDoh opened this issue Apr 3, 2024 · 5 comments

Comments

@AlexDoh
Copy link

AlexDoh commented Apr 3, 2024

Hello!
Using memlow-ffi and reading x32 process inside Win10x64 VM, so every pointer is an actually a DWORD(uint). So reading a c++ structure object with pointers, which are being read by memflow read_raw as x32 pointers (ulong) so it is impossible to normally read a structure data after any pointer inside a structure.
Could someone please add a fix or feature for supporting reading pointers as x86? I saw there is a feature for original Rust implementation for reading x32 addresses like "read_addr32", but probably it is only for an address or it supports the structures too, nit sure.
Please add possibility for reading pointers as x32 for a pointer type if reading into a structure.
Or at least please point me to the place where it could be added/updated, maybe I could contribute and add this.

Thanks!

@ko1N
Copy link
Member

ko1N commented Apr 3, 2024

Hey there, thanks for your first issue! Im not sure if i understood the request correctly though. The read_addr32 and read_addr64 as well as read_addr_arch functions are still present. However they are not exported to the C layer due to constraints in the implementation. You can easily re-implement them in your C code however by reading a uint32_t or uint64_t respectively and then put this into an address.

They are currently implemented like this:

fn read_addr_arch(&mut self, arch: ArchitectureObj, addr: Address) -> PartialResult<Address>

In case you want to read into a struct directly then of course pointers will not be sufficient as they the struct will have the pointer widths of the architecture you compile it for. To circumvent that you could for example either replace the pointers in the structs with uint32_t values or uint64_t values respectively and then read the struct they are pointing to.

Having raw points in a struct that you read with memflow will point to invalid memory anyways (in the context of your application). Currently there is no way to resolve raw pointers in a way that would work for this use case.
However in Rust we support 2 distinct pointer types that you can use in structs, here is an example:

#[repr(C)]
#[derive(Copy, Clone, Pod)]
pub struct Prop {
    pub table: Pointer64<Table>, // table_t *
    pub name: Pointer64<ReprCString>, // const char *
}

#[repr(C)]
#[derive(Default, Copy, Clone, Pod)]
pub struct Table {
    //
}

// ...

let virt_mem = &mut process.forward_mut();
let prop_name = prop.name.read_string(virt_mem)?.to_string();

// ...

let mut table = Table::default();
prop.table.read_into(virt_mem, &mut table)?;

Hope that helped.

@AlexDoh
Copy link
Author

AlexDoh commented Apr 3, 2024

@ko1N Thank you for the clarification!
Unfortunately I have to stick to the C implementation of memflow because I don't want to rewrite all the C structures, which are provided by the app SDK, which is written in C++ and there are a lot of classes/structures/types....

"In case you want to read into a struct directly then of course pointers will not be sufficient as they the struct will have the pointer widths of the architecture you compile it for" I have thought about that, but this is what I have got where there was a try to build with the x32 arch ("-m32" flag in Cmake file):

/usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(serde_json-33b935d647617e68.serde_json.efd370de48e8361e-cgu.04.rcgu.o)' is incompatible with i386 output /usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(serde_json-33b935d647617e68.serde_json.efd370de48e8361e-cgu.11.rcgu.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(coarsetime-be883958c8d90051.coarsetime.2930bd6dd2e35a34-cgu.0.rcgu.o)' is incompatible with i386 output /usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(coarsetime-be883958c8d90051.coarsetime.2930bd6dd2e35a34-cgu.1.rcgu.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(compiler_builtins-1088ecd7666b60f4.compiler_builtins.3b448df83059ed2c-cgu.007.rcgu.o)' is incompatible with i386 output /usr/bin/ld: i386:x86-64 architecture of input file /home/alex/repo/dma/lib/memflow/target/release/libmemflow_ffi.a(time-e8f3324299bc6e2b.time.d1c83796c831e0dd-cgu.03.rcgu.o)' is incompatible with i386 output

Is it possible to have x32 memflow-ffi build?

@ko1N
Copy link
Member

ko1N commented Apr 3, 2024

The current solution would be to manually build memflow-ffi as a 32bit target.

You could try compiling the main repo for i686. Something like this could work:

rustup target add i686-pc-windows-msvc
cargo build --target i686-pc-windows-msvc --release --all-features --workspace

Edit: I will try and see if we could add a test case to the ci for this.

@AlexDoh
Copy link
Author

AlexDoh commented Apr 3, 2024

Thanks @ko1N! But it showed this error:

alex@fedora:~/repo/memflow$ cargo build --target i686-pc-windows-msvc --release --all-features --workspace
warning: unused #[macro_use] import
--> memflow/src/lib.rs:232:1
|
232 | #[macro_use]
| ^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default
warning: memflow (lib) generated 1 warning
Compiling memflow-ffi v0.2.0 (/home/alex/repo/memflow/memflow-ffi)
error: linker link.exe not found
|
= note: No such file or directory (os error 2)
note: the msvc targets depend on the msvc linker but link.exe was not found
note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
note: VS Code is a different product, and is not sufficient.
error: could not compile memflow-ffi (lib) due to 1 previous error

Does this build expects WinOS to be running on? I am using Fedora as host Os and Win10 as guest Os
I have also tried to run with target "stable-i686-pc-windows-gnu", but it showed even more compilation errors

@ko1N
Copy link
Member

ko1N commented Apr 3, 2024

Then you probably want to use something like i686-unknown-linux-gnu instead. Please refer to the rustup docs on how to setup different targets: https://rust-lang.github.io/rustup/cross-compilation.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants