2011-04-01 40 views
0

字符串我有如下一個非常簡單的程序: 的#include查找在編譯的可執行

int main(){ 
char* mystring = "ABCDEFGHIJKLMNO"; 
puts(mystring); 

char otherstring[15]; 
otherstring[0] = 'a'; 
otherstring[1] = 'b'; 
otherstring[2] = 'c'; 
otherstring[3] = 'd'; 
otherstring[4] = 'e'; 
otherstring[5] = 'f'; 
otherstring[6] = 'g'; 
otherstring[7] = 'h'; 
otherstring[8] = 'i'; 
otherstring[9] = 'j'; 
otherstring[10] = 'k'; 
otherstring[11] = 'l'; 
otherstring[12] = 'm'; 
otherstring[13] = 'n'; 
otherstring[14] = 'o'; 
puts(otherstring); 

return 0; 
} 

編譯器爲MS VC++。

我是否使用或不使用優化來構建此程序我可以使用十六進制編輯器在可執行文件中找到字符串「ABCDEFGHIJKLMNO」。

但是,什麼是編譯器這樣做是otherstring不同,我不能找到字符串「ABCDEFGHIJKLMNO」

我使用的十六進制編輯器是Hexedit - 但嘗試了其他人,仍然無法找到otherstring。任何人有任何想法爲什麼不或如何找到?

順便說一下,我不是因爲黑客的原因這樣做。

+0

你能找到字符串 「\ X00 \ X00 \ x00b \ X00 \ X00 \ x00c \ X00 \ X00 \ X00」 中的二進制文件(使用4個字節的每一個字母)? – pmg 2011-04-01 11:38:00

+0

$ strings binary-file | grep「ABCDEFGHIJKLMNO」 – Chappelle 2012-02-21 14:13:51

回答

5

這是我的gcc用這段代碼所做的。我假設你的編譯器做了類似的事情。字符串常量存儲在只讀部分,mystring用它的地址初始化。
各個字符都直接放置在堆棧的陣列位置。還要注意的是,當你調用puts時,其他字符串不會被NULL終止。

  .file "test.c" 
      .section  .rodata 
    .LC0: 
      .string "ABCDEFGHIJKLMNO" 
      .text 
    .globl main 
      .type main, @function 
    main: 
    .LFB0: 
      .cfi_startproc 
      pushq %rbp 
       .cfi_def_cfa_offset 16 
      movq %rsp, %rbp 
      .cfi_offset 6, -16 
      .cfi_def_cfa_register 6 
      subq $48, %rsp 
      movq %fs:40, %rax 
      movq %rax, -8(%rbp) 
      xorl %eax, %eax 
    /* here is where mystring is loaded with the address of "ABCDEFGHIJKLMNO" */ 
      movq $.LC0, -40(%rbp) 
    /* this is the call to puts */ 
       movq -40(%rbp), %rax 
      movq %rax, %rdi 
      call puts 
    /* here is where the bytes are loaded into otherstring on the stack */    
      movb $97, -32(%rbp) //'a' 
      movb $98, -31(%rbp) //'b' 
      movb $99, -30(%rbp) //'c' 
      movb $100, -29(%rbp) //'d' 
      movb $101, -28(%rbp) //'e' 
      movb $102, -27(%rbp) //'f' 
      movb $103, -26(%rbp) //'g' 
      movb $104, -25(%rbp) //'h' 
      movb $105, -24(%rbp) //'i' 
      movb $106, -23(%rbp) //'j' 
      movb $107, -22(%rbp) //'k' 
      movb $108, -21(%rbp) //'l' 
      movb $109, -20(%rbp) //'m' 
      movb $110, -19(%rbp) //'n' 
      movb $111, -18(%rbp) //'o' 
1

編譯器可能會將每個字符的編號放在每個數組中,就像您編寫它時一樣,沒有通過閱讀代碼可以找到任何優化。請記住,單個字符與c中的數字沒有區別,因此您甚至可以使用ascii代碼而不是'a'。我希望你會看到那些轉換回來的字母,只是間隔一點。

1

在第一種情況下,編譯器用確切的字符串「ABC ...」初始化數據。

在第二種情況下,每個分配都是按順序完成的,因此編譯器會生成代碼來執行此分配。在可執行文件中,您應該看到15個重複字節序列,其中只有初始化程序('a','b','c'...)發生更改。

+1

換句話說,字符直接放置在生成的機器碼中。 – 2011-04-01 14:35:22