一個有趣的C語言程式,誰說程式員不懂浪漫

來源:互聯網
上載者:User

瀏覽看雪論壇,發現有人講了一個有趣的C語言程式。

原帖地址:http://bbs.pediy.com/showthread.php?p=389887

我做了一點點的修改,最後列印出 i O y(中間那個是個心的形狀,運行程式就知道了)

#include <stdio.h>int main(){    const short int c1 = 49920;    const int c2 = 1073742008;    int (*pf)() = (int (*)())&c2;     printf("%c %c %c\n", *((char*)pf()+1)-0x11,*(char*)pf()-0x4a, *((char*)pf()+1)-0x1);    return   0; }

這兩句代碼:

const short int c1 = 49920;const int c2 = 1073742008;

定義了兩個局部變數,數值轉換成16進位為:

const short int c1 = 0xc300;const int c2 = 0x400000b8;

其中變數c1的地址為:0x0012FF44 ,佔兩個位元組,c2的地址為:0x0012FF40,佔四個位元組。

這兩個變數佔據了連續的空間。變數賦值後,從0x12fff40開始的記憶體單中繼存放區的位元組碼為:B8 00 00 40 00 C3 。對應的彙編碼是:

 mov         eax,400000h ret

用OD試試,輸入二進位代碼或者彙編代碼就可以看到

接下來的這句:

int (*pf)() = (int (*)())&c2;

 定義了一個函數指標,參數為NULL,傳回值為int類型。 這個函數指標,指向上面的彙編碼(注意記憶體位址的順序)。這樣,後面執行pf(),就執行了這段彙編碼。

接下來,

printf("%c %c %c\n", *((char*)pf()+1)-0x11,*(char*)pf()-0x4a, *((char*)pf()+1)-0x1);

先看*(char*)pf()-0x11這個運算式, 執行了了pf指向的彙編代碼,從彙編代碼看,這個函數調用後的傳回值是0x400000,pf()前面的char *是把函數的傳回值轉換成一個char*型指標,這個指標指向0x400000,前面再加個*號,表示取0x400000地址的內容,由於是char *型指標,因此從這個地址取一個位元組。
*(char*)pf()-0x11 表示的是從0x400000取出的位元組內容再減去0x11。

熟悉PE檔案結構的朋友一定知道,對於exe檔案0x400000是記憶體載入的基地址。也就是說,0x400000 位元組的內容對應的是0x4D,0x400001 位元組的內容對應的是0x5A.
這是我們常說的pe檔案起始的兩個位元組,"MZ"。這樣,運算式*(char*)pf()-*就可以隨意修改了。

送給女朋友做個禮物吧。

沒事的時候可以瀏覽些論壇,經常能發現一些很多有趣的東西,很多時候這些不經意的發現,往往增加了生活的樂趣。這個文章比較早了,一開始看到這個程式也沒想明白,看了一下解釋才豁然開朗,當然這種代碼在實際中是不可能使用的,不過我倒是很喜歡搜集這些稀奇古怪的小代碼,平添了生活的樂趣。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.