#2012_12_14 星期五 add by greshem
#现象: lcov 执行的时候 发现 ,
xxx.gcda:stamp mismatch with graph file ,
根据晚上的说法是 删除 gcno gcda 相关的文件, 重新生成 之后 还是一样.
最后生成的html , 里面显示的 代码覆盖率全部为0, 原因应该是 gcno gcda 两个文件的的时间戳不同 因为源码文件比较大, 导致连个文件 不在一秒之内生成吧.
########################################################################
#资源的目录 在 H:\sdb1\_xfile\2012_all_iso\_xfile_201212\gcov_bug_二进制_爆破_crack_代码覆盖率
########################################################################
#花费: 2h
#gcov 的版本是如下:
#gcov --version
#gcov (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
#Copyright (C) 2011 Free Software Foundation, Inc.
#
########################################################################
看 gcc-4.6.2 的代码 最后只是一个标记不同而已 , 不会太影响程序逻辑的 代码注释掉就可以了,
但是本来 gcc 的编译过程冗长 还不如 自己用二进制的方式 修改。
360 main (int argc, char **argv)
529 process_file (const char *file_name)
1035 read_count_file (void)
...
1068 tag = gcov_read_unsigned ();
1069 if (tag != bbg_stamp)
1070 {
1071 fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1072 goto cleanup;
1073 }
########################################################################
main
process_file
read_count_file
########################################################################
.text:0804C582 cmp ds:dword_80509FC, edx
.text:0804C588 jz short loc_804C5F0
.text:0804C58A mov eax, ds:dword_80509F4
.text:0804C58F mov edx, ds:stderr
.text:0804C595 mov [esp+8Ch+whence], eax
.text:0804C599 mov [esp+8Ch+off], offset aSStampMismatch ; "%s:stamp mismatch with graph file\n"
.text:0804C5A1 mov [esp+8Ch+ptr], edx
.text:0804C5A4 call cleanup
.text:0804C5A9
.text:0804C5A9 loc_804C5A9: ; CODE XREF: sub_804C430+43Dj
.text:0804C5A9 ; sub_804C430+6C8j ...
########################################################################
#
0804C599 C7 44 24 04 78 E1 04 08 89 14 24 E8 47 F3 FF FF
所有 最后就是要把 E8 47 F3 FF FF
nop 掉就可以了
其实地址是 08048A90
########################################################################
winhex 中寻找 E847F3FFFF , 确实可以找到 而且唯一.
生成了 gcov_nop 放到了 linux
objdump -d gcov > a
objdump -d gcov_no > b
########################################################################
#
#804c61f: 0f 84 33 05 00 00 je
if (tag != bbg_stamp)
.text:0804C6A7 mov eax, [esi+1Ch]
.text:0804C6AA lea edx, [eax+eax] ; Load Effective Address
.text:0804C6AD cmp edx, [esp+8Ch+var_60] ; Compare Two Operands
.text:0804C6B1 0f 85 1b 04 00 00 jnz loc_804CAD2 ; Jump if Not Zero (ZF=0)
0f 85 1b 04 00 00
修改成 0f84 1b 04 00 00
text:0804C561 loc_804C561: ; CODE XREF: sub_804C430+4C2j
.text:0804C561 mov eax, 1
.text:0804C566 call sub_804BA50 ; Call Procedure
.text:0804C56B xor edx, edx ; Logical Exclusive OR
.text:0804C56D test eax, eax ; Logical Compare
.text:0804C56F 74 11 jz short loc_804C582 ; Jump if Zero (ZF=1)
.text:0804C571 8b 2d 1c 0a 05 08 mov ebp, ds:dword_8050A1C
.text:0804C577 mov edx, [eax]
.text:0804C579 test ebp, ebp ; Logical Compare
.text:0804C57B mov edi, edx
.text:0804C57D bswap edi ; Swap bytes
.text:0804C57F cmovnz edx, edi ; Move if Not Zero (ZF=0)
.text:0804C582
.text:0804C582 loc_804C582: ; CODE XREF: sub_804C430+13Fj
.text:0804C582 cmp ds:dword_80509FC, edx ; Compare Two Operands
.text:0804C588 74 66 jz short loc_804C5F0 ; Jump if Zero (ZF=1)
.text:0804C58A a1 f4 09 05 08 mov eax, ds:dword_80509F4
.text:0804C58F mov edx, ds:stderr
.text:0804C595 mov [esp+8Ch+whence], eax
.text:0804C599 mov [esp+8Ch+off], offset aSStampMismatch ; "%s:stamp mismatch with graph file\n"
.text:0804C5A1 mov [esp+8Ch+ptr], edx
.text:0804C5A4 call cleanup ; Call Procedure
#最后确定下来 需要在 WINHEX 中 把 7466a1f4 替换成 7566a1f5 最后的在.text段中的偏移是 0704C588,对应汇编指令 jz 修改成 jnz
#来回折腾了好几个 4-5次 都弄错了. 修改汇编还是很麻烦的.
#
#
##############
最后发现 winhex 修改起来 太麻烦了, 写了一个 脚本, 输出PERL 的二进制, 然后执行下面的perl脚本又可以 生成 二进制文件. 修改起来方面 结合objdump -d 的方式 实现和winhex一样的功能了.
cat /bin/winhex_hexdump_edit.pl
#!/usr/bin/perl
my $input_file=shift or die("usage: $0 input_file \n");
my $perl_output=$input_file.".pl";
$perl_output=~s/\//_/g;
#生成的脚本里面的, 生成的二进制文件.
my $output_file_in_perl= $input_file.".bin";
$output_file_in_perl=~s/\//_/g;
if( -f $perl_output )
{
print "#[Warn]: $perl_output while be delete \n";
}
open(OUTPUT, "> $perl_output") or die("create file error \n");
print OUTPUT <
open(FILE, ">$output_file_in_perl");
binmode FILEHANDLE, ":raw";
my \$buffer=
EOF
;
#-A address 没有address 偏移地址.
#-t 每个字节 打印. 便于输出到per里面去.
open( PIPE, "od -An -t x1 $input_file -v |") or die(" open file error \n");
for()
{
chomp;
$_=~s/ /\\x/g;
print OUTPUT "\"$_\"\.\n";
}
print OUTPUT "\"\"\n";
print OUTPUT ";\n";
print OUTPUT <print FILE \$buffer;
close(FILE);
print "#$output_file_in_perl generated \\n";
EOF
;