Terinspirasi oleh pertanyaan StackOverflow yang sekarang dihapus . Bisakah Anda menemukan cara untuk mengeksekusi metode tertentu, tanpa secara eksplisit menyebutnya? Semakin tidak langsung, semakin baik.
Inilah yang saya maksud, tepatnya (C digunakan hanya untuk contoh, semua bahasa diterima):
// Call this.
void the_function(void)
{
printf("Hi there!\n");
}
int main(int argc, char** argv)
{
the_function(); // NO! Bad! This is a direct call.
return 0;
}
Pertanyaan asli:
popularity-contest
function
Komunitas
sumber
sumber
Jawaban:
C
Ketika dikompilasi dengan GCC, kompiler menggantikan
printf("Goodbye!\n")
denganputs("Goodbye!")
, yang lebih sederhana dan dianggap setara. Saya secara diam-diam menyediakanputs
fungsi khusus saya , sehingga dipanggil sebagai gantinya.sumber
Nah, bagaimana malware bisa menjalankan fungsi yang tidak dipanggil dalam kode? Dengan buffer yang meluap!
Di sistem saya, alamat pengirim
main
kebetulan disimpan 3 kata di atas variabel lokal pertama. Dengan mengacak alamat pengirim itu dengan alamat fungsi lain,main
"mengembalikan" ke fungsi itu. Jika Anda ingin mereproduksi perilaku ini di sistem lain, Anda mungkin harus mengubah 3 ke nilai lain.sumber
<!-- language: lang-c -->
dua baris sebelum kode Anda untuk menyorotnya.Pesta
sumber
Python 2
Berikut adalah beberapa cara yang terinspirasi oleh jawaban lain:
mengeksekusi kode secara langsung
Ini adalah cara terbaik untuk tidak memanggil fungsi.
menggunakan destructor
Menggunakan std I / O
menggunakan pencarian atribut
Mekanisme impor
Yah saya kira itu saja .. Saya tidak bisa mengimpor apa pun sekarang. Jangan tunggu ..
Menggunakan kurung get-item
[]
Menggunakan variabel global. Kesukaanku!
hello
adalah akses ked['hello']
. Setelah ini dunia tampak kelabu.Kelas meta;)
Menggunakan iterator (Anda dapat membebani operator apa pun dan menggunakannya)
Kesalahan!
Kerangka kerja memanggil Anda kembali. Hampir setiap GUI memiliki fungsi ini.
Jalankan string sumber (func harus dalam file)
Dekorator
dengan acar de-serialisasi (paling tidak favorit datang)
Menggunakan serialisasi
Lebih banyak jawaban Python:
hasattr
globals()
dan__call__
secara tidak langsungreprlib
sumber
Javascript
Yang ini menggunakan JSFuck untuk melakukan pekerjaan kotor.
sumber
""
adalah string, dan[]
mengevaluasi ke 0, jadi""[[]]
tidak terdefinisi, dan""[[]]+""
"tidak terdefinisi". Dari sana Anda dapat mengeluarkan huruf individual:(""[[]]+"")[[]]
is "u". Jadi ini lebih seperti hack untuk memanggil exec dengan kode arbitrer. Saya pikir itu penting?function anonymous() { x() }
.Python
Ini ditetapkan
the_function
sebagai fungsi profil, menyebabkannya dieksekusi pada setiap panggilan fungsi dan kembali.sumber
C #
Kami dapat menyalahgunakan DLR untuk selalu mengeksekusi beberapa kode setiap kali Anda mencoba memanggil metode apa pun di kelas. Ini sedikit lebih murah / jelas daripada solusi seperti delegasi, refleksi, konstruktor statis, dll., Karena metode yang dieksekusi tidak hanya tidak pernah dipanggil tetapi bahkan tidak pernah direferensikan , bahkan tidak dengan namanya.
Ini selalu mencetak "Ha! Membuatmu tertipu!" apa pun yang Anda coba gunakan
a
. Jadi saya bisa dengan mudah menulisa.SuperCaliFragilisticExpiAlidocious()
dan akan melakukan hal yang sama.sumber
GNU C
Ini sangat langsung, tetapi tentu saja bukan panggilan untuk
hello_world
, meskipun fungsinya mengeksekusi.sumber
Rubi
Terinspirasi oleh wat .
sumber
C
Anda dapat mendaftarkan fungsi yang akan dipanggil di akhir program dalam C, jika itu sesuai dengan kebutuhan Anda:
sumber
Jawa
Mencoba ini dengan java:
Metode
secretMethodNotCalledInMain
ini dipanggil hanya dengan refleksi, dan saya tidak mencari sesuatu yang disebutsecretMethodNotCalledInMain
(sebaliknya saya mencari sesuatu yang tidak dipanggilmain
). Lebih lanjut, bagian reflektif dari kode dipanggil di luarmain
metode ketika handler pengecualian JDK menendang masuk.Ini info JVM saya:
Ini adalah output dari program saya:
Saya tidak mengharapkan mereka
NullPointerException
yang dilempar dari kode asli untuk menangani refleksi. Tapi, seperti yang disebutkan oleh @ johnchen902 itu karena mewarisi beberapa metode darijava.lang.Object
dan saya akhirnya memanggil mereka dinull
s.sumber
NPE
bukan bug JDK. Mereka dilempar karena Anda mencoba memanggil metode instan yang dideklarasikanjava.lang.Object
sepertitoString()
dengannull
.C ++
Salah satu cara dalam C ++ adalah dalam konstruktor dan / atau destruktor objek statis:
sumber
new
, dan dengan demikian akan menjadi jawaban yang menarik untuk memiliki cara untuk memohon yang tidaknew
. Tapi saya tidak tahu, konstruktor statis terasa seperti sedikit curang.new (p) foo()
. Dan Anda dapat merusak objek tanpa melepaskan memori melaluip->~foo()
.C: Hello World
Keluaran:
Untuk menautkan metode ini, kita perlu printf () untuk dikompilasi di suatu tempat dalam program, tetapi tidak harus benar-benar dipanggil. Fungsi printf () dan main () terletak 276 byte terpisah satu sama lain di segmen kode. Nilai ini akan berubah berdasarkan OS dan kompiler. Anda dapat menemukan alamat aktual di sistem Anda dengan kode ini dan kemudian kurangi saja:
sumber
*
sebelummain
benar-benar membingungkan dan tidak perlu.main
adalah fungsi yang Anda tidak dapat melakukan dereferensi, sehingga secara implisit meluruh ke pointer fungsi yang kemudian direferensikan untuk menghasilkan fungsi lagi. Anda tidak bisa mengurangi int dari suatu fungsi, jadi itu meluruh ke pointer fungsi lagi. Anda mungkin juga menulis(*****main-276)
;) Anda mungkin bermaksud menulis(&main-276)
atau(*(main-276))
sebagai gantinya.The * before main is really confusing and unnecessary.
- Bukankah itu umumnya hal yang baik di situs ini?main
, tetapi tidak dapat menemukannya sekarang ...C (dengan GCC sebaris asm)
Ini akan menyebabkan beberapa kode yang dipancarkan GCC berakhir di segmen berbeda dari file objek, secara efektif membuat aliran kontrol “jatuh melalui” fungsi_fungsi. Perhatikan bahwa ini tidak berfungsi jika GCC memutuskan untuk menyusun ulang fungsi, jelas. Diuji dengan GCC 3.4.6 pada MirBSD-current / i386, menggunakan
-O2
. (Juga, itu istirahat debug, kompilasi dengan-g
kesalahan ☺)sumber
PHP ≥5.4.0
Solusi ini memang merupakan kekacauan yang mengerikan, tetapi ia melakukan tugas yang diberikan kepadanya (tidak ada ketentuan seberapa baik ia harus melakukan).
Fungsi untuk memanggil tanpa memanggil :
Solusinya :
Contoh :
Output yang mungkin:
Penjelasan :
Ketika dipanggil,
executeFunction()
akan membaca isi dari file yang sedang dieksekusi (yang berarti ini hanya dimaksudkan untuk dijalankan dari CLI, seperti yang digunakan$argv
), menguraikan argumen dan isi dari fungsi yang ditentukan, meretas semuanya kembali menjadi potongan baru dari kode,eval()
semuanya, dan kembalikan hasilnya. Hasilnya adalah yanggetRandomString()
tidak pernah benar-benar dipanggil, baik secara langsung atau tidak langsung, tetapi kode dalam fungsi tubuh masih dijalankan.sumber
__construct()
metode penting dalam PHP karena Anda tidak pernah memanggil fungsi secara langsung, tetapi gunakannew Something()
sebagai gantinya?register_tick_function()
,,register_shutdown_function()
atauspl_autoload_register()
mirip dengan jawaban Python @ grc, tapi saya merasa seperti itu 'curang' dan mengambil jalan keluar yang mudah.Perl
Ya, hanya itu yang ada untuk itu. Tidak semua subrutin dibuat sama.
sumber
T-SQL
Ini fitur bawaan. Pemicu untuk menang!
Jika Anda benar-benar ingin bersenang-senang dengannya, buat banyak BUKAN pemicu pada Hari April Mop.
Hasil:
Sangat lucu. Lulz seperti itu. Wow.
Tinker menambahkannya di SQLFiddle.
sumber
JavaScript
Di konsol Firefox:
Kemudian mulai ketik apa saja di konsol - Firefox memanggil
.toString()
beberapa kali saat Anda mengetik di konsol.Pendekatan serupa adalah:
sumber
C
Platform pilihan adalah Linux. Kami tidak dapat memanggil fungsi kami, jadi kami akan meminta tautan kami melakukannya:
Bagaimana cara mendapatkan alamat ajaib?
Kami mengandalkan Spesifikasi Core Basis Standar Linux, yang mengatakan:
Kompilasi kode:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Periksa alamat
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Temukan VMA-nya:
dan ganti nilai itu untuk
ADDRESS
.sumber
VB6 dan VBA
Tidak yakin apakah ini memenuhi syarat atau tidak, karena memanggil metode kelas:
Ini berlaku dalam modul kelas:
Dan ini adalah kode "panggilan":
Ini berfungsi dengan menukar fungsi vptr's untuk dua Subs di vtable untuk kelas.
sumber
Haskell
Dalam haskell jika Anda melakukannya:
Ini akan dieksekusi segera tanpa memanggil namanya saat Anda menjalankannya. Sihir!
sumber
Javascript
Mudah, cukup gunakan
on___
acara di JS. Sebagai contoh:sumber
Jawa
Jawaban java lainnya dari saya. Seperti yang Anda lihat dalam kode, kode itu langsung memanggil
theCalledMethod
, tetapi metodenotCalledMethod
ini dijalankan sebagai gantinya.Jadi, pada akhirnya saya melakukan 2 hal:
Menjalankannya:
sumber
getBytes()
metode, menyalakannyagetBytes("UTF-8")
. Karena saya tidak memiliki OS X, dapatkah Anda menguji apakah ini berfungsi?Python
sumber
Jawa
Yay, pengumpulan sampah!
Versi untuk mereka yang mau tidak mau akan mengatakan itu
System.gc()
tidak dapat diandalkan:sumber
Objektif-C
(Mungkin hanya jika dikompilasi dengan dentang di Mac OS X)
Kode ini menggunakan beberapa trik untuk sampai ke fungsi yang tidak digunakan. Pertama adalah nilai 0x2A27. Ini adalah penunjuk yang ditandai untuk bilangan bulat 42, yang menyandikan nilai dalam penunjuk untuk menghindari mengalokasikan objek.
Berikutnya adalah
MyClass
. Itu tidak pernah digunakan, tetapi runtime memanggil+load
metode ketika itu dimuat, sebelumnyamain
. Ini secara dinamis membuat dan mendaftarkan kelas baru, menggunakanNSValue
sebagai superclass-nya. Itu juga menambahkan+load
metode untuk kelas itu, menggunakanMyClass
's-unusedMethod
sebagai implementasinya. Setelah pendaftaran, ia memanggil metode memuat di kelas baru (untuk beberapa alasan itu tidak dipanggil secara otomatis).Karena metode beban kelas baru menggunakan implementasi yang sama dengan
unusedMethod
, yang secara efektif disebut. Dibutuhkan superkelas itu sendiri, dan ditambahkanunusedFunction
sebagai implementasi untukdoesNotRecognizeSelector:
metode kelas itu . Metode ini awalnya merupakan metode instance onMyClass
, tetapi sedang dipanggil sebagai metode kelas pada kelas baru, demikianself
juga objek kelas baru. Oleh karena itu, superclass adalahNSValue
, yang juga merupakan superclass untukNSNumber
.Akhirnya,
main
lari. Dibutuhkan nilai pointer dan menempelkannya dalamNSString *
variabel (pemain__bridge
dan pertama yangvoid *
memungkinkan ini untuk digunakan dengan atau tanpa ARC). Kemudian, ia mencoba memanggilstringByAppendingString:
variabel itu. Karena sebenarnya angka, yang tidak menerapkan metode itu,doesNotRecognizeSelector:
metode ini disebut sebagai gantinya, yang perjalanan melalui hirarki kelas untukNSValue
mana ia diimplementasikan menggunakanunusedFunction
.Catatan: ketidakcocokan dengan sistem lain adalah karena penggunaan penunjuk yang ditandai, yang saya tidak percaya telah dilaksanakan oleh implementasi lain. Jika ini diganti dengan nomor yang biasanya dibuat, sisa kode harus bekerja dengan baik.
sumber
0x2A27
nilai, jadi saya tidak tahu apakah itu diterapkan di tempat lain. ObjFW jelas menarik.0x2A27
adalah pointer tagJavascript
Saya merasa seperti ini tidak secara eksplisit terlihat seperti memanggil fungsi
sumber
C # (via
using
)sumber
Jawa
Saya mengambil keuntungan dari fitur khusus serialisasi Java. The
readObject
Metode dipanggil ketika objek deserialized, tapi tidak langsung disebut - tidak dengan kode saya, juga oleh perpustakaan deserialization. Jika Anda menggali lebih dalam ke sumbernya, Anda akan melihat bahwa pada tingkat rendah metode ini dipanggil secara internal melalui refleksi.sumber
Perl
Ini sangat mudah. Kode di bawah ini secara otomatis menjalankan kode dalam subrutin, bahkan tanpa panggilan eksplisit.
Bahkan jika Anda batalkan komentar pada panggilan, itu masih akan dipanggil hanya sekali.
sumber