Coder Social home page Coder Social logo

Comments (4)

bjorn3 avatar bjorn3 commented on May 30, 2024

Why are you using undecorated if you need the @4? import_name_type = "undecorated" tells rustc to not generate any prefixes or suffixes to the symbol. If you want them import_name_type = "decorated" (the default) is what you should use afaik.

from rust.

mingkuang-Chuyu avatar mingkuang-Chuyu commented on May 30, 2024

Why are you using undecorated if you need the @4? import_name_type = "undecorated" tells rustc to not generate any prefixes or suffixes to the symbol. If you want them import_name_type = "decorated" (the default) is what you should use afaik.

Normally, the import_name_type attribute should not change the symbol name.

You can check the "synchronization.lib" file of the Windows SDK, the info about WakeByAddressSingle function is as follows:

dumpbin /HEADERS "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\synchronization.lib"

image

Then we look at the disassembly code when using WakeByAddressSingle, and we can see that the symbol name is still __imp__WakeByAddressSingle@4.

image

Rust's behavior is not standard, and there are security issues.

In another lib file, there happens to be such a function. Because of Rust's non-standard behavior, they will have exactly the same symbol names. This makes it impossible for the linker to distinguish between them, and the linker will only use the first symbol.

In the following code, will rust use the _Test function or the Test function? Why is this so? This is because rust's undecorated doesn't follow the C decorated name rule!

// in rust __imp__Test
#[link(name = "DLL A", kind = "raw-dylib", import_name_type = "undecorated")]
    extern "system" {
        // extern "C" void  __stdcall _Test();
        pub fn _Test();
    }

// DLL A
#pragma comment(linker, "/export:_Test=__Test@0")
extern "C" void  __stdcall _Test()
{
    // in standard, symbol name is `__imp___Test@0` and `__Test@0`
    // in rust(undecorated), symbol name is  `__imp__Test` and `_Test`
}


// DLL B
extern "C" void __cdecl Test()
{
   // in standard, symbol name is `__imp__Test` and  `_Test`
   // Note that the name of the symbol is exactly the same as in the previous rust(undecorated) scene !!!
}

from rust.

ChrisDenton avatar ChrisDenton commented on May 30, 2024

cc @dpaoliello for this and #124956

from rust.

dpaoliello avatar dpaoliello commented on May 30, 2024

there are security issues

Can you please elaborate on this? If you are linking against a malicious import library or loading a malicious DLL, then name confusion doesn't provide any benefits to the attacker: they already have arbitrary read/write/execute and can use many other tricks to force their code to be executed.

When generating the lib, the symbol name should remain __imp__WakeByAddressSingle@4, just set the IMPORT_OBJECT_HEADER::NameType property to IMPORT_NAME_UNDECORATE. Then the linker will automatically convert the name to WakeByAddressSingle.

This is a fair criticism, but we'd need to make sure that using NameType produces the same behavior that Rust currently has (i.e., that we can control exactly which function name is loaded at runtime) especially in cases where GCC and MSVC disagree (see the import_name_type MCP). I wouldn't want to change this now without an MCP and a motivating example where the Rust compiler has incorrect behavior.

Rust's behavior is not standard
This is because rust's undecorated doesn't follow the C decorated name rule!

Can you please point me to documentation for this "standard" or "rule"?

Also, the intent of import_name_type is to opt-out of normal function name decoration and instead to use the modified name decoration that is documented in Rust's docs: https://doc.rust-lang.org/reference/items/external-blocks.html#the-import_name_type-key.

In the following code, will rust use the _Test function or the Test function? Why is this so?

It calls Test in DLL A.dll because you asked it to call Test without any decorations.

You have shown that Rust produces different import headers than MSVC or Clang does, but you haven't explained why this is an issue. Please remember that the goal of the raw-dylib feature in Rust is that the final binary will load a specific function from a specific DLL without the developer having to provide an import library to the linker. This is a different goal than MSVC and Clang have for their import libraries.

If you can show an example where Rust calls a function that does not match the name per the import_name_type spec in the Rust docs (conflicting symbol definitions? linker depending on SymbolName being set?) then that would be a bug that we could address.

from rust.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.