思想:

再次在 GDT 中偷内存 搭建 系统调用需要的 逻辑框架与功能实现;

基本分解妄想:

构建系统调用的代码:

拷贝到 偷取的内存中:

idt 向量 序号21位置: 8003ee00`0008f120

各函数的实现:

注意: systemcallentry() 中

esp + 0xc 是 3环 的 esp

3环的 esp 应该是调用 函数的时候的发怒hi地址;所以实际的参数 是 + 4 偏移的位置。

测试 效果 代码:

在 中断表 21 项 构建自己的门;

实战:

1偷取内存

1.1 侦察可偷取内存

发现 和前面 差不多 ; 从GDT :0x120 的位置就后面就没有使用了;可以偷取内存。

1.2 规划可偷取内存

给 SysFastCallEntry、ReadMem、AllocMem分别给予 128byte、64byte、64byte的空间;应该够了。

2 代码

2.1 填充代码 到 偷取内存

#include"pch.h"
#include <stdio.h>
#include<stdlib.h>
#include<Windows.h>

// release 版本会比较好一点,debug会填充一些空间,release会比较稳定

DWORD g_iData = 0;//定义一个全局变量,来存储 0 环数据

DWORD g_Addr[] = {0x8003f120,0x8003f1b0,0x8003f1f0};// 3块 偷取的内存的首地址;分别用来存放 sysfastcallentry、readmem、allocmem的代码

DWORD *g_ServiceTable =(DWORD*) 0x8003f3c0;//在搞2GB 中 放置我们的山寨 SSDT;根据下标 作为 其服务序号 0 -- ReadMem 、 1 -- AllocMem。


char *p = NULL;
int i = 0;
void SystemCallEntry();
DWORD  ReadMem();
DWORD  AllocMem();
// 已经注册在中断处理中的20项的 函数地址 0环 用作填充函数
void _declspec(naked) FillData()
{// 这里是裸函数,所以不会有函数头 push ebp,mov ebp,esp,,和 ret x / sub esp,x 来平衡堆栈;
// 这样的好处是 我们能控制全部的代码。

// 通过循环拷贝 code 到 偷取来的区域:
// 1 .拷贝 systemcallentry() 函数code
p = (char *)g_Addr[0];
for (i = 0; i < 128; i++)
{
*p = ((char *)SystemCallEntry)[i];
p++;
}

// 2 .拷贝 readmem() 函数code
p = (char *)g_Addr[1];
for (i = 0; i < 64; i++)
{
*p = ((char *)ReadMem)[i];
p++;
}

// 3. 拷贝AllocMem() 函数 code
p = (char *)g_Addr[2];
for (i = 0; i < 64; i++)
{
*p = ((char *)AllocMem)[i];
p++;
}
// 初始化 ssdt 表
g_ServiceTable[0] = 0x8003f1b0;
g_ServiceTable[1] = 0x8003f1f0;

// 注册 int 21; 中断向量
__asm
{
// 0x8003f120 --systemcallentry()
// eq eq 8003f508 8003ee00`0008f120

mov eax, 0x0008f120;
mov ds : [0x8003f508], eax;
mov eax, 0x8003ee00;
mov ds : [0x8003f50c], eax;

iretd;//iret 是实地址模式 16位的中断返回
}


}
// SystemCallEntry 函数 实现 注册到 int 21 中去;
void _declspec(naked) SystemCallEntry()
{
__asm
{

push 0x30
pop fs
sti;//开启中断

mov ebx,ss:[esp+0xc] // 获取 3环的 esp
mov ecx,ds:[ebx +4] // 跳过 返回地址 获取参数
mov ebx,0x8003f3c0  // 山寨 ssdt 地址
mov eax,ds:[ebx+eax*4]// 获取ssdt[eax] 地址
call eax

cli;//关闭中断 怕 pop fs; 和 iretd 之间进行线程切换会崩溃。
push 0x3b
pop fs
iretd;

}

}

// ReadMem 函数 实现
DWORD _declspec(naked) ReadMem()
{
__asm
{
mov eax,ds:[ecx] // 直接读取就可以了
ret
}

}
DWORD g_pAddr;
// AllocMem 函数 实现
DWORD _declspec(naked) AllocMem()
{
__asm
{
push ecx
push 0
mov eax,0x8053454C // ExAllocatePool(dd type,dd size);
call eax
ret
}
}

void go()
{
__asm {
int 0x20;// 产生中断请求,调用对应中断处理--这里将 int 21 注册systemcallentry(),
// 并且 将对应的代码拷贝到gdt空闲的区域
}
}

void main()
{

if ((DWORD)FillData != 0x401040)// code : there is not same as the past, there some crt func takes the place401000 ~401040
{
printf("WRONG ADDR");
        sleep(1000);
exit(0);
}
go();// 产生中断请求,调用对应中断处理;进入0环
printf("Addr:%p: \n", FillData);
//printf("Data【0x0x8003f500】: %x \n", g_iData);
system("pause");
}

测试 山寨 的ssdt 表

代码:

