【问题标题】:Why does initializing a string in a function doesn't work like int while debugging为什么在调试时在函数中初始化字符串不像 int 那样工作
【发布时间】:2016-09-15 11:58:15
【问题描述】:

所以我今天尝试调试一些简单的 C 程序;

第一个是

int main(){

 int a ,b ;
 return 0 ;

}

反编译时给了我

  push        ebp  
  mov         ebp,esp  
  sub         esp,008h 

因为我需要 8 个字节将 a 和 b 存储在当前堆栈帧中,因为它们是局部变量!

但是当我尝试对字符串进行相同操作时说

int main() {

    char greeting[12] = "Pwnit2Ownit";
    return 0;
}

反编译时给了我

 push        ebp  
  mov         ebp,esp  
  sub         esp,0DCh 

0DCh 是 220 , 但是由于字符串只有 12 个字节长,所以

sub esp,0DCh

sub esp,00ch

相反?

任何人都可以分享一些关于字符串如何存储在内存中并稍后通过程序集访问的链接 [preferebly instruction] ,例如如果字符串的长度很大,那么字符串问候语如何存储在内存中,因为我们无法将所有内容都存储在堆栈本身

【问题讨论】:

  • @JoseManuelAbarcaRodríguez 这是关于 C 的,不确定链接的问题是否有帮助...
  • 编译器处于防御状态。它为您的字符串分配了额外的 208 个字节,因此当您超出缓冲区时,它不会造成任何真正的损害。我感觉有一个编译器选项可以关闭该功能。
  • 在此处快速搜索[c] stack guard,出现this
  • 如果你什么都不定义怎么办?这个堆栈分配还会存在吗?也许您没有看对正确的东西...
  • 是的,即使我们没有 char var ='a' ;相反,我们只有 char var;子 esp,0cch ;声明和不声明

标签: c debugging visual-c++ assembly reverse-engineering


【解决方案1】:

正如@user3386109 指出的那样,问题是防止溢出,Visual Studio 中的默认安全检查已启用,它提供了额外的空间以防止溢出,因此将其关闭,使编译器仅分配 12 个字节:D

关闭此安全措施(缓冲区安全检查 GS) 项目设置 -> C/C++ -> 代码生成 -> 安全检查 = 禁用 GS

一些与GS相关的帖子

http://preshing.com/20110807/the-cost-of-buffer-security-checks-in-visual-c/

【讨论】:

  • 另请注意,如果您编写了const char *greeting = "a string literal";,则字符串文字将存储在可执行文件的只读部分中,并且该函数只会将指向它的指针存储在堆栈中。除非您需要修改字符串,否则只需使用指向它们的指针,而不是数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2014-06-09
  • 1970-01-01
  • 2011-11-01
  • 2015-02-09
  • 1970-01-01
相关资源
最近更新 更多