MacOS环境-手写操作系统-46,47-C语言开发应用程序

简介: MacOS环境-手写操作系统-46,47-C语言开发应用程序

系统与应用内存交叉

1.简介

内核为了避免恶意程序通过污染其内存而入侵自己


在启动应用程序前 会专门给应用程序分配一块与内核完全隔离的内存 作为应用程序运行时的专属内存


这样内核就拥有了比应用程序更高的等级 也就是内核可以访问应用程序的内存 反之则不行


内核启动应用程序 -[DS,ES,SS寄存器指向应用程序专有的内存段描述符]


-> 应用程序运行自身代码-[DS,ES,SS寄存器切换到内核对应的内存段描述符]


->应用程序调用内核API CPU指向内核代码-[DS,ES,SS寄存器切换到应用程序专有的内存段描述符]


->内核执行完API后 把结果交还给应用程序


应用程序继续运行自己的代码-[DS,ES,SS寄存器切换到内核对应的内存段描述符]


->应用程序运行结束 CPU控制器交还给内核


2.代码

根据上面流程描述


在整个应用程序的生命周期内


切换DS,ES,SS这三个段寄存器 使他们在不同阶段指向不同的全局描述符


以便在发送数据读写操作时 代码读取的是合适的数据


接下来 我们根据前面理论 修改代码 让应用程序在调用内核API时 实现对应的内存切换


下面是应用程序的C代码


void api_putchar(int c);
void main() {
    api_putchar('A');
    return;
}


应用程序调用内核API在控制台上输出一个字符A


api_putchar是在api_call.asm中实现的
[SECTION .s32]
BITS 32
call main
retf
api_putchar:
  mov edx, 1
  mov al, [esp + 4]
  int 02Dh
  ret
%include "app.asm"

调用API时 API的输入参数都会存入八个通用寄存器


也就是eax,ebc,ecx…等这些寄存器


其中寄存器edx存储的是所需内核API的编号


这个值需要传给内核 这样内核才知道该执行哪些服务


上面的代码跟以前介绍过的代码一样 真正变化的


是执行指令int 02Dh 后 被执行的中断代码需要做较大修改


当中断指令执行后 被调用的函数代码如下(kernel.asm)


asm_cons_putchar:
AsmConsPutCharHandler equ asm_cons_putchar - $$
        push ds
        push es
        pushad
        ;以上代码还运行在应用程序的环境中
        ......


上面代码执行时


先把两个段寄存器ds,es压入堆栈 然后再通过指令pushad把八个通用寄存器的值压入堆栈


一定要注意 此时这些数据都存储在应用程序的内存里 内核是无法直接访问到的


此时内存的情景如下


image.png

相关寄存器的信息都被压入到应用程序的堆栈上


内核堆栈上还是空 要想让内核获得这些数据


就必须把这些数据从应用程序的堆栈搬运到内核堆栈上


接下来的代码做的就是这些苦力活

asm_cons_putchar:
AsmConsPutCharHandler equ asm_cons_putchar - $$
        ....
        
        ;以上代码还运行在应用程序的环境中

        ;把内存段切换到内核
        mov  ax, SelectorVram
        mov  ds, ax
        mov  es, ax 
        mov  ecx, [0xfe4];获取内核堆栈指针
        add  ecx, -40
        mov  [ecx+32], esp ;保存应用程序堆栈指针
        mov  [ecx+36], ss

        ;将pushad 压入到堆栈的值复制到系统堆栈,也就是应用程序调用API时传入的参数
        mov edx, [esp]
        mov ebx, [esp+4]
        mov [ecx], edx
        mov [ecx+4], ebx
        
        mov edx, [esp+8]
        mov ebx, [esp+12]
        mov [ecx+8], edx
        mov [ecx+12], ebx

        mov edx, [esp+16]
        mov ebx, [esp+20]
        mov [ecx+16], edx
        mov [ecx+20], ebx

        mov edx, [esp+24]
        mov ebx, [esp+28]
        mov [ecx+24], edx
        mov [ecx+28], ebx

        ;把堆栈段切换到内核
        mov  ax, SelectorStack
        mov  ss, ax
        mov  esp, ecx
        sti

        call kernel_api

        .....

代码先改变两个段寄存器ds,es的值 让他们指向内核的专用内存描述符


这样读写数据时 数据就会写入内核的专有内存


然后通过读取0xfe4处的内存数据获得内核堆栈指针的值 把该值放入ecx寄存器


