为什么这个内存地址有一个随机值? [英] Why does this memory address have a random value?

查看:754
本文介绍了为什么这个内存地址有一个随机值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在i386上运行的Linux:x86_64.I've写了件C code和我拆开它,以及读寄存器,了解程序组件是如何工作的。下面是我写我的C程序。

I am running linux on i386:x86_64.I've written a piece of c code and I've disassembled it as well as read the registers to understand how the program works in assembly. Below is my c program that I've written.

#include <unistd.h>
#include <string.h>
#include <stdio.h>

char *string_in = "Did not work";

int test(char *this){
    char sum_buf[6];
    strncpy(sum_buf,this,32);
    return 0;
}

int hello(){
    printf("hello man");
    string_in = "If this triggered, it means our shell code is working\n";
    while(1){
        printf("Worked!");
    }
    return 0;
}

int main(int argc, void **argv){
    test("\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x06\x06\x40\x00\x00\x00\x00\x00");//6f 73
    printf("My string is %s",string_in);
    return 0;
}

这件作品我的code,我一直在研究的是测试功能。当我拆开输出我的测试功能我得到...

The piece of my code that I've been examining is the test function. When I disassemble the output my test function I get ...

   0x00000000004005b4 <+0>:         push   %rbp
   0x00000000004005b5 <+1>:         mov    %rsp,%rbp
   0x00000000004005b8 <+4>:         sub    $0x20,%rsp
   0x00000000004005bc <+8>:         mov    %rdi,-0x18(%rbp)
   0x00000000004005c0 <+12>:        mov    %fs:0x28,%rax
=> 0x00000000004005c9 <+21>:        mov    %rax,-0x8(%rbp)
   0x00000000004005cd <+25>:        xor    %eax,%eax
   0x00000000004005cf <+27>:        mov    -0x18(%rbp),%rcx
   0x00000000004005d3 <+31>:        lea    -0x10(%rbp),%rax
   0x00000000004005d7 <+35>:        mov    $0x20,%edx
   0x00000000004005dc <+40>:        mov    %rcx,%rsi
   0x00000000004005df <+43>:        mov    %rax,%rdi
   0x00000000004005e2 <+46>:        callq  0x400490 <strncpy@plt>
   0x00000000004005e7 <+51>:        mov    $0x0,%eax
   0x00000000004005ec <+56>:        mov    -0x8(%rbp),%rdx
   0x00000000004005f0 <+60>:        xor    %fs:0x28,%rdx
   0x00000000004005f9 <+69>:        je     0x400600 <test+76>
   0x00000000004005fb <+71>:        callq  0x4004a0 <__stack_chk_fail@plt>
   0x0000000000400600 <+76>:        leaveq 
   0x0000000000400601 <+77>:        retq 

现在我的兴趣在于线474; 12>。从我的理解是指令告诉计算机取段寄存器%FS 的前28位,并将其放入%RAX 我的累加器。让我困扰的是,之前和执行该行后,我通过 P / X $ FS读寄存器%FS 这说明一个零值(甚至整个程序),从而%RAX 必须为零。然而,指令执行后,%RAX 不显示为零。实际上什么呢结果是一个随机数。然后,这个随机数被放在8字节之前%RBP (因为它本身是Little Endian),然后在情况再次检查有过流缓冲区已覆盖了空间。

Now my interest lies in line <12>. From my understanding that instruction is telling the computer to take the first 28 bits of the segment register %fs and place it into %rax my accumulator. What bothers me is that before and after this line is executed, I read the register %fs via p/x $fs which shows a value of zero ( even throughout the program ) and thus %rax must be zero. However %rax does not show zero after the instruction has been executed. In fact what does result is a random number. This random number is then placed 8 bytes before %rbp (since it is little endian) and then checked again in case there is a buffer over flow that has overwritten that space.

我想知道的是什么 MOV%FS:0x28,RAX%真正要做的事。有我的理解是正确的?为什么我阅读%FS零 P / X $ FS时?如何读取正确的价值?

What I would like to know is what mov %fs:0x28,%rax is really doing. Have I understood it right? Why am I reading zero for %fs when in p/x $fs and how do I read the correct value?

推荐答案

在x86_64的,分段寻址不再使用,但无论是 FS GS 寄存器可以访问特殊的操作系统数据结构被用作碱指针地址。所以你看到的是一个在从保存的值偏移加载值 FS 注册,而内容不位操作的 FS 寄存器。

On x86_64, segmented addressing is no longer used, but the both the FS and GS registers can be used as base-pointer addresses in order to access special operating system data-structures. So what you're seeing is a value loaded at an offset from the value held in the FS register, and not bit manipulation of the contents of the FS register.

具体是怎么发生的,就是 FS:0x28 在Linux上存储一个特殊的定点堆栈后卫值,code正在执行堆栈后卫检查。例如,如果你在你的code看得更远,你会看到,在值 FS:0x28 被存储在堆栈上,然后的内容一叠召回和 XOR 与在原值进行FS:0x28 。如果这两个值相等,这意味着零位已定,因为 XOR ING两个零值相同的值的结果,那么我们就跳到在测试常规,否则我们跳转到一个特殊功能,表明堆栈在某种程度上破坏,并存储在堆栈上的标记值发生了变化。

Specifically what's taking place, is that FS:0x28 on Linux is storing a special sentinel stack-guard value, and the code is performing a stack-guard check. For instance, if you look further in your code, you'll see that the value at FS:0x28 is stored on the stack, and then the contents of the stack are recalled and an XOR is performed with the original value at FS:0x28. If the two values are equal, which means that the zero-bit has been set because XOR'ing two of the same values results in a zero-value, then we jump to the test routine, otherwise we jump to a special function that indicates that the stack was somehow corrupted, and the sentinel value stored on the stack was changed.

这篇关于为什么这个内存地址有一个随机值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