繁体   English   中英

汇编中的跳转指令如何与多个进程一起工作?

[英]How does the jump instruction in assembly work with multiple processes?

所以,我对跳转指令在操作系统中的工作原理感到困惑。 我认为跳转指令设置处理器程序计数器中的值。 但程序可以在内存中的不同位置运行。 我在x86中看到,有JMP EAX指令,但我的C ++代码似乎没有使用它。 我在VC ++中编译了一些C ++代码:

int main()
{
    int i = 0;
    while (i < 10)
    {
        ++i;
        if (i == 7)
        {
            i += 1;
            continue;
        }
    }
}

这意味着:

    int main()
    {
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0CCh 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0CCh] 
00411382  mov         ecx,33h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
        int i = 0;
0041138E  mov         dword ptr [i],0 
        while (i < 10)
00411395  cmp         dword ptr [i],0Ah 
00411399  jge         main+47h (4113B7h) 
        {
            ++i;
0041139B  mov         eax,dword ptr [i] 
0041139E  add         eax,1 
004113A1  mov         dword ptr [i],eax 
            if (i == 7)
004113A4  cmp         dword ptr [i],7 
004113A8  jne         main+45h (4113B5h) 
            {
                i += 1;
004113AA  mov         eax,dword ptr [i] 
004113AD  add         eax,1 
004113B0  mov         dword ptr [i],eax 
                continue;
004113B3  jmp         main+25h (411395h) 
            }
        }
004113B5  jmp         main+25h (411395h) 
    }
004113B7  xor         eax,eax 
004113B9  pop         edi  
004113BA  pop         esi  
004113BB  pop         ebx  
004113BC  mov         esp,ebp 
004113BE  pop         ebp  
004113BF  ret              

所以我很困惑,对于命令jmp 411395h ,这是否意味着程序总是被加载到内存中的相同位置? 因为那似乎不合逻辑。

不,这里有两件事情可以发挥 - 你没有指定操作系统所以我会给出一般答案。

首先,可执行文件很少采用最终格式。 作为简化,编译将源转换为目标文件,并且链接将对象文件组合成可执行文件。

但是必须将可执行文件加载到内存中,在那个阶段,可以进行更多修改。 这些修改之一可以是修复可执行文件中的内存引用以指向已在不同位置加载的内存。

这可以通过包含本身内部地址列表的可执行文件来实现,该列表需要在运行时修复。

在许多现代操作系统中,虚拟内存和物理内存之间也存在脱节。

当您的流程开始时,您将获得自己的(用于Windows 32位的4G,我相信)加载进程的地址空间。 此地址空间中的地址与您的实际物理内存地址几乎没有关系,两者之间的转换由内存管理单元(MMU)完成。

实际上,您的进程可能会遍布物理地址空间,因为它已被分页并进入。但虚拟地址不会改变。

正如其他人所写的那样,有相对跳转和相对调用指令基本上为eip添加一个固定值,因此不依赖于程序在内存中的位置; 编译器喜欢尽可能使用这些。 您可以查看代码字节以查看编译器使用的确切指令。 但是,我假设你在询问跳转/调用绝对地址。

当链接器生成可执行文件时,它会生成假定特定基址的绝对地址 ; Microsoft链接器通常使用400000h 当OS加载可执行文件或dll时,它通过添加实际加载可执行文件的地址与链接器基于它的地址之间的差异来“修复”所有绝对地址。 .com之外的所有可执行格式都指定了某种类型的修正表,其中列出了必须以这种方式修补的可执行文件中的所有位置。 因此,在OS将您的可执行文件加载到基本地址(例如1500000h ,您的跳转将看起来像jmp 1511395h 您可以通过使用调试器查看实际代码字节来检查这一点。

较旧的Windows系统倾向于在链接器使用的基址处加载可执行文件; 这造成了安全风险,因为攻击者会提前知道内存中的内容。 这就是为什么较新的系统使用基地址随机化的原因。

内存位置与进程有关。 相对于程序的开头, main始终位于内存中的相同位置。

在x86(以及其他体系结构)上,大多数跳转指令都是IP相关的 :指令的二进制机器代码表示与当前指令指针的偏移量。 因此,无论代码加载到哪个虚拟地址,跳转指令都能正常工作。

相对跳转采用当前机器指令的地址(称为指令指针)并添加偏移量来计算要跳转到的地址。

如果你看看你的代码

004113B3  jmp         main+25h (411395h) 
004113B5  jmp         main+25h (411395h) 
004113B7  xor         eax,eax 

你会注意到jmp指令长2个字节(jmp为1个字节,偏移为1个字节),并且不能存储绝对的4字节地址。

相对跳转是CPU的基本功能(据我所知65xx,Z80,8086,68000),与虚拟内存,内存映射或地址空间随机化等高级功能无关。

大多数芯片具有相对跳跃(相对于当前位置)和虚拟寻址。

int main()
    {
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0CCh 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0CCh] 
00411382  mov         ecx,33h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
        int i = 0,int j=0;
0041138E  mov         dword ptr [i][j],0
        while (i < 10)
00411395  cmp         dword ptr [i][j[,0Bh 
00411399  jge         main+47h (4113B7h) 
        {
            ++i;
0041139B  mov         eax,dword ptr [i][j] 
0041139E  add         eax,1 
004113A1  mov         dword ptr [i][j],eax '
            if (i == 7)
004113A4  cmp         dword ptr [i][j],7 
004113A8  jne         main+45h (4113B5h) 
            {
                i += 1;
004113AA  mov         eax,ebx,dword ptr [i][j] 
004113AD  add         eax,1 
004113B0  mov         dword ptr [i][j],ebx 
                continue;
004113B3  jmp         main+25h (411395h) 
            }
        }
004113B5  jmp         main+25h (411395h) 
    }
004113B7  xor         eax,ebx 
004113B9  pop         edi  
004113BA  pop         esi  
004113BB  pop         ecx  
004113BC  mov         esp,ebp 
004113BE  pop         ebp  
004113BF  ret

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM