为什么我不能使用内存地址设置断点

时间:2018-01-26 03:38:17

标签: c gcc assembly compilation x86-64

当我遇到x68_64 bufferOverFlows的本教程时,我正在学习汇编处理器架构和利用开发,所以我复制了漏洞代码并使用gcc编译它。我编译的二进制文件不允许我设置断点,但是当我从网站下载二进制文件时("我不想这样做")它工作正常,内存地址正常

但是当我使用gdb在我的编译程序中转储main时,我的内存地址如下所示:     0x000000000000085e< + 83>:lea -0xd0(%rbp),%rax

function update(id)
          {
              var list_id = [];
              $("#id:checked").each(function() {
                      list_id.push(parseInt(this.value));
              });
          console.info(JSON.stringify(list_id));

              if(list_id.length > 0)
              {
                  if(confirm('Are you sure update this '+list_id.length+' data?'))
                  {
                      $.ajax({
                          type: 'POST',
                          data: {'devid_auto': list_id},
                          url: '<?php echo site_url('setting/mesin_update')?>',
                          success: function(result)
                          {
                              var hasil = result.replace(/\s/g,'');
                              if(hasil == 'y')
                              {
                                alert("Data Berhasil di Update");
                                location.reload();
                              }
                              else
                              {
                                  alert('Failed.');
                              }

                          },
                          error: function (jqXHR, textStatus, errorThrown)
                          {
                              alert('Error update data');
                          }
                      });
                  }
              }
              else
              {
                  alert('no data selected');
              }

          }

当我尝试在scanf函数之后设置Break poing时:     (gdb)break * 0x000000000000085e     断点1在0x85e     (gdb)运行

End of assembler dump.

1 个答案:

答案 0 :(得分:2)

您可以在虚拟地址上设置断点,但objdump不知道PIE可执行文件将在何处映射到内存,因此它使用0作为基址。为简化操作,请禁用PIE(which your distro apparently enables by default)。据推测,您的教程是在此之前编写的。 使用gcc -fno-pie -no-pie -g foo.c -o foo 。然后,您在objdump -drwC -Mintel中看到的地址将与运行时地址匹配。

但IDK为什么要数字地址;使用b main并从那里单步执行。即使您遗漏-g,您仍然会有函数的符号名称。

要解决问题,请参阅Stopping at the first machine code instruction in GDBSet a breakpoint on GDB entry point for stripped PIE binaries without disabling ASLR

从可执行文件中获得正在运行的进程后,您可以p &maindisas main查找main的实际运行时地址。但请注意,gdb会禁用ASLR,因此如果您使用GDB中的代码地址来利用PIE可执行文件,那么在GDB下运行它们时工作。正常运行&#34;&#34;将随机化您的可执行文件映射的虚拟地址。 (这就是为什么我建议构建一个与位置相关的可执行文件)。但更可能的是你只想在可执行堆栈上返回可执行代码,在这种情况下它的堆栈ASLR很重要,而堆栈ASLR仍然发生在普通的旧位置相关的可执行文件中(除非你也禁用它,比如gdb确实)。