标签: aslr

德尔福的ASLR和DEP,怎么说?

来自http://blogs.msdn.com/b/michael_howard/archive/2007/04/04/codegear-s-new-delphi-2007-supports-aslr-and-nx.aspx,我正在使用{$ SETPEOPTFLAGS $ 140在程序名称下的项目文件中获取地址空间布局随机化(ASLR)和DEP.

如何判断PE中是否设置了标志?PeStudio似乎有信息,但似乎没有用.

谢谢.

delphi dep portable-executable aslr

5
推荐指数
1
解决办法
1126
查看次数

地址空间布局随机化(ALSR)和mmap

我希望由于地址空间布局随机化(ALSR),从另一个进程分叉的进程将在调用时返回不同的地址mmap.但正如我发现的那样,事实并非如此.为此目的,我做了以下测试程序.返回的所有地址malloc对于父级和子级完全相同.需要注意的是,malloc对于CL1,CL2,PL1,PL2在内部使用mmap,因为他们是大块.

所以,我的问题是,mmap即使存在ALSR ,为什么不返回不同的地址.也许是因为这里的随机种子对于原始和分叉过程是相同的.或者还有其他原因吗?

int main()
{
  pid = fork();

  if (pid == 0)                // child
  {
    void * c1 = malloc( 4096 );
    void * c2 = malloc( 4096 );

    void * cl1 = malloc( (long)512e3 ); // internally uses mmap
    void * cl2 = malloc( (long)512e3 ); // internally uses mmap

    printf( "c1 = %p, c2 = %p, cl1 = %p, …
Run Code Online (Sandbox Code Playgroud)

c linux gcc x86-64 aslr

5
推荐指数
2
解决办法
2072
查看次数

ELF,PIE ASLR以及介于两者之间的所有内容,特别是在Linux中

好吧,所以在问我的问题之前,我想介绍一些技术细节,我想确保我是正确的:

位置无关可执行文件 - PIE,是一个无论加载到哪个内存地址都能执行的代码,对吗?

ASLR ------地址空间布局随机化,几乎说明为了保持地址静态,我们会以某种方式随机化它们,

我已经在Linux和基于Unix的系统中特别阅读了实现ASLR是可能的,无论我们的代码是否是PIE,如果它是PIE,所有跳转,调用和偏移是相对的,因此我们没有问题如果不是,请编写一些如何无论代码是可执行的还是共享对象,都会被修改并编辑地址....

对......现在这让我提出几个问题

  1. 如果ASLR可以在不是PIE的代码中实现并且是可执行的并且不共享/可重定位对象(我知道重定位如何在可重定位的对象中工作!!!!)它是如何完成的?,elf格式应该没有任何部分说明代码部分中的函数是什么,所以内核加载器可以修改它,对吧?ASLR应该是内核功能,因此实际上可以是例如包含例如这些指令的可执行文件

    伪代码:

    inc_eax:
     add eax, 5
     ret
    
    main:
     mov eax, 5
     mov ebx, 6
     call ABSOLUTE_ADDRES{inc_eax}
    
    Run Code Online (Sandbox Code Playgroud)

    如果内核可执行加载器没有存储在elf文件中的某个可重定位表中并且不是相对的,以便将可执行文件加载到某个随机地址,那么内核可执行加载器如何知道如何更改地址?

  2. 假设我错了,为了实现ASLR,你必须有一个PIE可执行文件,所有段都是相对的,如何编译C++ OOP代码并使其工作,例如,如果我有一个类的实例使用指向其结构中的虚拟表的指针,并且该虚拟表应该保存绝对地址,因此我无法为使用运行时虚拟表的C++程序编译纯PIE,并且不能再使用ASLR. ...我怀疑虚拟表是否包含相对地址,并且对于某些虚拟函数的每次调用都会有不同的虚拟表...

  3. 我的最后一个也是最不重要的问题是关于ELF和PIE,是否有一些特殊的方法来检测ELF可执行文件是PIE?我对ELF格式很熟悉所以我怀疑它有一种方法但是我可能错了,无论如何如果没有办法,内核加载器如何知道我们的可执行文件是否是PIE,因此它可以在其上使用ASLR

我已经把这一切搞砸了,如果有人能在这里帮助我,我会很感激,感谢提前

linker compilation elf aslr

5
推荐指数
1
解决办法
7281
查看次数

如何找到PIE二进制文件的负载重定位?

我需要在运行的进程中获取堆栈的基地址。这将使我能够打印将由addr2line理解的原始堆栈跟踪(已剥离运行二进制文件,但addr2line可以访问符号)。我通过检查以下内容的elf标头成功做到了这一点argv[0]:我读取了入口点并将其从中减去&_start

#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
void* entry_point = NULL;
void* base_addr = NULL;
extern char _start;

/// given argv[0] will populate global entry_pont
void read_elf_header(const char* elfFile) {
  // switch to Elf32_Ehdr for x86 architecture.
  Elf64_Ehdr header;
  FILE* file = fopen(elfFile, "rb");
  if(file) {
    fread(&header, 1, sizeof(header), file);
    if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
        printf("Entry point from file: %p\n", (void *) header.e_entry);
        entry_point = (void*)header.e_entry;
        base_addr = …
Run Code Online (Sandbox Code Playgroud)

c linux elf aslr position-independent-code

5
推荐指数
2
解决办法
119
查看次数

微软的ASLR很奇怪

我观看了一个ASLRed dll图像基于32位进程的地址.
这不是完全随机化.它只是随机化了1/2概率.

例如,一旦我加载一个DLL,然后图像加载到0x12345678.
然后我再次加载图像,图像加载到0x23456789.(基地址已更改!)
但我再次加载图像
0x12345678
0x23456789
0x12345678
0x23456789

...

为什么他们这样实施?
它是否适用于崩溃报告的频率?(用于获取重新部署的dll的相同崩溃地址)

windows dll portable-executable aslr

4
推荐指数
1
解决办法
2065
查看次数

Linux上的堆栈的ASLR熵位

我正在看麻省理工学院的一个演示文稿,他们解释了不同类型的ASLR实现.

例如,他们指出对于静态ASLR,堆栈具有19位的熵.根据我的理解,这意味着堆栈基地址只能随机化以获取2 ^ 19个不同的值.

我想问一下如何计算堆栈有19位的熵?

编辑:

在线检查后,我在Linux上找到了堆栈ASLR的一些解释.从另一个问题中学习,我认为可能相关的代码是:

#ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))     /* 8MB of VA */
#endif

static unsigned long randomize_stack_top(unsigned long stack_top)
{
    unsigned int random_variable = 0;

    if ((current->flags & PF_RANDOMIZE) &&
            !(current->personality & ADDR_NO_RANDOMIZE)) {
            random_variable = get_random_int() & STACK_RND_MASK;
            random_variable <<= PAGE_SHIFT;
    }
#ifdef CONFIG_STACK_GROWSUP
    return PAGE_ALIGN(stack_top) + random_variable;
#else
    return PAGE_ALIGN(stack_top) - random_variable;
#endif
}
Run Code Online (Sandbox Code Playgroud)

我想问一下这是否适合推理我的问题?

linux stack 32-bit entropy aslr

4
推荐指数
1
解决办法
1352
查看次数

如果全局变量的地址被硬编码在 ELF 中,它们如何随机化?

我在几个地方读到过,.data每次程序运行时,ASLR 应该以随机地址加载该部分,这意味着全局变量的地址应该不同。但是,如果我有以下代码:

int global_var = 42;

int main()
{
    global_var = 10;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用 编译它gcc -fpie -o global global.cobjdump -d -M intel显示以下内容:

  4004ed:   55                      push   rbp
  4004ee:   48 89 e5                mov    rbp,rsp
  4004f1:   c7 05 3d 0b 20 00 0a    mov    DWORD PTR [rip+0x200b3d],0xa        # 601038 <global_var>
Run Code Online (Sandbox Code Playgroud)

它似乎global_var总是被放置在 601038。事实上,如果我用调试符号编译,global_var的 DIE 会硬编码该地址:

$ gcc -ggdb3 -fpie -o global global.c
$ objdump --dwarf=info global
...
<1><55>: Abbrev Number: 4 (DW_TAG_variable) …
Run Code Online (Sandbox Code Playgroud)

c elf dwarf aslr

4
推荐指数
2
解决办法
939
查看次数

地址规范形式和指针算术

在符合AMD64标准的体系结构中,地址需要在取消引用之前采用规范形式.

英特尔手册的3.3.7.1节:

在64位模式中,如果微架构的地址位63到最重要的实现位被设置为全1或全零,则认为地址是规范形式.

现在,当前操作系统和体系结构中最有意义的实现位是第47位.这给我们留下了48位的地址空间.

特别是当启用ASLR时,用户程序可能会收到第47位设置的地址.

如果使用指针标记等优化并且高位用于存储信息,则程序必须确保将第48位至第63位设置回取消引用地址之前的第47位.

但请考虑以下代码:

int main()
{
    int* intArray = new int[100];

    int* it = intArray;

    // Fill the array with any value.
    for (int i = 0; i < 100; i++)
    {
        *it = 20;
        it++;   
    }

    delete [] intArray;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在考虑的intArray是,说:

0000 0000 0000 0000 0 111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100

设置itintArray并增加it一次,并考虑sizeof(int) == …

x86-64 pointer-arithmetic access-violation aslr

4
推荐指数
1
解决办法
1539
查看次数

在 Linux 中如何确定 PIE 可执行文件的文本部分的地址?

首先,我尝试对其进行一些逆向工程:

printf '
#include <stdio.h>
int main() {
    puts("hello world");
}
' > main.c
gcc -std=c99 -pie -fpie -ggdb3 -o pie main.c
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
readelf -s ./pie | grep -E 'main$'
gdb -batch -nh \
  -ex 'set disable-randomization off' \
  -ex 'start' -ex 'info line' \
  -ex 'start' -ex 'info line' \
  -ex 'set disable-randomization on' \
  -ex 'start' -ex 'info line' \
  -ex 'start' -ex 'info line' \
  ./pie \
;
Run Code Online (Sandbox Code Playgroud)

输出:

64: 000000000000063a    23 …
Run Code Online (Sandbox Code Playgroud)

linux glibc linux-kernel aslr position-independent-code

4
推荐指数
1
解决办法
1427
查看次数

从进程内部查找映射内存

设置:

  • 乌班图18x64
  • x86_64 应用程序
  • 从应用程序内部执行任意代码

我正在尝试编写即使启用 ASLR 也应该能够在内存中找到结构的代码。遗憾的是,我找不到对这些区域的任何静态引用,所以我猜我必须使用暴力方式并扫描进程内存。我试图做的是扫描应用程序的整个地址空间,但这不起作用,因为某些内存区域未分配,因此SIGSEGV在访问时会产生收益。现在我认为最好getpid()使用 pid 来访问/proc/$PID/maps并尝试从那里解析数据。

但我想知道,是否有更好的方法来识别分配的区域?也许甚至是一种不需要我访问 libc (= getpid, open, close) 或摆弄字符串的方法?

c linux memory x86-64 aslr

4
推荐指数
1
解决办法
2312
查看次数