เป็นไปได้ไหมที่จะเรียกใช้วิธีการส่วนตัวที่ส่งออกใน c ++

เป็นไปได้ไหมที่จะเรียกใช้วิธีการส่วนตัวของคลาสที่ส่งออกจาก DLL?
มันจะถูกซ่อนจากผู้ที่ต้องการใช้แต่ไม่ควรซ่อนหรือไม่
ขอบคุณ :)


person Idov    schedule 18.06.2011    source แหล่งที่มา
comment
ฉันจะแปลกใจถ้าคอมไพเลอร์ให้คุณทำเครื่องหมายฟังก์ชันสมาชิกส่วนตัวว่าส่งออกแล้ว   -  person MerickOWA    schedule 18.06.2011
comment
@MerickOWA: C++ ไม่รู้อะไรเลยเกี่ยวกับ DLL ดังนั้นจึงเป็นไปได้ในภาษาที่จะใช้ฟังก์ชันคลาสกับ dll จำนวนมาก (เว้นแต่ว่าคอมไพเลอร์จะห้าม) ฉันคิดว่ามันจะไม่เป็นเช่นนั้นเนื่องจากคุณสามารถกระจายฟังก์ชันหน่วยการแปลข้าม (ไฟล์ obj) ได้ ดังนั้นการแพร่กระจายพวกมันไปทั่ว DLLs จึงเป็นปัญหาสำหรับตัวเชื่อมโยง ซึ่งไม่ได้บังคับใช้ C++-ness มากนัก AFAICT (ยกเว้นเพื่อ -mange ชื่อฟังก์ชันที่เสียหายในข้อความแสดงข้อผิดพลาด)   -  person Macke    schedule 18.06.2011


คำตอบ (2)


ใช่ เป็นไปได้ แต่คุณต้องใช้เทคนิคการแคสต์ที่สกปรกหรืออาศัยพฤติกรรมกึ่งไม่ได้กำหนด แต่เพื่อความแน่นอน คุณสามารถเรียกใช้ฟังก์ชันที่ส่งออกได้ ไม่ว่าจะเป็นสถานะส่วนตัว/สาธารณะก็ตาม

ภาษาไม่ได้ให้การรักษาความปลอดภัยจากผู้โจมตีที่เป็นอันตราย มันจะช่วยให้ทุกคนเล่นตามกฎ แต่จะไม่ป้องกันผู้ที่พยายามจะทำลายระบบ

ตัวอย่างเช่น:

  • ใช้ GetProcAddress() เพื่อรับที่อยู่ของฟังก์ชัน ส่งไปยังประเภทฟังก์ชันสมาชิกที่ถูกต้อง แล้วเรียกใช้
  • สร้างไฟล์ส่วนหัวที่แก้ไขแล้วของคลาส โดยประกาศทุกอย่างให้เป็นสาธารณะ (หรือเพียงเพิ่มฟังก์ชันคงที่ void crowbar() ) คอมไพล์ต่อต้านสิ่งนั้น (พฤติกรรมที่ไม่ได้กำหนด เนื่องจากคุณละเมิด One Defintion Rule แต่มันอาจจะได้ผล...)

อย่าใช้คีย์เวิร์ดส่วนตัวของ C++ เพื่อความปลอดภัย

person Macke    schedule 18.06.2011
comment
ไม่มีประเภทฟังก์ชันสมาชิกที่ถูกต้องสำหรับตัวชี้ที่ได้รับผ่าน GetProcAddress ในกรณีส่วนใหญ่ การโทรจริงจะต้องมีการเขียนชุดประกอบบางส่วน แต่มันเป็นไปได้ - person Ben Voigt; 18.06.2011
comment
@Ben: ฉันคิดว่าการเรียกใช้ฟังก์ชันสมาชิกที่ไม่ใช่เสมือน (ถ้าเป็นฟังก์ชันสมาชิกเลย) ด้วย thiscall นั้นค่อนข้างตรงไปตรงมา มีปัญหาอื่นอีกไหม? (แค่สงสัย) - person Macke; 18.06.2011
comment
@Macke: ใช่คุณต้องผ่านตัวชี้ this อย่างใดและรูปแบบการโทร thiscall ไม่ตรงกับ cdecl หรือ stdcall เนื่องจาก thiscall ผ่านตัวชี้ this ในการลงทะเบียนแทนที่จะใช้สแต็ก มันอาจจะเข้ากันได้กับ fastcall จำไม่ได้ - person Ben Voigt; 18.06.2011
comment
@ เบ็น: ฉันคิดว่าคุณสามารถส่งตัวชี้ฟังก์ชันข้ามแบบแผนการเรียกได้ ถ้าไม่เช่นนั้นก็จำเป็นต้องประกอบ อย่างที่คุณพูด คุณต้องมี thiscall แต่นั่นควรมีความหมายโดยนัยในรูปแบบ ptr-to-member-function - person Macke; 18.06.2011
comment
@Macke: Pointer-to-member-function รองรับการค้นหา vtable คลาสฐานเสมือนที่ต้องการ this-pointer-adjustments ฯลฯ ตัวชี้ไปยังสมาชิกฟังก์ชันไม่ใช่ตัวชี้ฟังก์ชัน GetProcAddress ส่งคืนตัวชี้ฟังก์ชัน ไม่ใช่ตัวชี้ถึงสมาชิก ผลลัพธ์ของ GetProcAddress จำเป็นต้องส่งไปยังประเภทตัวชี้ฟังก์ชันที่ถูกต้อง (รวมถึงรูปแบบการเรียก) แต่ประเภทที่ถูกต้องไม่สามารถเขียนด้วย C ++ ได้ ฉันไม่คิดว่า - person Ben Voigt; 18.06.2011
comment
โปรดทราบว่าต้องมีการสนับสนุนเสมือนไม่ว่าฟังก์ชันสมาชิกเป้าหมายจะเป็นเสมือนหรือไม่ เนื่องจากไม่ได้เป็นส่วนหนึ่งของประเภท pmf รหัสที่เรียก pmf ไม่มีทางรู้ได้ว่า pmf นั้นถูกสร้างขึ้นจากฟังก์ชันเสมือนหรือไม่ใช่เสมือน - person Ben Voigt; 18.06.2011
comment
@เบน: ถูกต้อง ฉันรู้เกี่ยวกับความจำเป็นในสิ่งนั้น แต่ไม่ได้เชื่อมโยงจุดต่าง ๆ อย่างเหมาะสม มันจะเป็นแบบฝึกหัดที่น่าสนใจเพื่อดูว่ามีอะไรที่จำเป็นในการทำให้มันใช้งานได้ :) - person Macke; 18.06.2011

หากปรากฏในตารางการส่งออกของ DLL ก็สามารถเรียกใช้ได้โดยใช้ GetProcAddress และเรียกใช้ตัวชี้ฟังก์ชันที่ส่งคืน มีอุปสรรคทางเทคนิคบางประการเพื่อให้ได้รูปแบบการโทรที่ถูกต้อง แต่ก็เป็นไปได้ (โดยส่วนใหญ่แล้วจะต้องใช้ภาษาแอสเซมบลีบางอย่าง)

พูดอย่างเคร่งครัด ฟังก์ชันใดๆ ที่คอมไพลเลอร์สร้างอินสแตนซ์นอกบรรทัดสามารถเรียกใช้ด้วยโค้ดเนทีฟใดก็ได้ การส่งออกโดย DLL ช่วยให้ค้นหาที่อยู่ของโค้ดสำหรับฟังก์ชันได้ง่ายขึ้นมาก

person Ben Voigt    schedule 18.06.2011