【发布时间】:2019-09-11 13:06:13
【问题描述】:
我想在 C 中模拟一个向下增长的调用堆栈,并将以下内容压入堆栈:
这是我编写的测试代码,我只尝试推送字符串,字对齐,然后将地址推送到我刚刚推送的字符串:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
int main(){
/*Initialize stack */
size_t stack_size = (size_t) pow(2,10);
uint8_t *esp; /*Use byte-addressable stack pointer */
esp = (uint8_t *) malloc(stack_size);
esp += stack_size - 1; /*Set esp to top of allocated memory,
since stack grows downwards */
/* Parse the string into its tokens */
char s[] = "/bin/ls -l foo bar";
char *tokens[4];
char *token = strtok(s, " ");
int num_tokens = 0;
while (token != NULL)
{
tokens[num_tokens++] = token;
token = strtok(NULL, " ");
}
size_t esp_iter = 0; /*number of bytes pushed,
needed for word alignment */
char *stack_pointers[num_tokens]; /* Array to store addresses of
strings that were pushed */
/* Push the char arrays on the stack */
for (int j = 0; j < num_tokens; j++)
{
esp_iter += strlen(tokens[j]) + 1; /* +1 because of ‘\0’, which is
included in strncpy */
/* Address to store next string into */
char *next_pointer = (char *) ((uint8_t *) ( esp - esp_iter));
/* Store address in stack to which token j was pushed */
stack_pointers[j] = strncpy(next_pointer, tokens[j],
strlen(tokens[num_tokens]) + 1);
}
/* word aligning */
size_t pad = 4 - esp_iter % 4;
for (int j = 0; j < (int) pad; j++)
{
esp_iter += 1;
}
/* Push pointers to previously pushed strings */
for (int j = 0; j < num_tokens; j++)
{
esp_iter -= sizeof(char *);
/* Address on stack to store address of previously
pushed token to */
char *stack_pointer = (char *) (esp - esp_iter);
stack_pointer = (char *) stack_pointers[j];
}
return 0;
}
我想在字节级别上寻址堆栈,所以我使用 (uint8_t *) 作为堆栈指针。然后我应该能够在调用 strncpy.但是 strncpy 会产生分段错误,我不明白为什么。 我将内存从 0x7fc4c5001000 分配到 0x7fc4c50013ff。 Esp 设置为 0x7fc4c50013ff,然后我想例如将“bar”推入堆栈,因此我将堆栈指针(堆栈向低内存地址增长)递减 4,并使用目标地址 0x7fc4c50013fb 调用 strncpy,这应该有足够的空间来推这4个字符。为什么会出现段错误?
【问题讨论】:
-
您的代码可以真的使用一些间距...(和重新样式)。
-
我不需要完整阅读所有代码。我什至无法阅读它。我读了你的要求,如果它的格式正确并且提供了一个真正的minimal reproducible example,这很可能是一个很好的问题。向下投票箭头是有原因的。
-
此代码无法编译。我猜你在 main() 的某个地方错过了一个右括号
-
这一最新的编辑使代码的有效性和可构建性更低。请发布实际产生您所说的代码的代码。尽管有最新的变化,我已经回答了这个问题。您访问的范围超出了
tokens -
现在编辑了代码并修复了编译错误。很抱歉这个问题编辑得不好,希望现在至少可以阅读。