2012-11-19 16 views
4

我想用各種信息位「水印」一個C++二進制文件。在構建時包含這些信息很困難,因爲我不控制構建過程。到目前爲止,我唯一的想法是從here得到的,它是一個腳本,當它給出一個C++二進制文件時,會產生一個Bash腳本,如下所示。用位信息註釋一個C++二進制

簡而言之,它在原始二進制文件中附加了一個bash if-else,用於檢查第一個參數是否爲「--version」(在這種情況下是回聲信息)或不是(在這種情況下,它簡單地解碼爲文件「originalBinary」然後運行./originalBinary)。

這顯然是不理想的:

  • 我現在有二進制文件(這對於大型二進制文件可能會有問題)2份和
  • 過程運行由./originalBinary這是混淆了有人開始誰也不知道發生了什麼事情

什麼我不知道是我是否會能夠做到像有某種特殊exec $0更換./originalBinary電話,我可以人所以告訴exec不要從頭開始讀取文件,而是用100個字符的偏移量(或者開頭的Bash位的長度)。

另一個想法是讓Bash腳本自己編輯,即用sed刪除它的前21行,調用./$0來調用它自己,然後在./$0命令返回時附加if-else後面。然而,這看起來很脆弱(如果機器在通話返回之前崩潰,該怎麼辦?)。

最後,我得到的印象是,作爲連接器將通過在beginnig bash的東西被搞糊塗了,當它試圖加載庫:(

或者這將當二進制是一個共享資源失敗, ,你可以建議任何其他方式註釋一個C++二進制後構建?

我認爲準備一個具有所需信息的對象文件,而不是鏈接到給定的二進制文件,但這需要我以某種方式將ELF轉換回進入它的目標文件,將我的目標文件添加到列表中,然後重新鏈接(我從here得到印象,這可以用objcopy,但我還沒有設法得到這個工作)。此外,這種方法的問題在於,沒有好的方法來獲取信息,例如用「--version」調用二進制文件。

我試圖做什麼不可能?我希望我解釋清楚。

謝謝。

#!/bin/bash 

function PrintInformation() 
{ 
    echo "various bits of information" 
} 

if [[ $# -eq 1 && "$1" == "--version" ]]; then 
    PrintInformation 
    exit 0 
else 
    uudecode $0 
    ./originalBinary 
    exit 0 
fi 

begin 755 originalBinary 
M?T5,[email protected](!`0````````````(`/@`!````X`9```````!``````````'`1```` 
M`````````$``.``)`$``'@`;``8````%````0`````````!``$```````$`` 
M0```````^`$```````#X`0````````@``````````P````0````X`@`````` 
M`#@"0```````.`)````````<`````````!P``````````0`````````!```` 
M!0````````````````!``````````$```````*0*````````I`H````````` 
M`"````````$````&````\`T```````#P#6```````/`-8```````6`(````` 
M``"8`P``````````(````````@````8````@#@```````"`.8```````(`[email protected] 
M``````#``0```````,`!````````"``````````$````!````%0"```````` 
M5`)```````!4`D```````$0`````````1``````````$`````````%#E=&0$ 
M````L`D```````"P"4```````+`)0```````-``````````T``````````0` 
M````````4>5T9`8````````````````````````````````````````````` 
M````````````"`````````!2Y71D!````/`-````````\`[email protected]``````#P#6`` 
...............// my uuencode'd binary here 
end 
+1

你想對你的程序接受命令行參數? – andre

+1

這裏「註釋」是什麼意思?添加原始應用程序中不存在的cmd行參數?運送一個調用foo.bin的包裝腳本foo的問題在哪裏(如firefox et。al。這樣做)? – PlasmaHH

+0

命令行參數僅用於從二進制文件中獲取信息的便捷方式。通過「註釋」,我的意思是一個簡單的數據塊,比如生成日期和版本號。不幸的是,包裝腳本不是一個選項 - 它太侵入(必須堅持現狀) –

回答

1

可以使用了libelf,ELFsh或其他ELF工具來創建二進制自己的「節」,並把任何你在它想要的。 This question有更多的鏈接。如果全部您想要做的是將一個數據塊添加到二進制文件,則可能更容易使用objcopy - 添加段,比如answered here

+0

謝謝,我認爲這正是我所需要的。 –

0

這是一個黑客攻擊的一位,但你可以採取的方法是嵌入一個字符串,如這樣的:

static const char *version = "<<<VERSION-INFORMATION-HERE>>>"; 
在你的代碼

。必要時,您的程序可以打印出來。確保字符串足夠長,以容納真實版本信息所需的所有信息。然後,您可以編輯生成的二進制文件來覆蓋這個字符串你的「水印」這裏有一個(不是很漂亮,但功能),Perl腳本,它可以這樣做:

die "Usage $0 original-binary-file output-binary-file version-info" unless ($#ARGV == 2); 

$original = $ARGV[0]; 
$modified = $ARGV[1]; 
$new_version = $ARGV[2]; 
$version_magic = "<<<VERSION-INFORMATION-HERE>>>"; 

if (length($new_version) > length($version_magic)) { 
    die "$0: Length of version string '$new_version' must be less than that of '$version_magic'\n" 
} 
$new_version .= "\0" x (length($version_magic) - length($new_version)); 

open(IN, $original) 
    or die "\nCan't open $original for reading: $!\n"; 

open(OUT, ">$modified") 
    or die "\nCan't open $modified for writing: $!\n"; 

binmode IN; 
binmode OUT; 

my $buffer; 
my $size = -s $original; 

read(IN, $buffer, $size) 
    or die "$0: Failed to read $size bytes from $original: $!\n"; 

$buffer =~ s/\Q$version_magic\E/$new_version/; 

print OUT $buffer 
    or die "$0: Failed to write $size bytes to $modified: $!\n"; 

close IN 
    or die "$0: Can't close $original: $!\n"; 

close OUT 
    or die "$0: Can't close $modified: $!\n"; 

chmod 0755, $modified; 

print "Created $modified\n"; 
+0

謝謝。不幸的是,我無法訪問源代碼。這需要在完成後完成。 –