Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译后如何计算某个二进制函数(或基本块)的校验和?_C++_Security_Binary_X86_Obfuscation - Fatal编程技术网

C++ 编译后如何计算某个二进制函数(或基本块)的校验和?

C++ 编译后如何计算某个二进制函数(或基本块)的校验和?,c++,security,binary,x86,obfuscation,C++,Security,Binary,X86,Obfuscation,我想编写一些简单的防篡改机制,在运行时计算某个函数(或基本块)的校验和,并将其与固定的预计算值进行比较。如果校验和匹配,则一切正常;否则程序将终止 我可以在运行时轻松地计算校验和,但我不知道如何计算固定值进行比较 我想我必须在编译后对二进制文件进行一些后处理,因为在编译时不可能知道校验和(对吧?) 但是,如何在与我的函数(或基本块)相对应的二进制代码中定位代码点呢?我可以使用一些十六进制编辑器手动完成这项工作,但我想自动化这个过程。在预先计算校验和之后,我需要修改二进制文件以包含它-但这同样需要

我想编写一些简单的防篡改机制,在运行时计算某个函数(或基本块)的校验和,并将其与固定的预计算值进行比较。如果校验和匹配,则一切正常;否则程序将终止

我可以在运行时轻松地计算校验和,但我不知道如何计算固定值进行比较

我想我必须在编译后对二进制文件进行一些后处理,因为在编译时不可能知道校验和(对吧?)

但是,如何在与我的函数(或基本块)相对应的二进制代码中定位代码点呢?我可以使用一些十六进制编辑器手动完成这项工作,但我想自动化这个过程。在预先计算校验和之后,我需要修改二进制文件以包含它-但这同样需要能够在二进制文件中找到正确的位置


对解决方案有什么建议吗?

例如,您可以获得一个指向函数的指针,并将其重新解释为uint8\t数组。若不希望编译器在某个循环中使用该函数的内联副本,也可以禁用该函数的内联

uint8_t* pMain = (uint8_t*)&main;

然后,您必须尝试估计函数长度并计算校验和。

例如,您可以获得一个指向函数的指针,并将其重新解释为uint8\t数组。若不希望编译器在某个循环中使用该函数的内联副本,也可以禁用该函数的内联

uint8_t* pMain = (uint8_t*)&main;

然后,您必须尝试估计函数长度并计算校验和。

如果您的代码由多个文件组成,您可以使用以下机制:

  • 使用将来要检查的函数编译文件

  • 定位于编译文件(最有可能是.o、.obj)函数位置-例如使用objdump或类似工具-它必须显示人类可读的文本以及编译代码的十六进制代码

  • 例如:

    objdump a.o-d--insn宽度=10

    40064b:48 89 e5 mov%rsp%rbp
    40064e:ff d0 callq*%rax
    400650:5d pop%rbp
    400651:e9 7a ff ff jmpq 4005d0
    0000000000400656 :
    400656:55%按需付费
    400657:48 89 e5 mov%rsp,%rbp
    40065a:89 7d ec mov%edi,-0x14(%rbp)
    40065d:48 89 75 e0 mov%rsi,-0x20(%rbp)
    400661:8b 05 f9 09 20 00 mov 0x2009f9(%rip),%eax#601060
    400667:89 c2 mov%eax,%edx
    400669:48 8b 45 e0 mov-0x20(%rbp),%rax
    40066d:89 10 mov%edx,(%rax)
    40066f:48 8b 45 e0 mov-0x20(%rbp),%rax
    400673:48 83 C004添加$0x4,%rax
    400677:c7 00 01 00动产$0x1,(%rax)
    40067d:c7 45 fc 00移动$0x0,-0x4(%rbp)
    400684:eb 72 jmp 4006f8
    400686:83 7d fc 01 cmpl$0x1,-0x4(%rbp)
    40068a:75 1c jne 4006a8
    40068c:8b 45 fc mov-0x4(%rbp),%eax
    40068f:48 98 cltq
    
    因此,在objdump的情况下,函数名将被上面的计算函数示例包围

  • 编写脚本来解析它-在地址和反汇编代码之间需要十六进制代码

  • 计算您的CRC、哈希或您需要的任何内容

  • 存储CRC以及块长度,以便稍后在运行时将其解码到一个文件中,该文件也将被编译-当然,您需要知道映射哪个变量/常量保存哪个函数CRC

  • 链接所有文件

  • 如果单个文件可用(完整的可执行文件),您可以:

  • 在源代码中定义常量/静态以保存CRC
  • 如上所述进行CRC计算
  • 在二进制文件中找到您的var位置(在.data或.rodata节中)并更新它
  • 很可能您也需要修复可执行CRC
    如果代码由多个文件组成,则可以使用以下机制:

  • 使用将来要检查的函数编译文件

  • 定位于编译文件(最有可能是.o、.obj)函数位置-例如使用objdump或类似工具-它必须显示人类可读的文本以及编译代码的十六进制代码

  • 例如:

    objdump a.o-d--insn宽度=10

    40064b:48 89 e5 mov%rsp%rbp
    40064e:ff d0 callq*%rax
    400650:5d pop%rbp
    400651:e9 7a ff ff jmpq 4005d0
    0000000000400656 :
    400656:55%按需付费
    400657:48 89 e5 mov%rsp,%rbp
    40065a:89 7d ec mov%edi,-0x14(%rbp)
    40065d:48 89 75 e0 mov%rsi,-0x20(%rbp)
    400661:8b 05 f9 09 20 00 mov 0x2009f9(%rip),%eax#601060
    400667:89 c2 mov%eax,%edx
    400669:48 8b 45 e0 mov-0x20(%rbp),%rax
    40066d:89 10 mov%edx,(%rax)
    40066f:48 8b 45 e0 mov-0x20(%rbp),%rax
    400673:48 83 C004添加$0x4,%rax
    400677:c7 00 01 00动产$0x1,(%rax)
    40067d:c7 45 fc 00移动$0x0,-0x4(%rbp)
    400684:eb 72 jmp 4006f8
    400686:83 7d fc 01 cmpl$0x