Apakah mungkin untuk Memanggil metode pribadi yang diekspor di c++

Apakah mungkin untuk memanggil metode pribadi dari kelas yang diekspor dari DLL?
Apakah metode tersebut akan disembunyikan dari orang yang ingin menggunakannya tetapi tidak seharusnya menggunakannya?
terima kasih :)


person Idov    schedule 18.06.2011    source sumber
comment
Saya akan terkejut jika kompiler mengizinkan Anda menandai fungsi anggota pribadi sebagai diekspor.   -  person MerickOWA    schedule 18.06.2011
comment
@MerickOWA: C++ tidak tahu apa-apa tentang DLL, jadi mungkin saja, dalam bahasanya, untuk mengimplementasikan fungsi kelas di banyak dll (kecuali kompiler melarangnya). Saya pikir itu tidak akan terjadi karena Anda dapat menyebarkan fungsi unit terjemahan silang (file objek), jadi menyebarkannya ke seluruh DLL adalah masalah untuk linker, yang tidak menerapkan banyak C++ sama sekali, AFAICT (kecuali untuk de -kudis nama fungsi yang rusak dalam pesan kesalahan).   -  person Macke    schedule 18.06.2011


Jawaban (2)


Ya, itu mungkin, tetapi Anda perlu menggunakan trik casting yang kotor atau mengandalkan perilaku semi-tidak terdefinisi, namun yang pasti Anda dapat memanggil fungsi yang diekspor, tidak peduli statusnya pribadi/publik.

Bahasa tersebut tidak memberikan keamanan terhadap penyerang jahat. Hal ini akan membantu semua orang untuk mematuhi aturan, namun tidak akan melindungi mereka yang mencoba merusak sistem.

Contohnya:

  • gunakan GetProcAddress() untuk mendapatkan alamat fungsi, masukkan ke jenis fungsi anggota yang tepat, dan panggil.
  • buat file header kelas yang dimodifikasi, nyatakan semuanya sebagai publik (atau cukup tambahkan fungsi statis, void crowbar() ), kompilasi dengan itu. (Perilaku tidak terdefinisi, karena Anda melanggar Aturan Satu Definisi, tapi mungkin akan berhasil...)

Jangan mengandalkan kata kunci pribadi C++ untuk keamanan.

person Macke    schedule 18.06.2011
comment
Tidak ada tipe fungsi anggota yang tepat untuk pointer yang diperoleh melalui GetProcAddress. Dalam kebanyakan kasus, panggilan sebenarnya memerlukan penulisan beberapa perakitan. Tapi itu mungkin. - person Ben Voigt; 18.06.2011
comment
@Ben: Saya berasumsi memanggil fungsi anggota non-virtual (jika itu adalah fungsi anggota) dengan panggilan ini cukup mudah. Apakah ada masalah lain? (Hanya penasaran) - person Macke; 18.06.2011
comment
@Macke: Ya, Anda harus meneruskan penunjuk this, dan konvensi pemanggilan thiscall tidak cocok dengan cdecl atau stdcall, karena thiscall meneruskan penunjuk this dalam register daripada menggunakan tumpukan. Mungkin kompatibel dengan fastcall, saya tidak ingat. - person Ben Voigt; 18.06.2011
comment
@Ben: Saya berasumsi Anda dapat memberikan penunjuk fungsi di seluruh konvensi panggilan. Jika tidak, maka diperlukan perakitan. Seperti yang Anda katakan, Anda memerlukan thiscall, tetapi itu harus tersirat dalam tipe fungsi ptr-ke-anggota. - person Macke; 18.06.2011
comment
@Macke: Fungsi penunjuk ke anggota memiliki dukungan untuk pencarian vtable, kelas dasar virtual yang memerlukan penyesuaian this-penunjuk, dll. Fungsi penunjuk ke anggota bukanlah penunjuk fungsi. GetProcAddress mengembalikan penunjuk fungsi, bukan penunjuk ke anggota. Hasil dari GetProcAddress perlu diubah ke tipe penunjuk fungsi yang benar (termasuk konvensi pemanggilan), tetapi tipe yang benar tidak dapat ditulis dalam C++, menurut saya tidak. - person Ben Voigt; 18.06.2011
comment
Perhatikan bahwa dukungan virtual harus ada terlepas dari apakah fungsi anggota target adalah virtual atau tidak, karena mereka bukan bagian dari tipe pmf. Kode yang memanggil pmf tidak memiliki cara untuk mengetahui apakah pmf dibuat dari fungsi virtual atau non-virtual. - person Ben Voigt; 18.06.2011
comment
@Ben: Benar. Saya tahu tentang perlunya hal itu, tetapi bisa dikatakan tidak menghubungkan titik-titiknya dengan benar. Ini akan menjadi latihan yang menarik untuk melihat apa yang diperlukan agar hal itu berhasil. :) - person Macke; 18.06.2011

Jika muncul di tabel ekspor DLL, maka dapat dipanggil dengan menggunakan GetProcAddress dan memanggil penunjuk fungsi yang dikembalikan. Ada beberapa kendala teknis untuk mendapatkan konvensi pemanggilan yang tepat, namun hal ini mungkin terjadi (kemungkinan besar diperlukan beberapa bahasa assembly).

Sebenarnya, fungsi apa pun yang menghasilkan instance out-of-line oleh kompiler dapat dipanggil dengan kode asli apa pun. Diekspor oleh DLL membuatnya lebih mudah untuk menemukan alamat kode untuk fungsi tersebut.

person Ben Voigt    schedule 18.06.2011