Closed wangjia184 closed 2 years ago
It sounds like you're either using the PeFile from the wrong bitness or that you're running this on a big endian arch? big endian is not supported by this library as it does not allow reinterpreting disk bytes directly as rust structures.
Edit: it could also be that my filemapping code is just broken on linux... You can try std::fs::read
and hope the allocated byte buffer has the right alignment and see if that helps.
thanks @CasualX
I found the reason and it is not caused by the library. The reason is that -- when dotnet build on Linux targeting Windows, even if the assembly dll will be used in a x64 environment, the PE NT optional header still generating using a PE32 format.
I fixed the issue by try both PE64 and PE32
pub fn parse_pe_version(file_path : &str) -> String {
match FileMap::open(file_path) {
Err(_) => "".to_string(),
Ok(file_map) => {
let result = match Pe32File::from_bytes(&file_map) {
Err(_) => {
match Pe64File::from_bytes(&file_map) {
Ok(f) => f.resources(),
Err(e) => Err(e),
}
}
Ok(f) => f.resources()
};
match result {
Err(_) => "".to_string(),
Ok(resources) => {
match resources.version_info() {
Err(_) => "".to_string(),
Ok(version_info) => {
match version_info.fixed() {
None => "".to_string(),
Some(fixed_info) => {
let version = fixed_info.dwFileVersion.to_string();
if version.len() > 0 {
version
} else {
fixed_info.dwProductVersion.to_string()
}
}
}
}
}
}
}
},
}
}
Ah, surely explicitly using pelite::pe64::PeFile
should work?
The method to 'transparently' read from the 32-bit or 64-bit PE files is using the Wrap
. It redefines the whole pelite API on top of a generic Wrap<T32, T64>
type which dispatches between 32-bit (T32) and 64-bit (T64) variants.
Ah, surely explicitly using pelite::pe64::PeFile should work?
No, that does not work.
No, that does not work.
OH I see, it's ACTUALLY a PE32 file for C# dot net DLLs on linux, that took me some time to understand.
You can try pelite::PeFile
to handle dispatching between PE32 and PE64 for you:
let file_map = pelite::FileMap::open(path)?;
let resources = pelite::PeFile::from_bytes(&file_map)?.resources()?;
The following code works well on Windows, but on Linux in our CI environment, it cannot extract version.
We are running cross-compilation in containers of GitLab CI, the PE files are fine. I download them and try to parse on Windows, and it works. But when the code executes on Linux, it fails.
PeFile::from_bytes failed. try again with correct parser