于是通过ecx寄存器 代码便可以读写内核堆栈


接着的代码就是搬运数据的过程


从语句mov edx, [esp]到语句mov [ecx+28], ebx


这些语句执行完后 应用程序和内核堆栈的情况如下

image.png

也就是处于应用程序堆栈上前32个字节的数据被拷贝到了内核的堆栈上


最后代码把内核的堆栈段拷贝到ss寄存器 同时把内核指针复制给esp指针


到此ds,es,ss等寄存器都指向了内核专有内存块 而且数据也从应用程序的堆栈拷贝到内核的堆栈上


指向指令call kernel_api时 CPU的控制器交给内核代码


内核代码运行时如果要读写数据的话 读写的内容都来自于内核原来的专有内存段


因此内核运行时不必担心读取到恶意数据


当内核执行完API后 需要把CPU控制器交还给应用程序


此时就需要把内存从内核专有内存切换到应用程序专有内存 代码如下


;执行完内核代码后,把内存段和堆栈段重新切回到应用程序
        mov  ecx, [esp+32];恢复应用程序的堆栈指针esp
        mov  eax, [esp+36];恢复应用程序的堆栈段
        cli
        mov  ss, ax
        mov  esp, ecx
        popad
        pop  es
        pop  ds
        iretd


上面的代码把当前堆栈从内核堆栈切换回应用程序堆栈


同时指令pop es 和 pop ds 把内存从内核专有内存切换回应用程序的专有内存


别忘了 在这些代码运行前


我们先把es,ds压入了堆栈 这里就是把前面压入的内容重新恢复给es和ds这两个寄存器


大家可以感觉到 这个切换过程没什么技术难度 就是繁琐 很容易出错


其实intel专门提供了指令实现这样的功能 后面我们会使用到


需要执行这种繁琐切换流程的还有一处 就是时钟中断


如果应用程序运行过程中 时钟中断发生了


应用程序的代码会停止执行 而中断代码会被执行


中断代码属于内核代码 因此需要再次进行上面所描述的内存切换


因此时钟中断需要修改的代码如下

_timerHandler:
timerHandler equ _timerHandler - $$
    push es
    push ds
    pushad
    mov  ax, ss
    cmp  ax, SelectorStack
    jne  .from_app
    ;上面代码判断中断发生时是否处于内核环境

    push fs
    push gs

    call intHandlerForTimer
    
    pop gs
    pop fs
    popad
    pop ds
    pop es
     

    iretd
.from_app:
    ;把内存段切换到内核
    mov  ax, SelectorVram
    mov  ds, ax
    mov  es, ax 
    mov  ecx, [0xfe4];获取内核堆栈指针
    add  ecx, -8
    mov  [ecx+4], ss ;保存中断时的堆栈段
    mov  [ecx], esp  ;保存中断时堆栈指针

    mov  ax, SelectorStack ;切换到内核堆栈段
    mov  ss, ax
    mov  esp, ecx ;切换内核指针
    call intHandlerForTimer

    pop  ecx
    pop  eax
    mov  ss, ax
    mov  esp, ecx
    popad
    pop  ds
    pop  es
    iretd

代码运行时


首先判断中断发生时是内核代码在执行还是应用程序的代码在执行


如果是内核代码 那么就没有必要做内存切换了 直接执行时钟中断的代码


如果中断发送时是应用程序代码在执行 那么需要把内存从应用程序专有内存切换到内核专有内存


当中断执行完后 在把内存从内核专有内存切换回应用程序专有内存


3.运行

汇编语言编写的代码不好理解 不理解其实也没关系 后面我们会使用itenl提供的专门指令来实现这些功能


当上面的代码编译执行后 结果如下