// 4_ DIY_sysfastcallentryTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
DWORD _declspec(naked)  readMem(DWORD Addr)
{
__asm
{
mov eax, 0
int 0x21;
ret;
}
}
DWORD _declspec(naked)  AllocMem(DWORD Size)
{
__asm
{
mov eax, 1
int 0x21;
ret;
}
}

int main()
{
DWORD A = readMem(0x8003f3c0);
printf("%p", A);
DWORD B = AllocMem(0x60);
printf("%p", B);
system("pause");
}

效果图:

前面的是读出的数据;

后面的是申请的内存地址;

9_山寨系统调用 SystemCallEntry的更多相关文章

  1. 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D

    在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...

  2. c 进程和系统调用

    这一篇博客讲解进程和系统调用相关的知识 有这样一个场景,我需要输入一串文字,然后把我输入的文字加上一个本地的时间戳 保存在一个文件中,可以初步理解为一个备忘录也行 #include <stdio ...

  3. 让我们山寨一张Windows Azure Global的壁纸

    用过国际版Azure的同学都见过一个显示了机器中主要信息的壁纸,而这个壁纸是通过Sysinternals的一款叫做bginfo来实现的,这款软件的好处是对于批量管理主(虚拟)机的管理员和使用方都很实用 ...

  4. [翻译+山寨]Hangfire Highlighter Tutorial

    前言 Hangfire是一个开源且商业免费使用的工具函数库.可以让你非常容易地在ASP.NET应用(也可以不在ASP.NET应用)中执行多种类型的后台任务,而无需自行定制开发和管理基于Windows ...

  5. 我的操作系统复习——I/O控制和系统调用

    上篇博客介绍了存储器管理的相关知识——我的操作系统复习——存储器管理,本篇讲设备管理中的I/O控制方式和操作系统中的系统调用. 一.I/O控制方式 I/O就是输入输出,I/O设备指的是输入输出设备和存 ...

  6. xv6的作业翻译——作业1 - shell和系统调用

    Xv6的lecture LEC 1 Operating systems   L1: O/S overview L1:O/S概述   * 6.828 goals 6.828的目标   Understan ...

  7. Linux系统编程:基本I/O系统调用

    文件描述符 进程每打开一个文件的时候,会获得该文件的文件描述符,而后续的读写操作都把文件描述符作为参数.在用户空间或者内核空间,都是通过文件描述符来唯一地索引一个打开的文件.文件描述符使用int类型表 ...

  8. Linux系统调用和库函数调用的区别

    Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思 ...

  9. 从零开始山寨Caffe·陆:IO系统(一)

    你说你学过操作系统这门课?写个无Bug的生产者和消费者模型试试! ——你真的学好了操作系统这门课嘛? 在第壹章,展示过这样图: 其中,左半部分构成了新版Caffe最恼人.最庞大的IO系统. 也是历来最 ...

随机推荐

  1. ( 转)WPF面板布局介绍Grid、StackPanel、DockPanel、WrapPanel

    回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的使用经验,可能还存在错误之处,还请大家指出. 本 ...

  2. qemu源码分析

    参考:http://lists.gnu.org/archive/html/qemu-devel/2011-04/pdfhC5rVdz7U8.pdf 1. qemu与Bochs的区别: 1. Bochs ...

  3. Navicat创建事件,定时更新数据库

    一.新建事件 二.在定义里编写要更改的SQL语句 如果SQL语句有多条,需要将SQL语句放在begin...end中 begin update student set num = '0'; updat ...

  4. Git 学习第四天

    我们已经知道,通过命令 git remote add origin git@github.com/Your.name/file.git 可以连接远程仓库,那么,假如我现在想切换另个一远程仓库的连接应该 ...

  5. css过滤镜实现颜色渐变

    语法:filter : progid:DXImageTransform.Microsoft.Gradient ( enabled=bEnabled , startColorStr=iWidth , e ...

  6. axios以form-data形式的传递参数遇到的坑

    axios默认的Content-type是application/json;charset=UTF-8,如果想要以表单的形式传递参数,只要修改{headers:{'Content-Type':'app ...

  7. JDK8新特性之函数式接口

    什么是函数式接口 先来看看传统的创建线程是怎么写的 Thread t1 = new Thread(new Runnable() { @Override public void run() { Syst ...

  8. Dubbo管理端工具

    要得到dubbo的管理端工具其实很简单,只需要下面几步: 1.下载源码:我下载的是dubbo-dubbo-2.5.7.zip . 2.使用maven命令编译源码,得到war包: 将下载的dubbo-d ...

  9. 引入CSS样式表(书写位置)

    CSS可以写到那个位置? 是不是一定写到html文件里面呢? 内部样式表 内嵌式是将CSS代码集中写在HTML文档的head头部标签中,并且用style标签定义,其基本语法格式如下: <head ...

  10. Redis缓存数据库常见操作

    Jedis的最为常见的操作.主要包括常用的列表(list).集合(set).有序集合(sorted set).哈希表(hash)等数据结构,以及其他特性支持. 参考资料:http://hello-ni ...