如何调试用GDB执行bash shell脚本的C程序?

时间:2017-12-24 15:28:03

标签: c linux gdb

我使用-g 386共享--prefix = / usr选项(使用基本程序集版本)构建OpenSSL-1.0.2n以生成共享库libcrypto.so.1.0.0。

在crypto / aes文件夹中,生成aes-x86_64.s。

要执行AES加密和解密,我在linux终端中使用了以下命令。

/usr/bin/openssl enc -aes-128-cbc -in secrets.txt -out cipher.bin
/usr/bin/openssl enc -d -aes-128-cbc  -in cipher.bin -out decrypt_cip2.txt 

使用GDB,我可以调试上述命令的执行,如下所示

gdb openssl

gdb> set args enc -d -aes-128-cbc  -in cipher.bin -out decrypt_cip2.txt 
gdb> b AES_cbc_encrypt
gdb> run
Breakpoint 1, AES_cbc_encrypt () at aes-x86_64.s:1300
1300        cmpq    $0,%rdx

从上面的gdb调试输出中,验证了 aes-x86_64.s文件 AES_cbc_encrypt 函数被调用。

我需要验证,如果我使用的是使用系统调用执行bash脚本来执行AES解密的C程序, AES_cbc_encrypt 函数aes-x86_64.s文件仍在调用?

//test.c
    #include <stdio.h>
    #include <stdlib.h> 

    int main()
    {
    char cmd[500];
    sprintf(cmd, "/usr/bin/openssl enc -d -aes-128-cbc  -in cipher.bin -out decrypt_cip2.txt ");
    system(cmd);
    return 0;
      }
    gcc test.c -o test
    ./test

我是错的,如果我说当我执行这个C程序时,它间接调用openssl库(libcrypto.so)并执行解密。所以它必须调用aes-x86_64的AES_cbc_encrypt函数。 o文件。

但是,当我使用GDB调试此程序时,它没有显示对aes-x86_64.o文件的AES_cbc_encrypt函数的任何调用。它只是调用/ sysdeps / posix / system。 c,/ sysdeps / unix / sysv / linux / x86_64 / trust.c等。

gdb test

gdb> b AES_cbc_encrypt
Function "AES_cbc_encrypt" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (AES_cbc_encrypt) pending.

所以,这是我的问题

  1. 如何使用gdb调试上面的C代码,以便它在已安装的OpenSSL的断点AES_cbc_encrypt处停止?

  2. 我是否应该在C程序中使用非系统调用来运行那些bash命令,以确保间接调用 aes-x86_64.s文件 AES_cbc_encrypt 功能?

  3. 任何帮助或链接来解决这个问题都会非常明显。

    我在OpenSSL版本1.0.2n中使用Ubuntu 16.04,带有调试符号的gcc-7.0。

1 个答案:

答案 0 :(得分:1)

  

但是,当我使用GDB调试此程序时,它没有显示对aes-x86_64.o文件的AES_cbc_encrypt函数的任何调用。它只是调用/sysdeps/posix/system.c

默认情况下,GDB只调试一个进程(test程序)并且该进程不调用AES_cbc_encrypt - 而是创建一个新进程 - $SHELL,其中turn创建另一个进程 - /usr/bin/openssl,只有那个孙进程调用AES_cbc_encrypt

由于您正在调试openssl的祖父母,因此完全预期 GDB没有观察到AES_cbc_encrypt被链接到您 的过程中>调试,AES_cbc_encrypt上的断点永远不会建立,也不会“触发”。

  

如何使用gdb调试上述C代码,以便在安装的OpenSSL的断点AES_cbc_encrypt处停止?

有几种方法:

  1. 一种方法是修改test,使其调用gdb而不是调用openssl

    sprintf(cmd, "gdb --args /usr/bin/openssl enc -d -aes-128-cbc -in cipher.bin -out decrypt_cip2.txt"); system(cmd);

  2. 如果您不能或不想修改test程序,可以将/usr/bin/openssh重命名为/usr/bin/openssl.exe并将shell包装器放入/usr/bin/openssl }:

    #!/bin/sh exec gdb --args /usr/bin/openssl.exe "$@"

  3. 如果您不想执行上述任何一项,您可以使用GDB多次低级支持。文档herehere

  4. <强>更新

      

    我有点想知道它将如何执行.exe文件

    UNIX系统不关心文件扩展名(它们看起来文件内部,即在文件内容中,以找出如何运行它)。

    因此,您可以将可执行文件重命名为所需的任何openssl.fooopenssl.baropenssl.exeopenssl.orig等等仍然会正确运行。