目录
相关文章
|
1月前
|
安全 搜索推荐 Android开发
移动应用与系统:探索开发趋势与操作系统优化策略####
当今数字化时代,移动应用已成为日常生活不可或缺的一部分,而移动操作系统则是支撑这些应用运行的基石。本文旨在探讨当前移动应用开发的最新趋势,分析主流移动操作系统的特点及优化策略,为开发者提供有价值的参考。通过深入剖析技术创新、市场动态与用户需求变化,本文力求揭示移动应用与系统协同发展的内在逻辑,助力行业持续进步。 ####
47 9
|
20天前
|
安全 前端开发 Android开发
探索移动应用与系统:从开发到操作系统的深度解析
在数字化时代的浪潮中,移动应用和操作系统成为了我们日常生活的重要组成部分。本文将深入探讨移动应用的开发流程、关键技术和最佳实践,同时分析移动操作系统的核心功能、架构和安全性。通过实际案例和代码示例,我们将揭示如何构建高效、安全且用户友好的移动应用,并理解不同操作系统之间的差异及其对应用开发的影响。无论你是开发者还是对移动技术感兴趣的读者,这篇文章都将为你提供宝贵的见解和知识。
|
21天前
|
人工智能 搜索推荐 Android开发
移动应用与系统:探索开发趋势与操作系统演进####
本文深入剖析了移动应用开发的最新趋势与移动操作系统的演进历程,揭示了技术创新如何不断推动移动互联网生态的变革。通过对比分析不同操作系统的特性及其对应用开发的影响,本文旨在为开发者提供洞察未来技术方向的视角,同时探讨在多样化操作系统环境中实现高效开发的策略。 ####
19 0
|
1月前
|
人工智能 Android开发 数据安全/隐私保护
移动应用与系统:探索开发趋势与操作系统的协同进化####
当今时代,移动应用不再仅仅是简单的软件工具,它们已成为扩展智能手机及平板等设备功能的关键。本文旨在深入分析当前移动应用的开发趋势,探讨移动操作系统的最新进展及其对应用开发的影响,并阐述两者如何相互促进、协同进化,共同推动移动互联网技术向前发展。 ####
|
1月前
|
人工智能 物联网 Android开发
移动应用与系统:探索开发趋势与操作系统的协同进化####
本文深入探讨了移动应用开发的当前趋势,以及这些趋势如何与移动操作系统的发展相互影响、协同进化。通过分析最新的技术动态、市场数据及用户行为变化,本文旨在为开发者提供关于未来移动应用开发方向的洞察,并讨论操作系统层面的创新如何促进或制约应用的发展。 ####
|
20天前
|
5G 数据安全/隐私保护 Android开发
移动应用与系统:探索开发趋势与操作系统革新####
本文深入剖析当前移动应用开发的最新趋势,涵盖跨平台开发框架的兴起、人工智能技术的融合、5G技术对移动应用的影响,以及即时应用的发展现状。随后,文章将探讨主流移动操作系统的最新特性及其对开发者社区的影响,包括Android的持续进化、iOS的创新举措及华为鸿蒙OS的崛起。最后,还将讨论移动应用开发中面临的挑战与未来的发展机遇,为读者提供全面而深入的行业洞察。 ####
|
1月前
|
安全 物联网 Android开发
移动应用与系统:探索开发趋势与操作系统的演进####
【10月更文挑战第29天】 本文深入探讨了移动应用开发的最新趋势与挑战,并分析了主流移动操作系统(如Android、iOS)的发展动态。通过对比不同系统的技术特点和市场表现,揭示了移动应用生态系统的复杂性及其对开发者的影响。此外,还讨论了跨平台开发工具的兴起如何改变应用开发流程,以及这些变化对未来移动计算领域的潜在影响。 ####
43 4
|
27天前
|
人工智能 5G 开发工具
移动应用与系统的未来趋势:开发、操作系统创新及挑战###
本文探讨了移动应用开发和移动操作系统的最新发展趋势,包括人工智能的集成、跨平台开发工具的兴起以及5G技术对移动生态的影响。同时,还分析了开发者面临的主要挑战,如安全性问题、性能优化和用户体验提升等。通过具体案例和技术解析,本文旨在为开发者提供前瞻性指导,帮助他们在快速变化的移动科技领域保持竞争力。 ###
|
1月前
|
前端开发 测试技术 调度
移动应用与系统:探索开发与操作系统的奥秘####
【10月更文挑战第22天】 本文深入剖析了移动应用的开发流程与移动操作系统的核心原理,揭示了两者如何相互依存、共同推动移动互联网的发展。从应用架构设计到操作系统性能优化,全方位解读移动生态的技术细节,为开发者和用户提供有价值的参考。 ####
37 5
|
1月前
|
搜索推荐 前端开发 测试技术
移动应用与系统:探索开发之道与操作系统的演进#### 一、
【10月更文挑战第24天】 本文将带你深入探索移动应用开发的全过程,从构思到上架的每一个细节。同时,我们还将回顾移动操作系统的发展历程,分析当前主流系统的技术特点和未来趋势。无论你是开发者还是普通用户,都能在这里找到感兴趣的内容。 #### 二、
29 1