如何编译 C 程序,使二进制文件仅在 return 值不同?
How to compile C programs such that binaries differ only in different return value?
如果您编译两个仅 return 值不同的 C 程序,我希望二进制文件仅在此值的位上不同。但是,如果我使用 GCC 编译以下程序,转储二进制文件的位(使用 xxd)并对转储进行 diff,我会得到另一个不同之处。
文件
return127.c
int main() {
return 127;
}
return128.c
int main() {
return 128;
}
编译、转储和比较
# compile
gcc -Os -fdata-sections -ffunction-sections -fipa-pta -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all return127.c -o return127
gcc -Os -fdata-sections -ffunction-sections -fipa-pta -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all return128.c -o return128
# dump
xxd -b return127 > return127.xxd-bits
xxd -b return128 > return128.xxd-bits
# diff
diff return127.xxd-bits return128.xxd-bits
注:我用的编译命令评论一个C程序最小二进制的问题
差异
108,111c108,111
< 00000282: 01010101 00000000 01101011 11011010 11101100 11100011 U.k...
< 00000288: 00111010 10001111 00101111 00101100 01100001 00111100 :./,a<
< 0000028e: 10010010 11001011 00011000 11101010 11100111 00100011 .....#
< 00000294: 01001010 00111011 11111001 11111010 00000001 00000000 J;....
---
> 00000282: 01010101 00000000 00011101 11000011 10101000 00011001 U.....
> 00000288: 11011011 00110001 10100000 01001101 01000110 10010011 .1.MF.
> 0000028e: 00101101 01011101 11101001 00001000 01010101 11111101 -]..U.
> 00000294: 11011011 01000011 11010100 10101011 00000001 00000000 .C....
211c211
< 000004ec: 00000000 00000000 00000000 00000000 10111000 01111111 ......
---
> 000004ec: 00000000 00000000 00000000 00000000 10111000 10000000 ......
有两个区别。底部的差异显示 return 值的(预期)差异。这些行仅在最后 byte/block 处不同。二进制 01111111
是十进制 127
。二进制 10000000
是十进制 128
.
上面有什么区别?
What is the difference at the top?
这是构建 ID 的差异。安装 diffoscope
(或比较两个库的 readelf --wide --notes
输出),您会很好地看到:
│ Displaying notes found in: .note.gnu.build-id
│ Owner Data size Description
│ - GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 817d41c45a09c3822337307250bdb9410a1959b4
│ + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: de5fb81907549af3332e8136d6bd7ab4d884e0ce
How to compile C programs such that binaries differ only in different return value?
- 你必须在两个 gcc 上同时设置
__TIME__
和 __DATE__
。
- 您必须为这两个调用创建唯一的构建 ID。
以下脚本:
export SOURCE_DATE_EPOCH=$(date +%s)
f() {
gcc -Wl,--build-id=none \
-Os -fdata-sections -ffunction-sections -fipa-pta \
-Wl,--gc-sections -Wl,--as-needed -Wl,--strip-all \
-xc - -o ""
}
echo 'main(){return 127;}' | f /tmp/1
echo 'main(){return 128;}' | f /tmp/2
diffoscope /tmp/1 /tmp/2
和diffoscope
输出:
│ 0000000000001020 <.text>:
│ - mov [=12=]x7f,%eax
│ + mov [=12=]x80,%eax
│ retq
如果您编译两个仅 return 值不同的 C 程序,我希望二进制文件仅在此值的位上不同。但是,如果我使用 GCC 编译以下程序,转储二进制文件的位(使用 xxd)并对转储进行 diff,我会得到另一个不同之处。
文件
return127.c
int main() {
return 127;
}
return128.c
int main() {
return 128;
}
编译、转储和比较
# compile
gcc -Os -fdata-sections -ffunction-sections -fipa-pta -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all return127.c -o return127
gcc -Os -fdata-sections -ffunction-sections -fipa-pta -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all return128.c -o return128
# dump
xxd -b return127 > return127.xxd-bits
xxd -b return128 > return128.xxd-bits
# diff
diff return127.xxd-bits return128.xxd-bits
注:我用
差异
108,111c108,111
< 00000282: 01010101 00000000 01101011 11011010 11101100 11100011 U.k...
< 00000288: 00111010 10001111 00101111 00101100 01100001 00111100 :./,a<
< 0000028e: 10010010 11001011 00011000 11101010 11100111 00100011 .....#
< 00000294: 01001010 00111011 11111001 11111010 00000001 00000000 J;....
---
> 00000282: 01010101 00000000 00011101 11000011 10101000 00011001 U.....
> 00000288: 11011011 00110001 10100000 01001101 01000110 10010011 .1.MF.
> 0000028e: 00101101 01011101 11101001 00001000 01010101 11111101 -]..U.
> 00000294: 11011011 01000011 11010100 10101011 00000001 00000000 .C....
211c211
< 000004ec: 00000000 00000000 00000000 00000000 10111000 01111111 ......
---
> 000004ec: 00000000 00000000 00000000 00000000 10111000 10000000 ......
有两个区别。底部的差异显示 return 值的(预期)差异。这些行仅在最后 byte/block 处不同。二进制 01111111
是十进制 127
。二进制 10000000
是十进制 128
.
上面有什么区别?
What is the difference at the top?
这是构建 ID 的差异。安装 diffoscope
(或比较两个库的 readelf --wide --notes
输出),您会很好地看到:
│ Displaying notes found in: .note.gnu.build-id
│ Owner Data size Description
│ - GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 817d41c45a09c3822337307250bdb9410a1959b4
│ + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: de5fb81907549af3332e8136d6bd7ab4d884e0ce
How to compile C programs such that binaries differ only in different return value?
- 你必须在两个 gcc 上同时设置
__TIME__
和__DATE__
。 - 您必须为这两个调用创建唯一的构建 ID。
以下脚本:
export SOURCE_DATE_EPOCH=$(date +%s)
f() {
gcc -Wl,--build-id=none \
-Os -fdata-sections -ffunction-sections -fipa-pta \
-Wl,--gc-sections -Wl,--as-needed -Wl,--strip-all \
-xc - -o ""
}
echo 'main(){return 127;}' | f /tmp/1
echo 'main(){return 128;}' | f /tmp/2
diffoscope /tmp/1 /tmp/2
和diffoscope
输出:
│ 0000000000001020 <.text>:
│ - mov [=12=]x7f,%eax
│ + mov [=12=]x80,%eax
│ retq