在C中搜索和编辑值在当前过程的堆中
因此,在我们的大学作业中,我们被要求更改两个顺序printf(“%s”,s1)的输出; printf(“%s”,s2);
函数而无需触摸变量。目的是让我们在基于Linux的系统上使用该过程的内存布局的理论知识。
预期输出是针对第一个printf
调用以按空格拆分的S1和S2,以及第二次输出,以按原始应用程序预期保留。已知s1
和s2
的值和大小。
我最初的想法是malloc(0)
,并减去等于字符串长度的偏移量(块尺寸值+1),然后将其施放为char *。由于2个字符串值很小(绝对小于4KIB,这是页面大小),所以我希望只有一个分配给堆的区域,因此是线性的。
但是从看来我得到的值零值,这意味着我正在查看未命令的内存,或者我希望找到的字符串与众不同。
以下是所讨论的代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void heap_attack() {
// alternatively it can have signature of
// void heap_attack(void * v);
// but the task is assumed to be solvable with the original signature
}
int main(int argc, char const *argv[])
{
char * s1 = malloc(9);
char * s2 = malloc(9);
if (s1 == NULL || s2 == NULL) return EXIT_FAILURE;
strcpy(s1, "s0000000");
strcpy(s2, "s1111111");
heap_attack();
printf("student 1: %s\n", s1);
printf("student 2: %s\n", s2);
free(s1);
free(s2);
return 0;
}
我对HEAP_ATTACK
的实现开始如下:
void heap_attack() {
char * heap_end = malloc(0) - 1; // 1 for the size fragment preceding writable space
char * s1 = heap_end - 9;
printf("%s", s1); // here i expected to see the s1111111 string printed to stdout
}
So in our university assignment we were asked to change the output of two sequential printf("%s", s1); printf("%s", s2);
functions without touching the variables. The intent was for us to use the theoretical knowledge of the memory layout of the process on Linux based systems.
The expected output is for the first printf
call to output both s1 and s2 split by space(s), and for the output of the second to remain as intended by the original application. The values and sizes of s1
, and s2
are known.
My initial idea was to malloc(0)
and subtract the offset equal to the length of the string (+1 for the chunk size value) , and then cast that as a char *
. Since the 2 string values are very small (definitely less than 4KiB, which is the page size) I was hoping that there'd be just one region allocated for heap, and hence it is linear.
But from what it seems I get values of zero, which means I'm looking through an un-initialized memory, or something different then the strings I hoped to locate.
Below is the code in question:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void heap_attack() {
// alternatively it can have signature of
// void heap_attack(void * v);
// but the task is assumed to be solvable with the original signature
}
int main(int argc, char const *argv[])
{
char * s1 = malloc(9);
char * s2 = malloc(9);
if (s1 == NULL || s2 == NULL) return EXIT_FAILURE;
strcpy(s1, "s0000000");
strcpy(s2, "s1111111");
heap_attack();
printf("student 1: %s\n", s1);
printf("student 2: %s\n", s2);
free(s1);
free(s2);
return 0;
}
My implementation of the heap_attack
begins as follows:
void heap_attack() {
char * heap_end = malloc(0) - 1; // 1 for the size fragment preceding writable space
char * s1 = heap_end - 9;
printf("%s", s1); // here i expected to see the s1111111 string printed to stdout
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设您是使用GLIBC(最常见的设置)从事GNU/Linux的工作,那么您可以做出一些假设可以帮助您解决问题。
malloc()
呼叫没有任何free(Free()
在中间)将分配内存的连续块,因此第一个分配的字符串将会就在第二个之前。/lib/x86_64-linux-gnu/libc.so.6
将打印版本)。您也可以查看我的其他答案我简要地解释了malloc_chunk 。
2 * size_t
的倍数上。假设1和2(我们可以在此特定环境中再次做出)保证:
s2&gt; s1
(即s2
在s1
之后的内存中)(S2 -S1 -S1 -Strlen(S2)-1 在两个字符串之间的字节,除非
strlen(s2)
更改malloc(x)
, 否则此值不会更改。 /code>,并且始终在s2
的相同固定偏移量中,您可以轻松计算一次(假设s2
保持相同的长度)。帮助您找出所需的计算块的实际尺寸。 > sizeof(size_t)== 8 )。 /a>将为您提供确切的大小,不包括标题
。后来尝试释放(损坏的)块很可能会导致崩溃。在您的情况下,您可以完全避免
free()
完全不需要它。无论如何,操作系统都会在程序终止上回收内存。您的
heap_attack()
的可能实现是:Assuming that you are working on GNU/Linux using glibc, which is the most common setup, then you can make some assumptions that will help you solve the problem.
malloc()
calls without anyfree()
in the middle) will allocate contiguous chunks of memory, so the first allocated string will be right before the second./lib/x86_64-linux-gnu/libc.so.6
will print the version). You can also look at this other answer of mine where I briefly explain the internal layout of amalloc_chunk
.2 * size_t
.Assumptions 1 and 2 (which again we can make in this specific environment) guarantee that:
s2 > s1
(that is,s2
is in memory afters1
)(s2 - s1 - strlen(s2) - 1
bytes between the two strings, and this value will not change unlessstrlen(s2)
changes.malloc(x)
will be afters2
, and always at the same fixed offset froms2
, which you can easily calculate once and then use (assumings2
keeps the same length).Assumption 3 above will help you figure out the actual size of the chunks for the calculations you need. For
malloc(9)
the corresponding chunk (header included) would be 32 bytes (16 for header + 16 for data assumingsizeof(size_t) == 8
). Furthermoremalloc_usable_size()
will give you the exact size excluding the header.Filling up those bytes with spaces will accomplish what you wish for. However, in doing so, you will destroy the chunk header for
s1
, and any later attempt at freeing the (corrupted) chunk will most likely cause a crash. You can avoidfree()
altogether in your case since you don't really need it. The operating system will reclaim memory anyway on program termination.A possible implementation of your
heap_attack()
would be:如果我们选择堆解决方案:
And if we choose the heap solution: